From ada17a08ebc9efa7ac7851d70abc803f5aeb9821 Mon Sep 17 00:00:00 2001 From: noneofyourbusiness Date: Sun, 10 Dec 2023 22:36:49 +0100 Subject: [PATCH] riscv64-asm.c: add support for calculating addresses of symbols add some pseudoinstructions riscv64-tok.h: add pseudoinstructions from tables 25.{2,3} --- riscv64-asm.c | 42 +++++++++++++++++++++++++++++++++++++++++- riscv64-tok.h | 46 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/riscv64-asm.c b/riscv64-asm.c index 9c9c6b99..a83a1acc 100644 --- a/riscv64-asm.c +++ b/riscv64-asm.c @@ -167,6 +167,7 @@ static void asm_nullary_opcode(TCCState *s1, int token) static void parse_operand(TCCState *s1, Operand *op) { ExprValue e = {0}; + Sym label = {0}; int8_t reg; op->type = 0; @@ -190,6 +191,19 @@ static void parse_operand(TCCState *s1, Operand *op) if (!op->e.sym) { if (op->e.v < 0x1000) op->type = OP_IM12S; + } else if (op->e.sym->type.t & (VT_EXTERN | VT_STATIC)) { + label.type.t = VT_VOID | VT_STATIC; + + /* use the medium PIC model: GOT, auipc, lw */ + if (op->e.sym->type.t & VT_STATIC) + greloca(cur_text_section, op->e.sym, ind, R_RISCV_PCREL_HI20, 0); + else + greloca(cur_text_section, op->e.sym, ind, R_RISCV_GOT_HI20, 0); + put_extern_sym(&label, cur_text_section, ind, 0); + greloca(cur_text_section, &label, ind+4, R_RISCV_PCREL_LO12_I, 0); + + op->type = OP_IM12S; + op->e.v = 0; } else { expect("operand"); } @@ -206,6 +220,7 @@ static void asm_unary_opcode(TCCState *s1, int token) opcode |= ENCODE_RD(op.reg); switch (token) { + /* pseudoinstructions */ case TOK_ASM_rdcycle: asm_emit_opcode(opcode | (0xC00 << 20)); return; @@ -224,6 +239,7 @@ static void asm_unary_opcode(TCCState *s1, int token) case TOK_ASM_rdinstreth: asm_emit_opcode(opcode | (0xC82 << 20) | ENCODE_RD(op.reg)); return; + /* C extension */ case TOK_ASM_c_j: asm_emit_cj(token, 1 | (5 << 13), &op); return; @@ -375,6 +391,21 @@ static void asm_binary_opcode(TCCState* s1, int token) asm_emit_css(token, 2 | (5 << 13), ops, ops + 1); return; + /* pseudoinstructions */ + /* rd, sym */ + case TOK_ASM_la: + /* auipc rd, 0 */ + asm_emit_u(token, 3 | (5 << 2), ops, ops + 1); + /* lw rd, rd, 0 */ + asm_emit_i(token, 3 | (2 << 12), ops, ops, ops + 1); + return; + case TOK_ASM_lla: + /* auipc rd, 0 */ + asm_emit_u(token, 3 | (5 << 2), ops, ops + 1); + /* addi rd, rd, 0 */ + asm_emit_i(token, 3 | (4 << 2), ops, ops, ops + 1); + return; + default: expect("binary instruction"); } @@ -807,7 +838,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) case TOK_ASM_hrts: case TOK_ASM_mrth: case TOK_ASM_mrts: - case TOK_ASM_nop: case TOK_ASM_wfi: asm_nullary_opcode(s1, token); return; @@ -952,6 +982,16 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) asm_ternary_opcode(s1, token); return; + /* pseudoinstructions */ + case TOK_ASM_nop: + asm_nullary_opcode(s1, token); + return; + + case TOK_ASM_la: + case TOK_ASM_lla: + asm_binary_opcode(s1, token); + return; + default: expect("known instruction"); } diff --git a/riscv64-tok.h b/riscv64-tok.h index 92369d92..ecf448ef 100644 --- a/riscv64-tok.h +++ b/riscv64-tok.h @@ -244,10 +244,6 @@ DEF_ASM(rdinstret) DEF_ASM(rdinstreth) -/* no operation */ - DEF_ASM(nop) - DEF_ASM_WITH_SUFFIX(c, nop) - /* “M” Standard Extension for Integer Multiplication and Division, V2.0 */ DEF_ASM(mul) DEF_ASM(mulh) @@ -265,6 +261,7 @@ DEF_ASM(remuw) /* "C" Extension for Compressed Instructions, V2.0 */ + DEF_ASM_WITH_SUFFIX(c, nop) /* Loads */ DEF_ASM_WITH_SUFFIX(c, li) DEF_ASM_WITH_SUFFIX(c, lw) @@ -360,8 +357,10 @@ DEF_ASM(csrw) DEF_ASM(csrwi) DEF_ASM(frcsr) + DEF_ASM(frflags) DEF_ASM(frrm) DEF_ASM(fscsr) + DEF_ASM(fsflags) DEF_ASM(fsrm) /* Privileged Instructions */ @@ -371,4 +370,43 @@ DEF_ASM(hrts) DEF_ASM(wfi) +/* pseudoinstructions */ + DEF_ASM(beqz) + DEF_ASM(bgez) + DEF_ASM(bgt) + DEF_ASM(bgtu) + DEF_ASM(bgtz) + DEF_ASM(ble) + DEF_ASM(bleu) + DEF_ASM(blez) + DEF_ASM(bltz) + DEF_ASM(bnez) + DEF_ASM(call) + DEF_ASM_WITH_SUFFIX(fabs, d) + DEF_ASM_WITH_SUFFIX(fabs, s) + DEF_ASM(fld) + DEF_ASM(flw) + DEF_ASM_WITH_SUFFIX(fmv, d) + DEF_ASM_WITH_SUFFIX(fmv, s) + DEF_ASM_WITH_SUFFIX(fneg, d) + DEF_ASM_WITH_SUFFIX(fneg, s) + DEF_ASM(fsd) + DEF_ASM(fsw) + DEF_ASM(j) + DEF_ASM(la) + DEF_ASM(li) + DEF_ASM(lla) + DEF_ASM(mv) + DEF_ASM(neg) + DEF_ASM(negw) + DEF_ASM(nop) + DEF_ASM(not) + DEF_ASM(ret) + DEF_ASM(seqz) + DEF_ASM_WITH_SUFFIX(sext, w) + DEF_ASM(sgtz) + DEF_ASM(sltz) + DEF_ASM(snez) + DEF_ASM(tail) + #undef DEF_ASM_WITH_SUFFIX