v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
base-riscv-i.h
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.
4
5#ifndef V8_CODEGEN_RISCV_BASE_RISCV_I_H_
6#define V8_CODEGEN_RISCV_BASE_RISCV_I_H_
7
12
13namespace v8 {
14namespace internal {
16 public:
17 void lui(Register rd, int32_t imm20);
18 void auipc(Register rd, int32_t imm20);
19
20 // Jumps
21 void jal(Register rd, int32_t imm20);
22 void jalr(Register rd, Register rs1, int16_t imm12);
23
24 // Branches
25 void beq(Register rs1, Register rs2, int16_t imm12);
26 void bne(Register rs1, Register rs2, int16_t imm12);
27 void blt(Register rs1, Register rs2, int16_t imm12);
28 void bge(Register rs1, Register rs2, int16_t imm12);
29 void bltu(Register rs1, Register rs2, int16_t imm12);
30 void bgeu(Register rs1, Register rs2, int16_t imm12);
31 // Loads
32 void lb(Register rd, Register rs1, int16_t imm12);
33 void lh(Register rd, Register rs1, int16_t imm12);
34 void lw(Register rd, Register rs1, int16_t imm12);
35 void lbu(Register rd, Register rs1, int16_t imm12);
36 void lhu(Register rd, Register rs1, int16_t imm12);
37
38 // Stores
39 void sb(Register source, Register base, int16_t imm12);
40 void sh(Register source, Register base, int16_t imm12);
41 void sw(Register source, Register base, int16_t imm12);
42
43 // Arithmetic with immediate
44 void addi(Register rd, Register rs1, int16_t imm12);
45 void slti(Register rd, Register rs1, int16_t imm12);
46 void sltiu(Register rd, Register rs1, int16_t imm12);
47 void xori(Register rd, Register rs1, int16_t imm12);
48 void ori(Register rd, Register rs1, int16_t imm12);
49 void andi(Register rd, Register rs1, int16_t imm12);
50 void slli(Register rd, Register rs1, uint8_t shamt);
51 void srli(Register rd, Register rs1, uint8_t shamt);
52 void srai(Register rd, Register rs1, uint8_t shamt);
53
54 // Arithmetic
55 void add(Register rd, Register rs1, Register rs2);
56 void sub(Register rd, Register rs1, Register rs2);
57 void sll(Register rd, Register rs1, Register rs2);
58 void slt(Register rd, Register rs1, Register rs2);
59 void sltu(Register rd, Register rs1, Register rs2);
60 void xor_(Register rd, Register rs1, Register rs2);
61 void srl(Register rd, Register rs1, Register rs2);
62 void sra(Register rd, Register rs1, Register rs2);
63 void or_(Register rd, Register rs1, Register rs2);
64 void and_(Register rd, Register rs1, Register rs2);
65
66 // Other pseudo instructions that are not part of RISCV pseudo assemly
67 void nor(Register rd, Register rs, Register rt) {
68 or_(rd, rs, rt);
69 not_(rd, rd);
70 }
71
72 // Memory fences
73 void fence(uint8_t pred, uint8_t succ);
74 void fence_tso();
75
76 // Environment call / break
77 void ecall();
78 void ebreak();
79
80 void sync() { fence(0b1111, 0b1111); }
81
82 // This is a de facto standard (as set by GNU binutils) 32-bit unimplemented
83 // instruction (i.e., it should always trap, if your implementation has
84 // invalid instruction traps).
85 void unimp();
86
87 static int JumpOffset(Instr instr);
88 static int AuipcOffset(Instr instr);
89 static int JalrOffset(Instr instr);
90 static int LoadOffset(Instr instr);
91
92 // Check if an instruction is a branch of some kind.
93 static bool IsBranch(Instr instr);
94 static bool IsNop(Instr instr);
95 static bool IsJump(Instr instr);
96 static bool IsJal(Instr instr);
97 static bool IsJalr(Instr instr);
98 static bool IsLui(Instr instr);
99 static bool IsAuipc(Instr instr);
100 static bool IsAddi(Instr instr);
101 static bool IsOri(Instr instr);
102 static bool IsSlli(Instr instr);
103 static bool IsLw(Instr instr);
104
105 inline int32_t branch_offset(Label* L) {
107 }
108 inline int32_t jump_offset(Label* L) {
110 }
111
112 // Branches
113 void beq(Register rs1, Register rs2, Label* L) {
114 beq(rs1, rs2, branch_offset(L));
115 }
116 void bne(Register rs1, Register rs2, Label* L) {
117 bne(rs1, rs2, branch_offset(L));
118 }
119 void blt(Register rs1, Register rs2, Label* L) {
120 blt(rs1, rs2, branch_offset(L));
121 }
122 void bge(Register rs1, Register rs2, Label* L) {
123 bge(rs1, rs2, branch_offset(L));
124 }
125 void bltu(Register rs1, Register rs2, Label* L) {
126 bltu(rs1, rs2, branch_offset(L));
127 }
128 void bgeu(Register rs1, Register rs2, Label* L) {
129 bgeu(rs1, rs2, branch_offset(L));
130 }
131
132 void beqz(Register rs, int16_t imm13) { beq(rs, zero_reg, imm13); }
133 void beqz(Register rs1, Label* L) { beqz(rs1, branch_offset(L)); }
134 void bnez(Register rs, int16_t imm13) { bne(rs, zero_reg, imm13); }
135 void bnez(Register rs1, Label* L) { bnez(rs1, branch_offset(L)); }
136 void blez(Register rs, int16_t imm13) { bge(zero_reg, rs, imm13); }
137 void blez(Register rs1, Label* L) { blez(rs1, branch_offset(L)); }
138 void bgez(Register rs, int16_t imm13) { bge(rs, zero_reg, imm13); }
139 void bgez(Register rs1, Label* L) { bgez(rs1, branch_offset(L)); }
140 void bltz(Register rs, int16_t imm13) { blt(rs, zero_reg, imm13); }
141 void bltz(Register rs1, Label* L) { bltz(rs1, branch_offset(L)); }
142 void bgtz(Register rs, int16_t imm13) { blt(zero_reg, rs, imm13); }
143
144 void bgtz(Register rs1, Label* L) { bgtz(rs1, branch_offset(L)); }
145 void bgt(Register rs1, Register rs2, int16_t imm13) { blt(rs2, rs1, imm13); }
146 void bgt(Register rs1, Register rs2, Label* L) {
147 bgt(rs1, rs2, branch_offset(L));
148 }
149 void ble(Register rs1, Register rs2, int16_t imm13) { bge(rs2, rs1, imm13); }
150 void ble(Register rs1, Register rs2, Label* L) {
151 ble(rs1, rs2, branch_offset(L));
152 }
153 void bgtu(Register rs1, Register rs2, int16_t imm13) {
154 bltu(rs2, rs1, imm13);
155 }
156 void bgtu(Register rs1, Register rs2, Label* L) {
157 bgtu(rs1, rs2, branch_offset(L));
158 }
159 void bleu(Register rs1, Register rs2, int16_t imm13) {
160 bgeu(rs2, rs1, imm13);
161 }
162 void bleu(Register rs1, Register rs2, Label* L) {
163 bleu(rs1, rs2, branch_offset(L));
164 }
165
166 void j(int32_t imm21) { jal(zero_reg, imm21); }
167 void j(Label* L) { j(jump_offset(L)); }
168 void b(Label* L) { j(L); }
169 void jal(int32_t imm21) { jal(ra, imm21); }
170 void jal(Label* L) { jal(jump_offset(L)); }
171 void jr(Register rs) { jalr(zero_reg, rs, 0); }
172 void jr(Register rs, int32_t imm12) { jalr(zero_reg, rs, imm12); }
173 void jalr(Register rs, int32_t imm12) { jalr(ra, rs, imm12); }
174 void jalr(Register rs) { jalr(ra, rs, 0); }
175 void ret() { jalr(zero_reg, ra, 0); }
176 void call(int32_t offset) {
177 auipc(ra, (offset >> 12) + ((offset & 0x800) >> 11));
178 jalr(ra, ra, offset << 20 >> 20);
179 }
180
181 void mv(Register rd, Register rs) { addi(rd, rs, 0); }
182 void not_(Register rd, Register rs) { xori(rd, rs, -1); }
183 void neg(Register rd, Register rs) { sub(rd, zero_reg, rs); }
184 void seqz(Register rd, Register rs) { sltiu(rd, rs, 1); }
185 void snez(Register rd, Register rs) { sltu(rd, zero_reg, rs); }
186 void sltz(Register rd, Register rs) { slt(rd, rs, zero_reg); }
187 void sgtz(Register rd, Register rs) { slt(rd, zero_reg, rs); }
188
189#if V8_TARGET_ARCH_RISCV64
190 void lwu(Register rd, Register rs1, int16_t imm12);
191 void ld(Register rd, Register rs1, int16_t imm12);
192 void sd(Register source, Register base, int16_t imm12);
193 void addiw(Register rd, Register rs1, int16_t imm12);
194 void slliw(Register rd, Register rs1, uint8_t shamt);
195 void srliw(Register rd, Register rs1, uint8_t shamt);
196 void sraiw(Register rd, Register rs1, uint8_t shamt);
197 void addw(Register rd, Register rs1, Register rs2);
198 void subw(Register rd, Register rs1, Register rs2);
199 void sllw(Register rd, Register rs1, Register rs2);
200 void srlw(Register rd, Register rs1, Register rs2);
201 void sraw(Register rd, Register rs1, Register rs2);
202 void negw(Register rd, Register rs) { subw(rd, zero_reg, rs); }
203 void sext_w(Register rd, Register rs) { addiw(rd, rs, 0); }
204
205 static bool IsAddiw(Instr instr);
206 static bool IsLd(Instr instr);
207#endif
208};
209
210} // namespace internal
211} // namespace v8
212
213#endif // V8_CODEGEN_RISCV_BASE_RISCV_I_H_
void sltz(Register rd, Register rs)
void bnez(Register rs1, Label *L)
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 beqz(Register rs, int16_t imm13)
void sh(Register source, Register base, int16_t imm12)
void mv(Register rd, Register rs)
void bltz(Register rs1, Label *L)
void and_(Register rd, Register rs1, Register rs2)
void sltiu(Register rd, Register rs1, int16_t imm12)
static bool IsLui(Instr instr)
void snez(Register rd, Register rs)
void lh(Register rd, Register rs1, int16_t imm12)
static int LoadOffset(Instr instr)
void bgez(Register rs1, Label *L)
void bleu(Register rs1, Register rs2, Label *L)
void fence(uint8_t pred, uint8_t succ)
static int AuipcOffset(Instr instr)
void seqz(Register rd, Register rs)
void blez(Register rs1, Label *L)
void ble(Register rs1, Register rs2, int16_t imm13)
void blez(Register rs, int16_t imm13)
static int JalrOffset(Instr instr)
void jalr(Register rs, int32_t imm12)
static bool IsSlli(Instr instr)
void srai(Register rd, Register rs1, uint8_t shamt)
static bool IsJalr(Instr instr)
int32_t jump_offset(Label *L)
void beqz(Register rs1, Label *L)
void jalr(Register rd, Register rs1, int16_t imm12)
void add(Register rd, Register rs1, Register rs2)
void bnez(Register rs, int16_t imm13)
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 sgtz(Register rd, Register rs)
void bgeu(Register rs1, Register rs2, Label *L)
void srli(Register rd, Register rs1, uint8_t shamt)
void call(int32_t offset)
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 bgtu(Register rs1, Register rs2, Label *L)
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 bgt(Register rs1, Register rs2, int16_t imm13)
void auipc(Register rd, int32_t imm20)
int32_t branch_offset(Label *L)
void not_(Register rd, Register rs)
void sub(Register rd, Register rs1, Register rs2)
void blt(Register rs1, Register rs2, Label *L)
void bltu(Register rs1, Register rs2, Label *L)
void srl(Register rd, Register rs1, Register rs2)
void ble(Register rs1, Register rs2, Label *L)
void beq(Register rs1, Register rs2, Label *L)
void xori(Register rd, Register rs1, int16_t imm12)
void bleu(Register rs1, Register rs2, int16_t imm13)
void bne(Register rs1, Register rs2, int16_t imm12)
static bool IsNop(Instr instr)
void bgt(Register rs1, Register rs2, Label *L)
void bgtu(Register rs1, Register rs2, int16_t imm13)
void bltz(Register rs, int16_t imm13)
static bool IsOri(Instr instr)
void bge(Register rs1, Register rs2, Label *L)
void jr(Register rs, int32_t imm12)
void nor(Register rd, Register rs, Register rt)
void sw(Register source, Register base, int16_t imm12)
void bgtz(Register rs1, Label *L)
void bge(Register rs1, Register rs2, int16_t imm12)
void bgtz(Register rs, int16_t imm13)
static bool IsBranch(Instr instr)
void bgez(Register rs, int16_t imm13)
void lb(Register rd, Register rs1, int16_t imm12)
void bgeu(Register rs1, Register rs2, int16_t imm12)
void neg(Register rd, Register rs)
void bne(Register rs1, Register rs2, Label *L)
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)
virtual int32_t branch_offset_helper(Label *L, OffsetSize bits)=0
int32_t offset
Instruction * instr
constexpr int L