History

riscv64-asm: Add sll, slli, srl, srli, sra, srai, sllw, slld, slliw, sllid, srlw, srld, srliw, srlid, sraw, srad, sraiw, sraid

Danny Milosavljevic committed 5 years ago

Commit 8b1a89f1 parent 0b1cc482 files · +149 −0Browse files

Unified · Split

2 files
  1. riscv64-asm.c +127 −0
  2. riscv64-tok.h +22 −0
riscv64-asm.c+127−0
@@ -221,6 +221,112 @@ static void asm_binary_opcode(TCCState* s1, int token) · 220 unmodified lines
221221 }
222222 }
223223
224+/* caller: Add funct3, funct7 into opcode */
225+static void asm_emit_r(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
226+{
227+ if (rd->type != OP_REG) {
228+ tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
229+ return;
230+ }
231+ if (rs1->type != OP_REG) {
232+ tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
233+ return;
234+ }
235+ if (rs2->type != OP_REG) {
236+ tcc_error("'%s': Expected second source operand that is a register or immediate", get_tok_str(token, NULL));
237+ return;
238+ }
239+ /* R-type instruction:
240+ 31...25 funct7
241+ 24...20 rs2
242+ 19...15 rs1
243+ 14...12 funct3
244+ 11...7 rd
245+ 6...0 opcode */
246+ gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg));
247+}
248+
249+/* caller: Add funct3 into opcode */
250+static void asm_emit_i(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
251+{
252+ if (rd->type != OP_REG) {
253+ tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
254+ return;
255+ }
256+ if (rs1->type != OP_REG) {
257+ tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
258+ return;
259+ }
260+ if (rs2->type != OP_IM12S) {
261+ tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 4095", get_tok_str(token, NULL));
262+ return;
263+ }
264+ /* I-type instruction:
265+ 31...20 imm[11:0]
266+ 19...15 rs1
267+ 14...12 funct3
268+ 11...7 rd
269+ 6...0 opcode */
270+
271+ gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | (rs2->e.v << 20));
272+}
273+
274+static void asm_shift_opcode(TCCState *s1, int token)
275+{
276+ Operand ops[3];
277+ parse_operand(s1, &ops[0]);
278+ if (tok == ',')
279+ next();
280+ else
281+ expect("','");
282+ parse_operand(s1, &ops[1]);
283+ if (tok == ',')
284+ next();
285+ else
286+ expect("','");
287+ parse_operand(s1, &ops[2]);
288+
289+ switch (token) {
290+ case TOK_ASM_sll:
291+ asm_emit_r(token, (0xC << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
292+ return;
293+ case TOK_ASM_slli:
294+ asm_emit_i(token, (4 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
295+ return;
296+ case TOK_ASM_srl:
297+ asm_emit_r(token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);
298+ return;
299+ case TOK_ASM_srli:
300+ asm_emit_i(token, (0x4 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
301+ return;
302+ case TOK_ASM_sra:
303+ asm_emit_r(token, (0xC << 2) | 3 | (5 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]);
304+ return;
305+ case TOK_ASM_srai:
306+ asm_emit_i(token, (0x4 << 2) | 3 | (5 << 12) | (16 << 26), &ops[0], &ops[1], &ops[2]);
307+ return;
308+ case TOK_ASM_sllw:
309+ asm_emit_r(token, (0xE << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
310+ return;
311+ case TOK_ASM_slliw:
312+ asm_emit_i(token, (6 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
313+ return;
314+ case TOK_ASM_srlw:
315+ asm_emit_r(token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
316+ return;
317+ case TOK_ASM_srliw:
318+ asm_emit_i(token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
319+ return;
320+ case TOK_ASM_sraw:
321+ asm_emit_r(token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
322+ return;
323+ case TOK_ASM_sraiw:
324+ asm_emit_i(token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
325+ return;
326+ default:
327+ expect("shift instruction");
328+ }
329+}
224330
225331 ST_FUNC void asm_opcode(TCCState *s1, int token)
226332 {
@@ -252,6 +358,27 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 25 unmodified lines
252358 asm_binary_opcode(s1, token);
253359 return;
254360
361+ case TOK_ASM_sll:
362+ case TOK_ASM_slli:
363+ case TOK_ASM_srl:
364+ case TOK_ASM_srli:
365+ case TOK_ASM_sra:
366+ case TOK_ASM_srai:
367+ case TOK_ASM_sllw:
368+ case TOK_ASM_slld:
369+ case TOK_ASM_slliw:
370+ case TOK_ASM_sllid:
371+ case TOK_ASM_srlw:
372+ case TOK_ASM_srld:
373+ case TOK_ASM_srliw:
374+ case TOK_ASM_srlid:
375+ case TOK_ASM_sraw:
376+ case TOK_ASM_srad:
377+ case TOK_ASM_sraiw:
378+ case TOK_ASM_sraid:
379+ asm_shift_opcode(s1, token);
380+ return;
381+
255382 default:
256383 expect("known instruction");
257384 }
riscv64-tok.h+22−0
@@ -82,6 +82,28 @@ · 81 unmodified lines
8282 #define DEF_ASM_WITH_SUFFIX(x, y) \
8383 DEF(TOK_ASM_ ## x ## _ ## y, #x #y)
8484
85+/* Shifts */
86+
87+ DEF_ASM(sll)
88+ DEF_ASM(slli)
89+ DEF_ASM(srl)
90+ DEF_ASM(srli)
91+ DEF_ASM(sra)
92+ DEF_ASM(srai)
93+
94+ DEF_ASM(sllw)
95+ DEF_ASM(slld)
96+ DEF_ASM(slliw)
97+ DEF_ASM(sllid)
98+ DEF_ASM(srlw)
99+ DEF_ASM(srld)
100+ DEF_ASM(srliw)
101+ DEF_ASM(srlid)
102+ DEF_ASM(sraw)
103+ DEF_ASM(srad)
104+ DEF_ASM(sraiw)
105+ DEF_ASM(sraid)
106+
85107 /* Arithmetic */
86108
87109 DEF_ASM(lui)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t