v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
base-riscv-i.cc
Go to the documentation of this file.
1// Copyright 2022 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
6namespace v8 {
7namespace internal {
8
9void AssemblerRISCVI::lui(Register rd, int32_t imm20) {
10 GenInstrU(LUI, rd, imm20);
11}
12
13void AssemblerRISCVI::auipc(Register rd, int32_t imm20) {
14 GenInstrU(AUIPC, rd, imm20);
15}
16
17// Jumps
18
19void AssemblerRISCVI::jal(Register rd, int32_t imm21) {
20 GenInstrJ(JAL, rd, imm21);
23}
24
25void AssemblerRISCVI::jalr(Register rd, Register rs1, int16_t imm12) {
26 GenInstrI(0b000, JALR, rd, rs1, imm12);
29}
30
31// Branches
32
33void AssemblerRISCVI::beq(Register rs1, Register rs2, int16_t imm13) {
34 GenInstrBranchCC_rri(0b000, rs1, rs2, imm13);
36}
37
38void AssemblerRISCVI::bne(Register rs1, Register rs2, int16_t imm13) {
39 GenInstrBranchCC_rri(0b001, rs1, rs2, imm13);
41}
42
43void AssemblerRISCVI::blt(Register rs1, Register rs2, int16_t imm13) {
44 GenInstrBranchCC_rri(0b100, rs1, rs2, imm13);
46}
47
48void AssemblerRISCVI::bge(Register rs1, Register rs2, int16_t imm13) {
49 GenInstrBranchCC_rri(0b101, rs1, rs2, imm13);
51}
52
53void AssemblerRISCVI::bltu(Register rs1, Register rs2, int16_t imm13) {
54 GenInstrBranchCC_rri(0b110, rs1, rs2, imm13);
56}
57
58void AssemblerRISCVI::bgeu(Register rs1, Register rs2, int16_t imm13) {
59 GenInstrBranchCC_rri(0b111, rs1, rs2, imm13);
61}
62
63// Loads
64
65void AssemblerRISCVI::lb(Register rd, Register rs1, int16_t imm12) {
66 GenInstrLoad_ri(0b000, rd, rs1, imm12);
67}
68
69void AssemblerRISCVI::lh(Register rd, Register rs1, int16_t imm12) {
70 GenInstrLoad_ri(0b001, rd, rs1, imm12);
71}
72
73void AssemblerRISCVI::lw(Register rd, Register rs1, int16_t imm12) {
74 GenInstrLoad_ri(0b010, rd, rs1, imm12);
75}
76
77void AssemblerRISCVI::lbu(Register rd, Register rs1, int16_t imm12) {
78 GenInstrLoad_ri(0b100, rd, rs1, imm12);
79}
80
81void AssemblerRISCVI::lhu(Register rd, Register rs1, int16_t imm12) {
82 GenInstrLoad_ri(0b101, rd, rs1, imm12);
83}
84
85// Stores
86
87void AssemblerRISCVI::sb(Register source, Register base, int16_t imm12) {
88 GenInstrStore_rri(0b000, base, source, imm12);
89}
90
91void AssemblerRISCVI::sh(Register source, Register base, int16_t imm12) {
92 GenInstrStore_rri(0b001, base, source, imm12);
93}
94
95void AssemblerRISCVI::sw(Register source, Register base, int16_t imm12) {
96 GenInstrStore_rri(0b010, base, source, imm12);
97}
98
99// Arithmetic with immediate
100
101void AssemblerRISCVI::addi(Register rd, Register rs1, int16_t imm12) {
102 GenInstrALU_ri(0b000, rd, rs1, imm12);
103}
104
105void AssemblerRISCVI::slti(Register rd, Register rs1, int16_t imm12) {
106 GenInstrALU_ri(0b010, rd, rs1, imm12);
107}
108
109void AssemblerRISCVI::sltiu(Register rd, Register rs1, int16_t imm12) {
110 GenInstrALU_ri(0b011, rd, rs1, imm12);
111}
112
113void AssemblerRISCVI::xori(Register rd, Register rs1, int16_t imm12) {
114 GenInstrALU_ri(0b100, rd, rs1, imm12);
115}
116
117void AssemblerRISCVI::ori(Register rd, Register rs1, int16_t imm12) {
118 GenInstrALU_ri(0b110, rd, rs1, imm12);
119}
120
121void AssemblerRISCVI::andi(Register rd, Register rs1, int16_t imm12) {
122 GenInstrALU_ri(0b111, rd, rs1, imm12);
123}
124
125void AssemblerRISCVI::slli(Register rd, Register rs1, uint8_t shamt) {
126 GenInstrShift_ri(0, 0b001, rd, rs1, shamt & 0x3f);
127}
128
129void AssemblerRISCVI::srli(Register rd, Register rs1, uint8_t shamt) {
130 GenInstrShift_ri(0, 0b101, rd, rs1, shamt & 0x3f);
131}
132
133void AssemblerRISCVI::srai(Register rd, Register rs1, uint8_t shamt) {
134 GenInstrShift_ri(1, 0b101, rd, rs1, shamt & 0x3f);
135}
136
137// Arithmetic
138
140 GenInstrALU_rr(0b0000000, 0b000, rd, rs1, rs2);
141}
142
144 GenInstrALU_rr(0b0100000, 0b000, rd, rs1, rs2);
145}
146
148 GenInstrALU_rr(0b0000000, 0b001, rd, rs1, rs2);
149}
150
152 GenInstrALU_rr(0b0000000, 0b010, rd, rs1, rs2);
153}
154
156 GenInstrALU_rr(0b0000000, 0b011, rd, rs1, rs2);
157}
158
160 GenInstrALU_rr(0b0000000, 0b100, rd, rs1, rs2);
161}
162
164 GenInstrALU_rr(0b0000000, 0b101, rd, rs1, rs2);
165}
166
168 GenInstrALU_rr(0b0100000, 0b101, rd, rs1, rs2);
169}
170
172 GenInstrALU_rr(0b0000000, 0b110, rd, rs1, rs2);
173}
174
176 GenInstrALU_rr(0b0000000, 0b111, rd, rs1, rs2);
177}
178
179// Memory fences
180
181void AssemblerRISCVI::fence(uint8_t pred, uint8_t succ) {
182 DCHECK(is_uint4(pred) && is_uint4(succ));
183 uint16_t imm12 = succ | (pred << 4) | (0b0000 << 8);
184 GenInstrI(0b000, MISC_MEM, ToRegister(0), ToRegister(0), imm12);
185}
186
188 uint16_t imm12 = (0b0011) | (0b0011 << 4) | (0b1000 << 8);
189 GenInstrI(0b000, MISC_MEM, ToRegister(0), ToRegister(0), imm12);
190}
191
192// Environment call / break
193
195 GenInstrI(0b000, SYSTEM, ToRegister(0), ToRegister(0), 0);
196}
197
199 GenInstrI(0b000, SYSTEM, ToRegister(0), ToRegister(0), 1);
200}
201
202// This is a de facto standard (as set by GNU binutils) 32-bit unimplemented
203// instruction (i.e., it should always trap, if your implementation has invalid
204// instruction traps).
206 GenInstrI(0b001, SYSTEM, ToRegister(0), ToRegister(0), 0b110000000000);
207}
208
212
214 int Op = instr & kBaseOpcodeMask;
215 return Op == JAL || Op == JALR;
216}
217
219
223
227
243
245 int32_t imm21 = ((instr & 0x7fe00000) >> 20) | ((instr & 0x100000) >> 9) |
246 (instr & 0xff000) | ((instr & 0x80000000) >> 11);
247 imm21 = imm21 << 11 >> 11;
248 return imm21;
249}
250
253 int32_t imm12 = static_cast<int32_t>(instr & kImm12Mask) >> 20;
254 return imm12;
255}
256
259 int32_t imm20 = static_cast<int32_t>(instr & kImm20Mask);
260 return imm20;
261}
262
266
268#if V8_TARGET_ARCH_RISCV64
269 DCHECK(IsLd(instr));
270#elif V8_TARGET_ARCH_RISCV32
271 DCHECK(IsLw(instr));
272#endif
273 int32_t imm12 = static_cast<int32_t>(instr & kImm12Mask) >> 20;
274 return imm12;
275}
276
277#ifdef V8_TARGET_ARCH_RISCV64
278
279bool AssemblerRISCVI::IsAddiw(Instr instr) {
280 return (instr & (kBaseOpcodeMask | kFunct3Mask)) == RO_ADDIW;
281}
282
283bool AssemblerRISCVI::IsLd(Instr instr) {
284 return (instr & (kBaseOpcodeMask | kFunct3Mask)) == RO_LD;
285}
286
287void AssemblerRISCVI::lwu(Register rd, Register rs1, int16_t imm12) {
288 GenInstrLoad_ri(0b110, rd, rs1, imm12);
289}
290
291void AssemblerRISCVI::ld(Register rd, Register rs1, int16_t imm12) {
292 GenInstrLoad_ri(0b011, rd, rs1, imm12);
293}
294
295void AssemblerRISCVI::sd(Register source, Register base, int16_t imm12) {
296 GenInstrStore_rri(0b011, base, source, imm12);
297}
298
299void AssemblerRISCVI::addiw(Register rd, Register rs1, int16_t imm12) {
300 GenInstrI(0b000, OP_IMM_32, rd, rs1, imm12);
301}
302
303void AssemblerRISCVI::slliw(Register rd, Register rs1, uint8_t shamt) {
304 GenInstrShiftW_ri(0, 0b001, rd, rs1, shamt & 0x1f);
305}
306
307void AssemblerRISCVI::srliw(Register rd, Register rs1, uint8_t shamt) {
308 GenInstrShiftW_ri(0, 0b101, rd, rs1, shamt & 0x1f);
309}
310
311void AssemblerRISCVI::sraiw(Register rd, Register rs1, uint8_t shamt) {
312 GenInstrShiftW_ri(1, 0b101, rd, rs1, shamt & 0x1f);
313}
314
315void AssemblerRISCVI::addw(Register rd, Register rs1, Register rs2) {
316 GenInstrALUW_rr(0b0000000, 0b000, rd, rs1, rs2);
317}
318
319void AssemblerRISCVI::subw(Register rd, Register rs1, Register rs2) {
320 GenInstrALUW_rr(0b0100000, 0b000, rd, rs1, rs2);
321}
322
323void AssemblerRISCVI::sllw(Register rd, Register rs1, Register rs2) {
324 GenInstrALUW_rr(0b0000000, 0b001, rd, rs1, rs2);
325}
326
327void AssemblerRISCVI::srlw(Register rd, Register rs1, Register rs2) {
328 GenInstrALUW_rr(0b0000000, 0b101, rd, rs1, rs2);
329}
330
331void AssemblerRISCVI::sraw(Register rd, Register rs1, Register rs2) {
332 GenInstrALUW_rr(0b0100000, 0b101, rd, rs1, rs2);
333}
334
335#endif
336
337} // namespace internal
338} // namespace v8
void addi(Register rd, Register rs1, int16_t imm12)
void lhu(Register rd, Register rs1, int16_t imm12)
void sltu(Register rd, Register rs1, Register rs2)
void or_(Register rd, Register rs1, Register rs2)
void blt(Register rs1, Register rs2, int16_t imm12)
void lui(Register rd, int32_t imm20)
void sh(Register source, Register base, int16_t imm12)
void and_(Register rd, Register rs1, Register rs2)
void sltiu(Register rd, Register rs1, int16_t imm12)
static bool IsLui(Instr instr)
void lh(Register rd, Register rs1, int16_t imm12)
static int LoadOffset(Instr instr)
void fence(uint8_t pred, uint8_t succ)
static int AuipcOffset(Instr instr)
static int JalrOffset(Instr instr)
static bool IsSlli(Instr instr)
void srai(Register rd, Register rs1, uint8_t shamt)
static bool IsJalr(Instr instr)
void jalr(Register rd, Register rs1, int16_t imm12)
void add(Register rd, Register rs1, Register rs2)
static bool IsJump(Instr instr)
static int JumpOffset(Instr instr)
void beq(Register rs1, Register rs2, int16_t imm12)
static bool IsJal(Instr instr)
void bltu(Register rs1, Register rs2, int16_t imm12)
static bool IsAddi(Instr instr)
void srli(Register rd, Register rs1, uint8_t shamt)
void xor_(Register rd, Register rs1, Register rs2)
static bool IsLw(Instr instr)
void andi(Register rd, Register rs1, int16_t imm12)
void lw(Register rd, Register rs1, int16_t imm12)
void slt(Register rd, Register rs1, Register rs2)
void ori(Register rd, Register rs1, int16_t imm12)
static bool IsAuipc(Instr instr)
void lbu(Register rd, Register rs1, int16_t imm12)
void auipc(Register rd, int32_t imm20)
void sub(Register rd, Register rs1, Register rs2)
void srl(Register rd, Register rs1, Register rs2)
void xori(Register rd, Register rs1, int16_t imm12)
void bne(Register rs1, Register rs2, int16_t imm12)
static bool IsNop(Instr instr)
static bool IsOri(Instr instr)
void sw(Register source, Register base, int16_t imm12)
void bge(Register rs1, Register rs2, int16_t imm12)
static bool IsBranch(Instr instr)
void lb(Register rd, Register rs1, int16_t imm12)
void bgeu(Register rs1, Register rs2, int16_t imm12)
void jal(Register rd, int32_t imm20)
void sll(Register rd, Register rs1, Register rs2)
void sb(Register source, Register base, int16_t imm12)
void slti(Register rd, Register rs1, int16_t imm12)
void slli(Register rd, Register rs1, uint8_t shamt)
void sra(Register rd, Register rs1, Register rs2)
void GenInstrBranchCC_rri(uint8_t funct3, Register rs1, Register rs2, int16_t imm12)
void GenInstrJ(BaseOpcode opcode, Register rd, int32_t imm20)
void GenInstrLoad_ri(uint8_t funct3, Register rd, Register rs1, int16_t imm12)
void GenInstrALU_ri(uint8_t funct3, Register rd, Register rs1, int16_t imm12)
void GenInstrShift_ri(bool arithshift, uint8_t funct3, Register rd, Register rs1, uint8_t shamt)
void GenInstrALUW_rr(uint8_t funct7, uint8_t funct3, Register rd, Register rs1, Register rs2)
void GenInstrALU_rr(uint8_t funct7, uint8_t funct3, Register rd, Register rs1, Register rs2)
void GenInstrStore_rri(uint8_t funct3, Register rs1, Register rs2, int16_t imm12)
void GenInstrI(uint8_t funct3, BaseOpcode opcode, Register rd, Register rs1, int16_t imm12)
void GenInstrU(BaseOpcode opcode, Register rd, int32_t imm20)
virtual void BlockTrampolinePoolFor(int instructions)=0
void GenInstrShiftW_ri(bool arithshift, uint8_t funct3, Register rd, Register rs1, uint8_t shamt)
Instruction * instr
const uint32_t kFunct3Mask
constexpr Opcode JAL
constexpr Opcode LUI
constexpr Opcode RO_SLLI
constexpr Opcode RO_ORI
constexpr Opcode RO_LW
constexpr Opcode RO_ADDI
Register ToRegister(int num)
const uint32_t kBaseOpcodeMask
const uint32_t kImm20Mask
#define DCHECK(condition)
Definition logging.h:482