1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #if V8_TARGET_ARCH_RISCV64
6
7 #include "src/codegen/riscv64/constants-riscv64.h"
8
9 namespace v8 {
10 namespace internal {
11
12 // -----------------------------------------------------------------------------
13 // Registers.
14
15 // These register names are defined in a way to match the native disassembler
16 // formatting. See for example the command "objdump -d <binary file>".
17 const char* Registers::names_[kNumSimuRegisters] = {
18 "zero_reg", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "s1", "a0",
19 "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5",
20 "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"};
21
22 // List of alias names which can be used when referring to RISC-V registers.
23 const Registers::RegisterAlias Registers::aliases_[] = {
24 {0, "zero"},
25 {33, "pc"},
26 {8, "s0"},
27 {8, "s0_fp"},
28 {kInvalidRegister, nullptr}};
29
Name(int reg)30 const char* Registers::Name(int reg) {
31 const char* result;
32 if ((0 <= reg) && (reg < kNumSimuRegisters)) {
33 result = names_[reg];
34 } else {
35 result = "noreg";
36 }
37 return result;
38 }
39
Number(const char * name)40 int Registers::Number(const char* name) {
41 // Look through the canonical names.
42 for (int i = 0; i < kNumSimuRegisters; i++) {
43 if (strcmp(names_[i], name) == 0) {
44 return i;
45 }
46 }
47
48 // Look through the alias names.
49 int i = 0;
50 while (aliases_[i].reg != kInvalidRegister) {
51 if (strcmp(aliases_[i].name, name) == 0) {
52 return aliases_[i].reg;
53 }
54 i++;
55 }
56
57 // No register with the reguested name found.
58 return kInvalidRegister;
59 }
60
61 /*
62 const char* FPURegisters::names_[kNumFPURegisters] = {
63 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10",
64 "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
65 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};
66 */
67 const char* FPURegisters::names_[kNumFPURegisters] = {
68 "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
69 "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
70 "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
71 "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"};
72
73 // List of alias names which can be used when referring to RISC-V FP registers.
74 const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
75 {kInvalidRegister, nullptr}};
76
Name(int creg)77 const char* FPURegisters::Name(int creg) {
78 const char* result;
79 if ((0 <= creg) && (creg < kNumFPURegisters)) {
80 result = names_[creg];
81 } else {
82 result = "nocreg";
83 }
84 return result;
85 }
86
Number(const char * name)87 int FPURegisters::Number(const char* name) {
88 // Look through the canonical names.
89 for (int i = 0; i < kNumFPURegisters; i++) {
90 if (strcmp(names_[i], name) == 0) {
91 return i;
92 }
93 }
94
95 // Look through the alias names.
96 int i = 0;
97 while (aliases_[i].creg != kInvalidRegister) {
98 if (strcmp(aliases_[i].name, name) == 0) {
99 return aliases_[i].creg;
100 }
101 i++;
102 }
103
104 // No Cregister with the reguested name found.
105 return kInvalidFPURegister;
106 }
107
108 const char* VRegisters::names_[kNumVRegisters] = {
109 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10",
110 "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
111 "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
112
113 const VRegisters::RegisterAlias VRegisters::aliases_[] = {
114 {kInvalidRegister, nullptr}};
115
Name(int creg)116 const char* VRegisters::Name(int creg) {
117 const char* result;
118 if ((0 <= creg) && (creg < kNumVRegisters)) {
119 result = names_[creg];
120 } else {
121 result = "nocreg";
122 }
123 return result;
124 }
125
Number(const char * name)126 int VRegisters::Number(const char* name) {
127 // Look through the canonical names.
128 for (int i = 0; i < kNumVRegisters; i++) {
129 if (strcmp(names_[i], name) == 0) {
130 return i;
131 }
132 }
133
134 // Look through the alias names.
135 int i = 0;
136 while (aliases_[i].creg != kInvalidRegister) {
137 if (strcmp(aliases_[i].name, name) == 0) {
138 return aliases_[i].creg;
139 }
140 i++;
141 }
142
143 // No Cregister with the reguested name found.
144 return kInvalidVRegister;
145 }
146
InstructionType() const147 InstructionBase::Type InstructionBase::InstructionType() const {
148 if (IsIllegalInstruction()) {
149 return kUnsupported;
150 }
151 // RV64C Instruction
152 if (FLAG_riscv_c_extension && IsShortInstruction()) {
153 switch (InstructionBits() & kRvcOpcodeMask) {
154 case RO_C_ADDI4SPN:
155 return kCIWType;
156 case RO_C_FLD:
157 case RO_C_LW:
158 case RO_C_LD:
159 return kCLType;
160 case RO_C_FSD:
161 case RO_C_SW:
162 case RO_C_SD:
163 return kCSType;
164 case RO_C_NOP_ADDI:
165 case RO_C_ADDIW:
166 case RO_C_LI:
167 case RO_C_LUI_ADD:
168 return kCIType;
169 case RO_C_MISC_ALU:
170 if (Bits(11, 10) != 0b11)
171 return kCBType;
172 else
173 return kCAType;
174 case RO_C_J:
175 return kCJType;
176 case RO_C_BEQZ:
177 case RO_C_BNEZ:
178 return kCBType;
179 case RO_C_SLLI:
180 case RO_C_FLDSP:
181 case RO_C_LWSP:
182 case RO_C_LDSP:
183 return kCIType;
184 case RO_C_JR_MV_ADD:
185 return kCRType;
186 case RO_C_FSDSP:
187 case RO_C_SWSP:
188 case RO_C_SDSP:
189 return kCSSType;
190 default:
191 break;
192 }
193 } else {
194 // RISCV routine
195 switch (InstructionBits() & kBaseOpcodeMask) {
196 case LOAD:
197 return kIType;
198 case LOAD_FP:
199 return kIType;
200 case MISC_MEM:
201 return kIType;
202 case OP_IMM:
203 return kIType;
204 case AUIPC:
205 return kUType;
206 case OP_IMM_32:
207 return kIType;
208 case STORE:
209 return kSType;
210 case STORE_FP:
211 return kSType;
212 case AMO:
213 return kRType;
214 case OP:
215 return kRType;
216 case LUI:
217 return kUType;
218 case OP_32:
219 return kRType;
220 case MADD:
221 case MSUB:
222 case NMSUB:
223 case NMADD:
224 return kR4Type;
225 case OP_FP:
226 return kRType;
227 case BRANCH:
228 return kBType;
229 case JALR:
230 return kIType;
231 case JAL:
232 return kJType;
233 case SYSTEM:
234 return kIType;
235 case OP_V:
236 return kVType;
237 }
238 }
239 return kUnsupported;
240 }
241
242 } // namespace internal
243 } // namespace v8
244
245 #endif // V8_TARGET_ARCH_RISCV64
246