From 1e37ec4917d03bb4dcfc9ca37a40fa75e9636c80 Mon Sep 17 00:00:00 2001 From: Danny Milosavljevic Date: Tue, 6 Apr 2021 13:26:09 +0200 Subject: [PATCH] riscv64-asm: Add add, addi, sub, addw, addd, addiw, addid, subw, subd, xor, xori, or, ori, and, andi, slt, slti, sltu, sltiu --- riscv64-asm.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ riscv64-tok.h | 26 ++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/riscv64-asm.c b/riscv64-asm.c index 0e7bc900..564b948a 100644 --- a/riscv64-asm.c +++ b/riscv64-asm.c @@ -328,6 +328,83 @@ static void asm_shift_opcode(TCCState *s1, int token) } } +static void asm_data_processing_opcode(TCCState* s1, int token) +{ + Operand ops[3]; + parse_operand(s1, &ops[0]); + if (tok == ',') + next(); + else + expect("','"); + parse_operand(s1, &ops[1]); + if (tok == ',') + next(); + else + expect("','"); + parse_operand(s1, &ops[2]); + + switch (token) { + // Arithmetic (RD,RS1,(RS2|IMM)); R-format, I-format or U-format + + case TOK_ASM_add: + asm_emit_r(token, (0xC << 2) | 3, &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_addi: + asm_emit_i(token, (4 << 2) | 3, &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_sub: + asm_emit_r(token, (0xC << 2) | 3 | (32 << 25), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_addw: + asm_emit_r(token, (0xE << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_addiw: // 64 bit + asm_emit_i(token, (0x6 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_subw: + asm_emit_r(token, (0xE << 2) | 3 | (0 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]); + return; + + // Logical (RD,RS1,(RS2|IMM)); R-format or I-format + + case TOK_ASM_xor: + asm_emit_r(token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_xori: + asm_emit_i(token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_or: + asm_emit_r(token, (0xC << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_ori: + asm_emit_i(token, (0x4 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_and: + asm_emit_r(token, (0xC << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_andi: + asm_emit_i(token, (0x4 << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]); + return; + + // Compare (RD,RS1,(RS2|IMM)); R-format or I-format + + case TOK_ASM_slt: + asm_emit_r(token, (0xC << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_slti: + asm_emit_i(token, (0x4 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_sltu: + asm_emit_r(token, (0xC << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); + return; + case TOK_ASM_sltiu: + asm_emit_i(token, (0x4 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); + return; + default: + expect("known data processing instruction"); + } +} + ST_FUNC void asm_opcode(TCCState *s1, int token) { switch (token) { @@ -379,6 +456,27 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) asm_shift_opcode(s1, token); return; + case TOK_ASM_add: + case TOK_ASM_addi: + case TOK_ASM_sub: + case TOK_ASM_addw: + case TOK_ASM_addd: + case TOK_ASM_addiw: + case TOK_ASM_addid: + case TOK_ASM_subw: + case TOK_ASM_subd: + case TOK_ASM_xor: + case TOK_ASM_xori: + case TOK_ASM_or: + case TOK_ASM_ori: + case TOK_ASM_and: + case TOK_ASM_andi: + case TOK_ASM_slt: + case TOK_ASM_slti: + case TOK_ASM_sltu: + case TOK_ASM_sltiu: + asm_data_processing_opcode(s1, token); + default: expect("known instruction"); } diff --git a/riscv64-tok.h b/riscv64-tok.h index f36cf449..f7d75727 100644 --- a/riscv64-tok.h +++ b/riscv64-tok.h @@ -106,9 +106,35 @@ /* Arithmetic */ + DEF_ASM(add) + DEF_ASM(addi) + DEF_ASM(sub) DEF_ASM(lui) DEF_ASM(auipc) + DEF_ASM(addw) + DEF_ASM(addd) + DEF_ASM(addiw) + DEF_ASM(addid) + DEF_ASM(subw) + DEF_ASM(subd) + +/* Logical */ + + DEF_ASM(xor) + DEF_ASM(xori) + DEF_ASM(or) + DEF_ASM(ori) + DEF_ASM(and) + DEF_ASM(andi) + +/* Compare */ + + DEF_ASM(slt) + DEF_ASM(slti) + DEF_ASM(sltu) + DEF_ASM(sltiu) + /* Sync */ DEF_ASM(fence)