v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
base-constants-riscv.cc
Go to the documentation of this file.
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.
5
8
9namespace v8 {
10namespace 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>".
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.
23const Registers::RegisterAlias Registers::aliases_[] = {
24 {0, "zero"},
25 {33, "pc"},
26 {8, "s0"},
27 {8, "s0_fp"},
28 {kInvalidRegister, nullptr}};
29
30const 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
40int 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/*
62const 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*/
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.
74const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
75 {kInvalidRegister, nullptr}};
76
77const 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
87int 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
108const 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
113const VRegisters::RegisterAlias VRegisters::aliases_[] = {
114 {kInvalidRegister, nullptr}};
115
116const 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
126int 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
148 uint8_t FirstByte = *reinterpret_cast<const uint8_t*>(this);
149 return (FirstByte & 0x03) <= C2;
150}
151
152template <class T>
154 DCHECK(this->IsShortInstruction());
155 return this->Bits(kRvcRdShift + kRvcRdBits - 1, kRvcRdShift);
156}
157
158template <class T>
160 DCHECK(this->IsShortInstruction());
161 return this->Bits(kRvcRs2Shift + kRvcRs2Bits - 1, kRvcRs2Shift);
162}
163
164template <class T>
166 DCHECK(this->IsShortInstruction());
167 return 0b1000 + this->Bits(kRvcRs1sShift + kRvcRs1sBits - 1, kRvcRs1sShift);
168}
169
170template <class T>
172 DCHECK(this->IsShortInstruction());
173 return 0b1000 + this->Bits(kRvcRs2sShift + kRvcRs2sBits - 1, kRvcRs2sShift);
174}
175
176template <class T>
178 DCHECK(this->IsShortInstruction());
179 return this->Bits(kRvcFunct6Shift + kRvcFunct6Bits - 1, kRvcFunct6Shift);
180}
181
182template <class T>
184 DCHECK(this->IsShortInstruction());
185 return this->Bits(kRvcFunct4Shift + kRvcFunct4Bits - 1, kRvcFunct4Shift);
186}
187
188template <class T>
190 DCHECK(this->IsShortInstruction());
191 return this->Bits(kRvcFunct3Shift + kRvcFunct3Bits - 1, kRvcFunct3Shift);
192}
193
194template <class T>
196 DCHECK(this->IsShortInstruction());
197 return this->Bits(kRvcFunct2Shift + kRvcFunct2Bits - 1, kRvcFunct2Shift);
198}
199
200template <class T>
202 DCHECK(this->IsShortInstruction());
203 return this->Bits(kRvcFunct2BShift + kRvcFunct2Bits - 1, kRvcFunct2BShift);
204}
205
206template <class T>
208 if ((this->InstructionBits() &
209 (kBaseOpcodeMask | kFunct3Mask | 0x80000000)) == RO_V_VSETVLI) {
210 uint32_t Bits = this->InstructionBits();
211 uint32_t zimm = Bits & kRvvZimmMask;
212 return zimm >> kRvvZimmShift;
213 } else {
214 DCHECK_EQ(
215 this->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask | 0xC0000000),
217 uint32_t Bits = this->InstructionBits();
218 uint32_t zimm = Bits & kRvvZimmMask;
219 return (zimm >> kRvvZimmShift) & 0x3FF;
220 }
221}
222
223template <class T>
225 DCHECK_EQ(
226 this->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask | 0xC0000000),
228 uint32_t Bits = this->InstructionBits();
229 uint32_t uimm = Bits & kRvvUimmMask;
230 return uimm >> kRvvUimmShift;
231}
232
233template <class T>
235 switch (OperandFunct3()) {
236 case RO_LB:
237 case RO_LBU:
238 case RO_LH:
239 case RO_LHU:
240 case RO_LW:
241#ifdef V8_TARGET_ARCH_RISCV64
242 case RO_LD:
243 case RO_LWU:
244#endif
245 return true;
246 case RO_C_LW:
247 case RO_C_LWSP:
248#ifdef V8_TARGET_ARCH_RISCV64
249 case RO_C_LD:
250 case RO_C_LDSP:
251#endif
252 return v8_flags.riscv_c_extension && this->IsShortInstruction();
253 default:
254 return BaseOpcode() == LOAD_FP;
255 }
256}
257
258template <class T>
260 switch (OperandFunct3()) {
261 case RO_SB:
262 case RO_SH:
263 case RO_SW:
264#ifdef V8_TARGET_ARCH_RISCV64
265 case RO_SD:
266#endif
267 return true;
268 case RO_C_SW:
269 case RO_C_SWSP:
270#ifdef V8_TARGET_ARCH_RISCV64
271 case RO_C_SD:
272 case RO_C_SDSP:
273#endif
274 return v8_flags.riscv_c_extension && this->IsShortInstruction();
275 default:
276 return BaseOpcode() == STORE_FP;
277 }
278}
279
281#ifdef USE_SIMULATOR
283#endif
284
286 if (IsIllegalInstruction()) {
287 return kUnsupported;
288 }
289 // RV64C Instruction
290 if (v8_flags.riscv_c_extension && IsShortInstruction()) {
291 switch (InstructionBits() & kRvcOpcodeMask) {
292 case RO_C_ADDI4SPN:
293 return kCIWType;
294 case RO_C_FLD:
295 case RO_C_LW:
296#ifdef V8_TARGET_ARCH_RISCV64
297 case RO_C_LD:
298#endif
299 return kCLType;
300 case RO_C_FSD:
301 case RO_C_SW:
302#ifdef V8_TARGET_ARCH_RISCV64
303 case RO_C_SD:
304#endif
305 return kCSType;
306 case RO_C_NOP_ADDI:
307 case RO_C_LI:
308#ifdef V8_TARGET_ARCH_RISCV64
309 case RO_C_ADDIW:
310#endif
311 case RO_C_LUI_ADD:
312 return kCIType;
313 case RO_C_MISC_ALU:
314 if (Bits(11, 10) != 0b11)
315 return kCBType;
316 else
317 return kCAType;
318 case RO_C_J:
319 return kCJType;
320 case RO_C_BEQZ:
321 case RO_C_BNEZ:
322 return kCBType;
323 case RO_C_SLLI:
324 case RO_C_FLDSP:
325 case RO_C_LWSP:
326#ifdef V8_TARGET_ARCH_RISCV64
327 case RO_C_LDSP:
328#endif
329 return kCIType;
330 case RO_C_JR_MV_ADD:
331 return kCRType;
332 case RO_C_FSDSP:
333 case RO_C_SWSP:
334#ifdef V8_TARGET_ARCH_RISCV64
335 case RO_C_SDSP:
336#endif
337 return kCSSType;
338 default:
339 break;
340 }
341 } else {
342 // RISCV routine
343 switch (InstructionBits() & kBaseOpcodeMask) {
344 case LOAD:
345 return kIType;
346 case LOAD_FP:
347 return kIType;
348 case MISC_MEM:
349 return kIType;
350 case OP_IMM:
351 return kIType;
352 case AUIPC:
353 return kUType;
354 case OP_IMM_32:
355 return kIType;
356 case STORE:
357 return kSType;
358 case STORE_FP:
359 return kSType;
360 case AMO:
361 return kRType;
362 case OP:
363 return kRType;
364 case LUI:
365 return kUType;
366 case OP_32:
367 return kRType;
368 case MADD:
369 case MSUB:
370 case NMSUB:
371 case NMADD:
372 return kR4Type;
373 case OP_FP:
374 return kRType;
375 case BRANCH:
376 return kBType;
377 case JALR:
378 return kIType;
379 case JAL:
380 return kJType;
381 case SYSTEM:
382 return kIType;
383 case OP_V:
384 return kVType;
385 }
386 }
387 return kUnsupported;
388}
389
390} // namespace internal
391} // namespace v8
static const RegisterAlias aliases_[]
static const char * names_[kNumFPURegisters]
static const char * Name(int reg)
static int Number(const char *name)
int Bits(int hi, int lo) const
static const RegisterAlias aliases_[]
static const char * names_[kNumRegisters]
static int Number(const char *name)
static const char * Name(int reg)
static const char * Name(int reg)
static int Number(const char *name)
static const char * names_[kNumVRegisters]
static const RegisterAlias aliases_[]
ZoneVector< RpoNumber > & result
LiftoffRegister reg
constexpr Opcode RO_V_VSETIVLI
constexpr Opcode RO_C_MISC_ALU
const uint32_t kFunct3Mask
constexpr Opcode RO_LBU
constexpr Opcode RO_C_NOP_ADDI
constexpr DataProcessing3SourceOp MSUB
constexpr Opcode RO_C_LWSP
constexpr Opcode RO_C_ADDI4SPN
constexpr Opcode RO_C_FLD
constexpr Opcode RO_LHU
constexpr Opcode RO_SB
const int kNumFPURegisters
constexpr Opcode RO_C_LI
constexpr Opcode RO_SH
const int kInvalidFPURegister
constexpr Opcode RO_C_JR_MV_ADD
constexpr Opcode RO_C_LW
constexpr Opcode RO_LH
const uint32_t kRvvZimmMask
constexpr Opcode RO_C_SW
const int kNumSimuRegisters
constexpr Opcode JAL
const int kInvalidRegister
const int kInvalidVRegister
constexpr Opcode LUI
constexpr Opcode RO_C_FSDSP
constexpr Opcode RO_C_BEQZ
constexpr Opcode RO_LW
constexpr Opcode RO_C_SWSP
const uint32_t kRvcOpcodeMask
constexpr Opcode RO_C_BNEZ
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr Opcode RO_V_VSETVLI
constexpr Opcode RO_C_J
constexpr Opcode RO_C_FSD
constexpr DataProcessing3SourceOp MADD
constexpr Opcode RO_LB
constexpr Opcode RO_C_FLDSP
const uint32_t kRvvUimmMask
constexpr Opcode RO_C_LUI_ADD
const uint32_t kBaseOpcodeMask
constexpr Opcode RO_C_SLLI
constexpr Opcode RO_SW
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485