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
221 }221 }
222}222}
223 223
224/* caller: Add funct3, funct7 into opcode */
225static 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 */
250static 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
274static 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}
224 330
225ST_FUNC void asm_opcode(TCCState *s1, int token)331ST_FUNC void asm_opcode(TCCState *s1, int token)
226{332{
@@ -252,6 +358,27 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 25 unmodified lines
252 asm_binary_opcode(s1, token);358 asm_binary_opcode(s1, token);
253 return;359 return;
254 360
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
255 default:382 default:
256 expect("known instruction");383 expect("known instruction");
257 }384 }
riscv64-tok.h+22−0
@@ -82,6 +82,28 @@ · 81 unmodified lines
82#define DEF_ASM_WITH_SUFFIX(x, y) \82#define DEF_ASM_WITH_SUFFIX(x, y) \
83 DEF(TOK_ASM_ ## x ## _ ## y, #x #y)83 DEF(TOK_ASM_ ## x ## _ ## y, #x #y)
84 84
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
85/* Arithmetic */107/* Arithmetic */
86 108
87 DEF_ASM(lui)109 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