11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_RISCV64
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/codegen/riscv64/constants-riscv64.h"
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_cinamespace v8 {
101cb0ef41Sopenharmony_cinamespace internal {
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
131cb0ef41Sopenharmony_ci// Registers.
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// These register names are defined in a way to match the native disassembler
161cb0ef41Sopenharmony_ci// formatting. See for example the command "objdump -d <binary file>".
171cb0ef41Sopenharmony_ciconst char* Registers::names_[kNumSimuRegisters] = {
181cb0ef41Sopenharmony_ci    "zero_reg", "ra", "sp", "gp", "tp",  "t0",  "t1", "t2", "fp", "s1", "a0",
191cb0ef41Sopenharmony_ci    "a1",       "a2", "a3", "a4", "a5",  "a6",  "a7", "s2", "s3", "s4", "s5",
201cb0ef41Sopenharmony_ci    "s6",       "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"};
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci// List of alias names which can be used when referring to RISC-V registers.
231cb0ef41Sopenharmony_ciconst Registers::RegisterAlias Registers::aliases_[] = {
241cb0ef41Sopenharmony_ci    {0, "zero"},
251cb0ef41Sopenharmony_ci    {33, "pc"},
261cb0ef41Sopenharmony_ci    {8, "s0"},
271cb0ef41Sopenharmony_ci    {8, "s0_fp"},
281cb0ef41Sopenharmony_ci    {kInvalidRegister, nullptr}};
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciconst char* Registers::Name(int reg) {
311cb0ef41Sopenharmony_ci  const char* result;
321cb0ef41Sopenharmony_ci  if ((0 <= reg) && (reg < kNumSimuRegisters)) {
331cb0ef41Sopenharmony_ci    result = names_[reg];
341cb0ef41Sopenharmony_ci  } else {
351cb0ef41Sopenharmony_ci    result = "noreg";
361cb0ef41Sopenharmony_ci  }
371cb0ef41Sopenharmony_ci  return result;
381cb0ef41Sopenharmony_ci}
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ciint Registers::Number(const char* name) {
411cb0ef41Sopenharmony_ci  // Look through the canonical names.
421cb0ef41Sopenharmony_ci  for (int i = 0; i < kNumSimuRegisters; i++) {
431cb0ef41Sopenharmony_ci    if (strcmp(names_[i], name) == 0) {
441cb0ef41Sopenharmony_ci      return i;
451cb0ef41Sopenharmony_ci    }
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  // Look through the alias names.
491cb0ef41Sopenharmony_ci  int i = 0;
501cb0ef41Sopenharmony_ci  while (aliases_[i].reg != kInvalidRegister) {
511cb0ef41Sopenharmony_ci    if (strcmp(aliases_[i].name, name) == 0) {
521cb0ef41Sopenharmony_ci      return aliases_[i].reg;
531cb0ef41Sopenharmony_ci    }
541cb0ef41Sopenharmony_ci    i++;
551cb0ef41Sopenharmony_ci  }
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  // No register with the reguested name found.
581cb0ef41Sopenharmony_ci  return kInvalidRegister;
591cb0ef41Sopenharmony_ci}
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci/*
621cb0ef41Sopenharmony_ciconst char* FPURegisters::names_[kNumFPURegisters] = {
631cb0ef41Sopenharmony_ci    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",  "f8",  "f9",  "f10",
641cb0ef41Sopenharmony_ci    "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
651cb0ef41Sopenharmony_ci    "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};
661cb0ef41Sopenharmony_ci*/
671cb0ef41Sopenharmony_ciconst char* FPURegisters::names_[kNumFPURegisters] = {
681cb0ef41Sopenharmony_ci    "ft0", "ft1", "ft2",  "ft3",  "ft4", "ft5", "ft6",  "ft7",
691cb0ef41Sopenharmony_ci    "fs0", "fs1", "fa0",  "fa1",  "fa2", "fa3", "fa4",  "fa5",
701cb0ef41Sopenharmony_ci    "fa6", "fa7", "fs2",  "fs3",  "fs4", "fs5", "fs6",  "fs7",
711cb0ef41Sopenharmony_ci    "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"};
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci// List of alias names which can be used when referring to RISC-V FP registers.
741cb0ef41Sopenharmony_ciconst FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
751cb0ef41Sopenharmony_ci    {kInvalidRegister, nullptr}};
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ciconst char* FPURegisters::Name(int creg) {
781cb0ef41Sopenharmony_ci  const char* result;
791cb0ef41Sopenharmony_ci  if ((0 <= creg) && (creg < kNumFPURegisters)) {
801cb0ef41Sopenharmony_ci    result = names_[creg];
811cb0ef41Sopenharmony_ci  } else {
821cb0ef41Sopenharmony_ci    result = "nocreg";
831cb0ef41Sopenharmony_ci  }
841cb0ef41Sopenharmony_ci  return result;
851cb0ef41Sopenharmony_ci}
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ciint FPURegisters::Number(const char* name) {
881cb0ef41Sopenharmony_ci  // Look through the canonical names.
891cb0ef41Sopenharmony_ci  for (int i = 0; i < kNumFPURegisters; i++) {
901cb0ef41Sopenharmony_ci    if (strcmp(names_[i], name) == 0) {
911cb0ef41Sopenharmony_ci      return i;
921cb0ef41Sopenharmony_ci    }
931cb0ef41Sopenharmony_ci  }
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  // Look through the alias names.
961cb0ef41Sopenharmony_ci  int i = 0;
971cb0ef41Sopenharmony_ci  while (aliases_[i].creg != kInvalidRegister) {
981cb0ef41Sopenharmony_ci    if (strcmp(aliases_[i].name, name) == 0) {
991cb0ef41Sopenharmony_ci      return aliases_[i].creg;
1001cb0ef41Sopenharmony_ci    }
1011cb0ef41Sopenharmony_ci    i++;
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  // No Cregister with the reguested name found.
1051cb0ef41Sopenharmony_ci  return kInvalidFPURegister;
1061cb0ef41Sopenharmony_ci}
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ciconst char* VRegisters::names_[kNumVRegisters] = {
1091cb0ef41Sopenharmony_ci    "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",  "v8",  "v9",  "v10",
1101cb0ef41Sopenharmony_ci    "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
1111cb0ef41Sopenharmony_ci    "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciconst VRegisters::RegisterAlias VRegisters::aliases_[] = {
1141cb0ef41Sopenharmony_ci    {kInvalidRegister, nullptr}};
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ciconst char* VRegisters::Name(int creg) {
1171cb0ef41Sopenharmony_ci  const char* result;
1181cb0ef41Sopenharmony_ci  if ((0 <= creg) && (creg < kNumVRegisters)) {
1191cb0ef41Sopenharmony_ci    result = names_[creg];
1201cb0ef41Sopenharmony_ci  } else {
1211cb0ef41Sopenharmony_ci    result = "nocreg";
1221cb0ef41Sopenharmony_ci  }
1231cb0ef41Sopenharmony_ci  return result;
1241cb0ef41Sopenharmony_ci}
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ciint VRegisters::Number(const char* name) {
1271cb0ef41Sopenharmony_ci  // Look through the canonical names.
1281cb0ef41Sopenharmony_ci  for (int i = 0; i < kNumVRegisters; i++) {
1291cb0ef41Sopenharmony_ci    if (strcmp(names_[i], name) == 0) {
1301cb0ef41Sopenharmony_ci      return i;
1311cb0ef41Sopenharmony_ci    }
1321cb0ef41Sopenharmony_ci  }
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  // Look through the alias names.
1351cb0ef41Sopenharmony_ci  int i = 0;
1361cb0ef41Sopenharmony_ci  while (aliases_[i].creg != kInvalidRegister) {
1371cb0ef41Sopenharmony_ci    if (strcmp(aliases_[i].name, name) == 0) {
1381cb0ef41Sopenharmony_ci      return aliases_[i].creg;
1391cb0ef41Sopenharmony_ci    }
1401cb0ef41Sopenharmony_ci    i++;
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  // No Cregister with the reguested name found.
1441cb0ef41Sopenharmony_ci  return kInvalidVRegister;
1451cb0ef41Sopenharmony_ci}
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ciInstructionBase::Type InstructionBase::InstructionType() const {
1481cb0ef41Sopenharmony_ci  if (IsIllegalInstruction()) {
1491cb0ef41Sopenharmony_ci    return kUnsupported;
1501cb0ef41Sopenharmony_ci  }
1511cb0ef41Sopenharmony_ci  // RV64C Instruction
1521cb0ef41Sopenharmony_ci  if (FLAG_riscv_c_extension && IsShortInstruction()) {
1531cb0ef41Sopenharmony_ci    switch (InstructionBits() & kRvcOpcodeMask) {
1541cb0ef41Sopenharmony_ci      case RO_C_ADDI4SPN:
1551cb0ef41Sopenharmony_ci        return kCIWType;
1561cb0ef41Sopenharmony_ci      case RO_C_FLD:
1571cb0ef41Sopenharmony_ci      case RO_C_LW:
1581cb0ef41Sopenharmony_ci      case RO_C_LD:
1591cb0ef41Sopenharmony_ci        return kCLType;
1601cb0ef41Sopenharmony_ci      case RO_C_FSD:
1611cb0ef41Sopenharmony_ci      case RO_C_SW:
1621cb0ef41Sopenharmony_ci      case RO_C_SD:
1631cb0ef41Sopenharmony_ci        return kCSType;
1641cb0ef41Sopenharmony_ci      case RO_C_NOP_ADDI:
1651cb0ef41Sopenharmony_ci      case RO_C_ADDIW:
1661cb0ef41Sopenharmony_ci      case RO_C_LI:
1671cb0ef41Sopenharmony_ci      case RO_C_LUI_ADD:
1681cb0ef41Sopenharmony_ci        return kCIType;
1691cb0ef41Sopenharmony_ci      case RO_C_MISC_ALU:
1701cb0ef41Sopenharmony_ci        if (Bits(11, 10) != 0b11)
1711cb0ef41Sopenharmony_ci          return kCBType;
1721cb0ef41Sopenharmony_ci        else
1731cb0ef41Sopenharmony_ci          return kCAType;
1741cb0ef41Sopenharmony_ci      case RO_C_J:
1751cb0ef41Sopenharmony_ci        return kCJType;
1761cb0ef41Sopenharmony_ci      case RO_C_BEQZ:
1771cb0ef41Sopenharmony_ci      case RO_C_BNEZ:
1781cb0ef41Sopenharmony_ci        return kCBType;
1791cb0ef41Sopenharmony_ci      case RO_C_SLLI:
1801cb0ef41Sopenharmony_ci      case RO_C_FLDSP:
1811cb0ef41Sopenharmony_ci      case RO_C_LWSP:
1821cb0ef41Sopenharmony_ci      case RO_C_LDSP:
1831cb0ef41Sopenharmony_ci        return kCIType;
1841cb0ef41Sopenharmony_ci      case RO_C_JR_MV_ADD:
1851cb0ef41Sopenharmony_ci        return kCRType;
1861cb0ef41Sopenharmony_ci      case RO_C_FSDSP:
1871cb0ef41Sopenharmony_ci      case RO_C_SWSP:
1881cb0ef41Sopenharmony_ci      case RO_C_SDSP:
1891cb0ef41Sopenharmony_ci        return kCSSType;
1901cb0ef41Sopenharmony_ci      default:
1911cb0ef41Sopenharmony_ci        break;
1921cb0ef41Sopenharmony_ci    }
1931cb0ef41Sopenharmony_ci  } else {
1941cb0ef41Sopenharmony_ci    // RISCV routine
1951cb0ef41Sopenharmony_ci    switch (InstructionBits() & kBaseOpcodeMask) {
1961cb0ef41Sopenharmony_ci      case LOAD:
1971cb0ef41Sopenharmony_ci        return kIType;
1981cb0ef41Sopenharmony_ci      case LOAD_FP:
1991cb0ef41Sopenharmony_ci        return kIType;
2001cb0ef41Sopenharmony_ci      case MISC_MEM:
2011cb0ef41Sopenharmony_ci        return kIType;
2021cb0ef41Sopenharmony_ci      case OP_IMM:
2031cb0ef41Sopenharmony_ci        return kIType;
2041cb0ef41Sopenharmony_ci      case AUIPC:
2051cb0ef41Sopenharmony_ci        return kUType;
2061cb0ef41Sopenharmony_ci      case OP_IMM_32:
2071cb0ef41Sopenharmony_ci        return kIType;
2081cb0ef41Sopenharmony_ci      case STORE:
2091cb0ef41Sopenharmony_ci        return kSType;
2101cb0ef41Sopenharmony_ci      case STORE_FP:
2111cb0ef41Sopenharmony_ci        return kSType;
2121cb0ef41Sopenharmony_ci      case AMO:
2131cb0ef41Sopenharmony_ci        return kRType;
2141cb0ef41Sopenharmony_ci      case OP:
2151cb0ef41Sopenharmony_ci        return kRType;
2161cb0ef41Sopenharmony_ci      case LUI:
2171cb0ef41Sopenharmony_ci        return kUType;
2181cb0ef41Sopenharmony_ci      case OP_32:
2191cb0ef41Sopenharmony_ci        return kRType;
2201cb0ef41Sopenharmony_ci      case MADD:
2211cb0ef41Sopenharmony_ci      case MSUB:
2221cb0ef41Sopenharmony_ci      case NMSUB:
2231cb0ef41Sopenharmony_ci      case NMADD:
2241cb0ef41Sopenharmony_ci        return kR4Type;
2251cb0ef41Sopenharmony_ci      case OP_FP:
2261cb0ef41Sopenharmony_ci        return kRType;
2271cb0ef41Sopenharmony_ci      case BRANCH:
2281cb0ef41Sopenharmony_ci        return kBType;
2291cb0ef41Sopenharmony_ci      case JALR:
2301cb0ef41Sopenharmony_ci        return kIType;
2311cb0ef41Sopenharmony_ci      case JAL:
2321cb0ef41Sopenharmony_ci        return kJType;
2331cb0ef41Sopenharmony_ci      case SYSTEM:
2341cb0ef41Sopenharmony_ci        return kIType;
2351cb0ef41Sopenharmony_ci      case OP_V:
2361cb0ef41Sopenharmony_ci        return kVType;
2371cb0ef41Sopenharmony_ci    }
2381cb0ef41Sopenharmony_ci  }
2391cb0ef41Sopenharmony_ci  return kUnsupported;
2401cb0ef41Sopenharmony_ci}
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci}  // namespace internal
2431cb0ef41Sopenharmony_ci}  // namespace v8
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci#endif  // V8_TARGET_ARCH_RISCV64
246