From 0b1cc489e16163ad3ed2b9de1bc4567dca46c3d5 Mon Sep 17 00:00:00 2001 From: Danny Milosavljevic Date: Tue, 6 Apr 2021 13:13:52 +0200 Subject: [PATCH] riscv64-asm: Add lui, auipc --- riscv64-asm.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ riscv64-tok.h | 5 +++++ 2 files changed, 53 insertions(+) diff --git a/riscv64-asm.c b/riscv64-asm.c index 4a1ab1d0..011f7982 100644 --- a/riscv64-asm.c +++ b/riscv64-asm.c @@ -179,6 +179,49 @@ static void asm_unary_opcode(TCCState *s1, int token) } } +static void asm_emit_u(int token, uint32_t opcode, const Operand* rd, const Operand* rs2) +{ + if (rd->type != OP_REG) { + tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL)); + return; + } + if (rs2->type != OP_IM12S && rs2->type != OP_IM32) { + tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL)); + return; + } else if (rs2->e.v >= 0x100000) { + tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(token, NULL)); + return; + } + /* U-type instruction: + 31...12 imm[31:12] + 11...7 rd + 6...0 opcode */ + gen_le32(opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12)); +} + +static void asm_binary_opcode(TCCState* s1, int token) +{ + Operand ops[2]; + parse_operand(s1, &ops[0]); + if (tok == ',') + next(); + else + expect("','"); + parse_operand(s1, &ops[1]); + + switch (token) { + case TOK_ASM_lui: + asm_emit_u(token, (0xD << 2) | 3, &ops[0], &ops[1]); + return; + case TOK_ASM_auipc: + asm_emit_u(token, (0x05 << 2) | 3, &ops[0], &ops[1]); + return; + default: + expect("binary instruction"); + } +} + + ST_FUNC void asm_opcode(TCCState *s1, int token) { switch (token) { @@ -204,6 +247,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) asm_unary_opcode(s1, token); return; + case TOK_ASM_lui: + case TOK_ASM_auipc: + asm_binary_opcode(s1, token); + return; + default: expect("known instruction"); } diff --git a/riscv64-tok.h b/riscv64-tok.h index d6709efd..5a81d1fc 100644 --- a/riscv64-tok.h +++ b/riscv64-tok.h @@ -82,6 +82,11 @@ #define DEF_ASM_WITH_SUFFIX(x, y) \ DEF(TOK_ASM_ ## x ## _ ## y, #x #y) +/* Arithmetic */ + + DEF_ASM(lui) + DEF_ASM(auipc) + /* Sync */ DEF_ASM(fence)