From 4891ab71a06a274a54fa0d34b76fe454e50d8ad4 Mon Sep 17 00:00:00 2001 From: Danny Milosavljevic Date: Tue, 6 Apr 2021 12:43:21 +0200 Subject: [PATCH] riscv64-asm: Add fence, fence.i, scall, sbreak, ecall, ebreak, wfi --- riscv64-asm.c | 65 ++++++++++++++++++++++++++++++- riscv64-tok.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ tcctok.h | 3 ++ 3 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 riscv64-tok.h diff --git a/riscv64-asm.c b/riscv64-asm.c index f7ba3bee..167d5251 100644 --- a/riscv64-asm.c +++ b/riscv64-asm.c @@ -49,9 +49,70 @@ ST_FUNC void gen_expr32(ExprValue *pe) gen_le32(pe->v); } -ST_FUNC void asm_opcode(TCCState *s1, int opcode) +static void asm_emit_opcode(uint32_t opcode) { + gen_le32(opcode); +} + +static void asm_nullary_opcode(TCCState *s1, int token) { - tcc_error("RISCV64 asm not implemented."); + switch (token) { + // Sync instructions + + case TOK_ASM_fence: // I + asm_emit_opcode((0x3 << 2) | 3 | (0 << 12)); + return; + case TOK_ASM_fence_i: // I + asm_emit_opcode((0x3 << 2) | 3| (1 << 12)); + return; + + // System calls + + case TOK_ASM_scall: // I (pseudo) + asm_emit_opcode((0x1C << 2) | 3 | (0 << 12)); + return; + case TOK_ASM_sbreak: // I (pseudo) + asm_emit_opcode((0x1C << 2) | 3 | (0 << 12) | (1 << 20)); + return; + + // Privileged Instructions + + case TOK_ASM_ecall: + asm_emit_opcode((0x1C << 2) | 3 | (0 << 20)); + return; + case TOK_ASM_ebreak: + asm_emit_opcode((0x1C << 2) | 3 | (1 << 20)); + return; + + // Other + + case TOK_ASM_wfi: + asm_emit_opcode((0x1C << 2) | 3 | (0x105 << 20)); + return; + + default: + expect("nullary instruction"); + } +} + +ST_FUNC void asm_opcode(TCCState *s1, int token) +{ + switch (token) { + case TOK_ASM_fence: + case TOK_ASM_fence_i: + case TOK_ASM_scall: + case TOK_ASM_sbreak: + case TOK_ASM_ecall: + case TOK_ASM_ebreak: + case TOK_ASM_mrts: + case TOK_ASM_mrth: + case TOK_ASM_hrts: + case TOK_ASM_wfi: + asm_nullary_opcode(s1, token); + return; + + default: + expect("known instruction"); + } } ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) diff --git a/riscv64-tok.h b/riscv64-tok.h new file mode 100644 index 00000000..af0e186b --- /dev/null +++ b/riscv64-tok.h @@ -0,0 +1,104 @@ +/* ------------------------------------------------------------------ */ +/* WARNING: relative order of tokens is important. */ + +// See https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf + +/* register */ + + DEF_ASM(x0) + DEF_ASM(x1) + DEF_ASM(x2) + DEF_ASM(x3) + DEF_ASM(x4) + DEF_ASM(x5) + DEF_ASM(x6) + DEF_ASM(x7) + DEF_ASM(x8) + DEF_ASM(x9) + DEF_ASM(x10) + DEF_ASM(x11) + DEF_ASM(x12) + DEF_ASM(x13) + DEF_ASM(x14) + DEF_ASM(x15) + DEF_ASM(x16) + DEF_ASM(x17) + DEF_ASM(x18) + DEF_ASM(x19) + DEF_ASM(x20) + DEF_ASM(x21) + DEF_ASM(x22) + DEF_ASM(x23) + DEF_ASM(x24) + DEF_ASM(x25) + DEF_ASM(x26) + DEF_ASM(x27) + DEF_ASM(x28) + DEF_ASM(x29) + DEF_ASM(x30) + DEF_ASM(x31) + +/* register macros */ + + DEF_ASM(zero) +/* + DEF_ASM(ra) + DEF_ASM(sp) + DEF_ASM(gp) + DEF_ASM(tp) + DEF_ASM(t0) + DEF_ASM(t1) + DEF_ASM(t2) + DEF_ASM(fp) + DEF_ASM(s1) + DEF_ASM(a0) + DEF_ASM(a1) + DEF_ASM(a2) + DEF_ASM(a3) + DEF_ASM(a4) + DEF_ASM(a5) + DEF_ASM(a6) + DEF_ASM(a7) + DEF_ASM(s2) + DEF_ASM(s3) + DEF_ASM(s4) + DEF_ASM(s5) + DEF_ASM(s6) + DEF_ASM(s7) + DEF_ASM(s8) + DEF_ASM(s9) + DEF_ASM(s10) + DEF_ASM(s11) + DEF_ASM(t3) + DEF_ASM(t4) + DEF_ASM(t5) + DEF_ASM(t6) + + DEF_ASM(s0) // = x8 +*/ + + DEF_ASM(pc) + +#define DEF_ASM_WITH_SUFFIX(x, y) \ + DEF(TOK_ASM_ ## x ## _ ## y, #x #y) + +/* Sync */ + + DEF_ASM(fence) + DEF_ASM_WITH_SUFFIX(fence, i) + +/* System call */ + + DEF_ASM(scall) + DEF_ASM(sbreak) + +/* Privileged Instructions */ + + DEF_ASM(ecall) + DEF_ASM(ebreak) + + DEF_ASM(mrts) + DEF_ASM(mrth) + DEF_ASM(hrts) + DEF_ASM(wfi) + diff --git a/tcctok.h b/tcctok.h index 87fb2c34..e5bc5fbe 100644 --- a/tcctok.h +++ b/tcctok.h @@ -391,3 +391,6 @@ #if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 #include "arm-tok.h" #endif +#if defined TCC_TARGET_RISCV64 +#include "riscv64-tok.h" +#endif