diff options
| author | Alessandro Gatti <a.gatti@frob.it> | 2024-08-25 16:28:35 +0200 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2025-01-02 11:49:10 +1100 |
| commit | 268acb714dd79fa5eeeb82c1fca022bc4ea126b7 (patch) | |
| tree | 428ed75070ee89847fd5087095e3d7331d5f9b26 /py/asmrv32.h | |
| parent | 3044233ea3726e9d8727d8f6a76f32c48e6fae5e (diff) | |
py/emitinlinerv32: Add inline assembler support for RV32.
This commit adds support for writing inline assembler functions when
targeting a RV32IMC processor.
Given that this takes up a bit of rodata space due to its large
instruction decoding table and its extensive error messages, it is
enabled by default only on offline targets such as mpy-cross and the
qemu port.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
Diffstat (limited to 'py/asmrv32.h')
| -rw-r--r-- | py/asmrv32.h | 302 |
1 files changed, 284 insertions, 18 deletions
diff --git a/py/asmrv32.h b/py/asmrv32.h index 775cf1ffc..584e3ffd2 100644 --- a/py/asmrv32.h +++ b/py/asmrv32.h @@ -74,9 +74,6 @@ #define ASM_RV32_REG_SP (ASM_RV32_REG_X2) #define ASM_RV32_REG_GP (ASM_RV32_REG_X3) #define ASM_RV32_REG_TP (ASM_RV32_REG_X4) -#define ASM_RV32_REG_T0 (ASM_RV32_REG_X5) -#define ASM_RV32_REG_T1 (ASM_RV32_REG_X6) -#define ASM_RV32_REG_T2 (ASM_RV32_REG_X7) #define ASM_RV32_REG_A0 (ASM_RV32_REG_X10) #define ASM_RV32_REG_A1 (ASM_RV32_REG_X11) #define ASM_RV32_REG_A2 (ASM_RV32_REG_X12) @@ -85,6 +82,9 @@ #define ASM_RV32_REG_A5 (ASM_RV32_REG_X15) #define ASM_RV32_REG_A6 (ASM_RV32_REG_X16) #define ASM_RV32_REG_A7 (ASM_RV32_REG_X17) +#define ASM_RV32_REG_T0 (ASM_RV32_REG_X5) +#define ASM_RV32_REG_T1 (ASM_RV32_REG_X6) +#define ASM_RV32_REG_T2 (ASM_RV32_REG_X7) #define ASM_RV32_REG_T3 (ASM_RV32_REG_X28) #define ASM_RV32_REG_T4 (ASM_RV32_REG_X29) #define ASM_RV32_REG_T5 (ASM_RV32_REG_X30) @@ -103,6 +103,12 @@ #define ASM_RV32_REG_S10 (ASM_RV32_REG_X26) #define ASM_RV32_REG_S11 (ASM_RV32_REG_X27) +#define RV32_AVAILABLE_REGISTERS_COUNT 32 +#define RV32_MAP_IN_C_REGISTER_WINDOW(register_number) \ + ((register_number) - ASM_RV32_REG_X8) +#define RV32_IS_IN_C_REGISTER_WINDOW(register_number) \ + (((register_number) >= ASM_RV32_REG_X8) && ((register_number) <= ASM_RV32_REG_X15)) + typedef struct _asm_rv32_t { // Opaque emitter state. mp_asm_base_t base; @@ -127,6 +133,10 @@ void asm_rv32_end_pass(asm_rv32_t *state); ((imm & 0x1E) << 7) | ((rs1 & 0x1F) << 15) | ((rs2 & 0x1F) << 20) | \ ((imm & 0x7E0) << 20) | ((imm & 0x1000) << 19)) +#define RV32_ENCODE_TYPE_CSRI(op, ft3, rd, csr, imm) \ + ((op & 0x7F) | ((rd & 0x1F) << 7) | ((ft3 & 0x07) << 12) | \ + ((csr & 0xFFF) << 20) | ((imm & 0x1F) << 15)) + #define RV32_ENCODE_TYPE_I(op, ft3, rd, rs, imm) \ ((op & 0x7F) | ((rd & 0x1F) << 7) | ((ft3 & 0x07) << 12) | \ ((rs & 0x1F) << 15) | ((imm & 0xFFF) << 20)) @@ -143,13 +153,16 @@ void asm_rv32_end_pass(asm_rv32_t *state); ((op & 0x7F) | ((imm & 0x1F) << 7) | ((ft3 & 0x07) << 12) | \ ((rs1 & 0x1F) << 15) | ((rs2 & 0x1F) << 20) | ((imm & 0xFE0) << 20)) +#define RV32_ENCODE_TYPE_CA(op, ft6, ft2, rd, rs) \ + ((op & 0x03) | ((ft6 & 0x3F) << 10) | ((ft2 & 0x03) << 5) | \ + ((rd & 0x03) << 7) | ((rs & 0x03) << 2)) + #define RV32_ENCODE_TYPE_U(op, rd, imm) \ ((op & 0x7F) | ((rd & 0x1F) << 7) | (imm & 0xFFFFF000)) #define RV32_ENCODE_TYPE_CB(op, ft3, rs, imm) \ ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rs & 0x07) << 7) | \ - (((imm) & 0x100) << 4) | (((imm) & 0xC0) >> 1) | (((imm) & 0x20) >> 3) | \ - (((imm) & 0x18) << 7) | (((imm) & 0x06) << 2)) + (((imm) & 0xE0) << 5) | (((imm) & 0x1F) << 2)) #define RV32_ENCODE_TYPE_CI(op, ft3, rd, imm) \ ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rd & 0x1F) << 7) | \ @@ -174,6 +187,11 @@ void asm_rv32_end_pass(asm_rv32_t *state); #define RV32_ENCODE_TYPE_CR(op, ft4, rs1, rs2) \ ((op & 0x03) | ((rs2 & 0x1F) << 2) | ((rs1 & 0x1F) << 7) | ((ft4 & 0x0F) << 12)) +#define RV32_ENCODE_TYPE_CS(op, ft3, rd, rs, imm) \ + ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rd & 0x07) << 2) | \ + ((rs & 0x07) << 7) | ((imm & 0x40) >> 1) | ((imm & 0x38) << 7) | \ + ((imm & 0x04) << 4)) + #define RV32_ENCODE_TYPE_CSS(op, ft3, rs, imm) \ ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rs & 0x1F) << 2) | ((imm) & 0x3F) << 7) @@ -198,6 +216,12 @@ static inline void asm_rv32_opcode_and(asm_rv32_t *state, mp_uint_t rd, mp_uint_ asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x07, 0x00, rd, rs1, rs2)); } +// ANDI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_andi(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 111 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x07, rd, rs, immediate)); +} + // AUIPC RD, offset static inline void asm_rv32_opcode_auipc(asm_rv32_t *state, mp_uint_t rd, mp_int_t offset) { // U: .................... ..... 0010111 @@ -210,6 +234,30 @@ static inline void asm_rv32_opcode_beq(asm_rv32_t *state, mp_uint_t rs1, mp_uint asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x00, rs1, rs2, offset)); } +// BGE RS1, RS2, OFFSET +static inline void asm_rv32_opcode_bge(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 101 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x05, rs1, rs2, offset)); +} + +// BGEU RS1, RS2, OFFSET +static inline void asm_rv32_opcode_bgeu(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 111 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x07, rs1, rs2, offset)); +} + +// BLT RS1, RS2, OFFSET +static inline void asm_rv32_opcode_blt(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 100 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x04, rs1, rs2, offset)); +} + +// BLTU RS1, RS2, OFFSET +static inline void asm_rv32_opcode_bltu(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 110 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x06, rs1, rs2, offset)); +} + // BNE RS1, RS2, OFFSET static inline void asm_rv32_opcode_bne(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { // B: . ...... ..... ..... 001 .... . 1100011 @@ -234,16 +282,39 @@ static inline void asm_rv32_opcode_caddi4spn(asm_rv32_t *state, mp_uint_t rd, mp asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CIW(0x00, 0x00, rd, immediate)); } +// C.AND RD', RS' +static inline void asm_rv32_opcode_cand(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CA: 100011 ... 11 ... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CA(0x01, 0x23, 0x03, rd, rs)); +} + +// C.ANDI RD', IMMEDIATE +static inline void asm_rv32_opcode_candi(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CB: 100 . 10 ... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x04, rd, + (((immediate & 0x20) << 2) | (immediate & 0x1F) | 0x40))); +} + // C.BEQZ RS', IMMEDIATE static inline void asm_rv32_opcode_cbeqz(asm_rv32_t *state, mp_uint_t rs, mp_int_t offset) { // CB: 110 ... ... ..... 01 - asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x06, rs, offset)); + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x06, rs, + (((offset & 0x100) >> 1) | ((offset & 0xC0) >> 3) | ((offset & 0x20) >> 5) | + ((offset & 0x18) << 2) | (offset & 0x06)))); } // C.BNEZ RS', IMMEDIATE static inline void asm_rv32_opcode_cbnez(asm_rv32_t *state, mp_uint_t rs, mp_int_t offset) { // CB: 111 ... ... ..... 01 - asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x07, rs, offset)); + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x07, rs, + (((offset & 0x100) >> 1) | ((offset & 0xC0) >> 3) | ((offset & 0x20) >> 5) | + ((offset & 0x18) << 2) | (offset & 0x06)))); +} + +// C.EBREAK +static inline void asm_rv32_opcode_cebreak(asm_rv32_t *state) { + // CA: 100 1 00000 00000 10 + asm_rv32_emit_halfword_opcode(state, 0x9002); } // C.J OFFSET @@ -252,6 +323,12 @@ static inline void asm_rv32_opcode_cj(asm_rv32_t *state, mp_int_t offset) { asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CJ(0x01, 0x05, offset)); } +// C.JAL OFFSET +static inline void asm_rv32_opcode_cjal(asm_rv32_t *state, mp_int_t offset) { + // CJ: 001 ........... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CJ(0x01, 0x01, offset)); +} + // C.JALR RS static inline void asm_rv32_opcode_cjalr(asm_rv32_t *state, mp_uint_t rs) { // CR: 1001 ..... 00000 10 @@ -294,31 +371,159 @@ static inline void asm_rv32_opcode_cmv(asm_rv32_t *state, mp_uint_t rd, mp_uint_ asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CR(0x02, 0x08, rd, rs)); } +// C.NOP +static inline void asm_rv32_opcode_cnop(asm_rv32_t *state) { + // CI: 000 . 00000 ..... 01 + asm_rv32_emit_halfword_opcode(state, 0x0001); +} + +// C.OR RD', RS' +static inline void asm_rv32_opcode_cor(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CA: 100011 ... 10 ... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CA(0x01, 0x23, 0x02, rd, rs)); +} + +// C.SLLI RD, IMMEDIATE +static inline void asm_rv32_opcode_cslli(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CI: 000 . ..... ..... 10 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CI(0x02, 0x00, rd, immediate)); +} + +// C.SRAI RD, IMMEDIATE +static inline void asm_rv32_opcode_csrai(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CB: 100 . 01 ... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x04, rd, + (((immediate & 0x20) << 2) | (immediate & 0x1F) | 0x20))); +} + +// C.SRLI RD, IMMEDIATE +static inline void asm_rv32_opcode_csrli(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CB: 100 . 00 ... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x04, rd, + (((immediate & 0x20) << 2) | (immediate & 0x1F)))); +} + +// C.SUB RD', RS' +static inline void asm_rv32_opcode_csub(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CA: 100011 ... 00 ... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CA(0x01, 0x23, 0x00, rd, rs)); +} + +// C.SW RS1', OFFSET(RS2') +static inline void asm_rv32_opcode_csw(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // CS: 110 ... ... .. ... 00 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CL(0x00, 0x06, rs1, rs2, offset)); +} + // C.SWSP RS, OFFSET static inline void asm_rv32_opcode_cswsp(asm_rv32_t *state, mp_uint_t rs, mp_uint_t offset) { // CSS: 010 ...... ..... 10 asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CSS(0x02, 0x06, rs, ((offset & 0xC0) >> 6) | (offset & 0x3C))); } -// JALR RD, RS, offset +// C.XOR RD', RS' +static inline void asm_rv32_opcode_cxor(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CA: 100011 ... 01 ... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CA(0x01, 0x23, 0x01, rd, rs)); +} + +// CSRRC RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_csrrc(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 011 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x73, 0x03, rd, rs, immediate)); +} + +// CSRRS RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_csrrs(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 010 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x73, 0x02, rd, rs, immediate)); +} + +// CSRRW RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_csrrw(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 001 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x73, 0x01, rd, rs, immediate)); +} + +// CSRRCI RD, CSR, IMMEDIATE +static inline void asm_rv32_opcode_csrrci(asm_rv32_t *state, mp_uint_t rd, mp_uint_t csr, mp_int_t immediate) { + // CSRI: ............ ..... 111 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_CSRI(0x73, 0x07, rd, csr, immediate)); +} + +// CSRRSI RD, CSR, IMMEDIATE +static inline void asm_rv32_opcode_csrrsi(asm_rv32_t *state, mp_uint_t rd, mp_uint_t csr, mp_int_t immediate) { + // CSRI: ............ ..... 110 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_CSRI(0x73, 0x06, rd, csr, immediate)); +} + +// CSRRWI RD, CSR, IMMEDIATE +static inline void asm_rv32_opcode_csrrwi(asm_rv32_t *state, mp_uint_t rd, mp_uint_t csr, mp_int_t immediate) { + // CSRI: ............ ..... 101 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_CSRI(0x73, 0x05, rd, csr, immediate)); +} + +// DIV RD, RS1, RS2 +static inline void asm_rv32_opcode_div(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 100 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x04, 0x01, rd, rs1, rs2)); +} + +// DIVU RD, RS1, RS2 +static inline void asm_rv32_opcode_divu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 101 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x05, 0x01, rd, rs1, rs2)); +} + +// EBREAK +static inline void asm_rv32_opcode_ebreak(asm_rv32_t *state) { + // I: 000000000001 00000 000 00000 1110011 + asm_rv32_emit_word_opcode(state, 0x100073); +} + +// ECALL +static inline void asm_rv32_opcode_ecall(asm_rv32_t *state) { + // I: 000000000000 00000 000 00000 1110011 + asm_rv32_emit_word_opcode(state, 0x73); +} + +// JAL RD, OFFSET +static inline void asm_rv32_opcode_jal(asm_rv32_t *state, mp_uint_t rd, mp_int_t offset) { + // J: ......................... 1101111 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_J(0x6F, rd, offset)); +} + +// JALR RD, RS, OFFSET static inline void asm_rv32_opcode_jalr(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { // I: ............ ..... 000 ..... 1100111 asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x67, 0x00, rd, rs, offset)); } +// LB RD, OFFSET(RS) +static inline void asm_rv32_opcode_lb(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { + // I: ............ ..... 000 ..... 0000011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, 0x00, rd, rs, offset)); +} + // LBU RD, OFFSET(RS) static inline void asm_rv32_opcode_lbu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { // I: ............ ..... 100 ..... 0000011 asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, 0x04, rd, rs, offset)); } +// LH RD, OFFSET(RS) +static inline void asm_rv32_opcode_lh(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { + // I: ............ ..... 001 ..... 0000011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, 0x01, rd, rs, offset)); +} + // LHU RD, OFFSET(RS) static inline void asm_rv32_opcode_lhu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { // I: ............ ..... 101 ..... 0000011 asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, 0x05, rd, rs, offset)); } -// LUI RD, immediate +// LUI RD, IMMEDIATE static inline void asm_rv32_opcode_lui(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { // U: .................... ..... 0110111 asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_U(0x37, rd, immediate)); @@ -336,12 +541,48 @@ static inline void asm_rv32_opcode_mul(asm_rv32_t *state, mp_uint_t rd, mp_uint_ asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x00, 0x01, rd, rs1, rs2)); } +// MULH RD, RS1, RS2 +static inline void asm_rv32_opcode_mulh(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 001 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x01, 0x01, rd, rs1, rs2)); +} + +// MULHSU RD, RS1, RS2 +static inline void asm_rv32_opcode_mulhsu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 010 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x02, 0x01, rd, rs1, rs2)); +} + +// MULHU RD, RS1, RS2 +static inline void asm_rv32_opcode_mulhu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 011 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x03, 0x01, rd, rs1, rs2)); +} + // OR RD, RS1, RS2 static inline void asm_rv32_opcode_or(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { // R: 0000000 ..... ..... 110 ..... 0110011 asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x06, 0x00, rd, rs1, rs2)); } +// ORI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_ori(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 110 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x06, rd, rs, immediate)); +} + +// REM RD, RS1, RS2 +static inline void asm_rv32_opcode_rem(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 110 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x06, 0x01, rd, rs1, rs2)); +} + +// REMU RD, RS1, RS2 +static inline void asm_rv32_opcode_remu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 111 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x07, 0x01, rd, rs1, rs2)); +} + // SLL RD, RS1, RS2 static inline void asm_rv32_opcode_sll(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { // R: 0000000 ..... ..... 001 ..... 0110011 @@ -349,23 +590,29 @@ static inline void asm_rv32_opcode_sll(asm_rv32_t *state, mp_uint_t rd, mp_uint_ } // SLLI RD, RS, IMMEDIATE -static inline void asm_rv32_opcode_slli(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_uint_t immediate) { +static inline void asm_rv32_opcode_slli(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { // I: 0000000..... ..... 001 ..... 0010011 asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x01, rd, rs, immediate & 0x1F)); } -// SRL RD, RS1, RS2 -static inline void asm_rv32_opcode_srl(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { - // R: 0000000 ..... ..... 101 ..... 0110011 - asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x05, 0x00, rd, rs1, rs2)); -} - // SLT RD, RS1, RS2 static inline void asm_rv32_opcode_slt(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { // R: 0000000 ..... ..... 010 ..... 0110011 asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x02, 0x00, rd, rs1, rs2)); } +// SLTI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_slti(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 010 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x02, rd, rs, immediate)); +} + +// SLTIU RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_sltiu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 011 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x03, rd, rs, immediate)); +} + // SLTU RD, RS1, RS2 static inline void asm_rv32_opcode_sltu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { // R: 0000000 ..... ..... 011 ..... 0110011 @@ -378,6 +625,24 @@ static inline void asm_rv32_opcode_sra(asm_rv32_t *state, mp_uint_t rd, mp_uint_ asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x05, 0x20, rd, rs1, rs2)); } +// SRAI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_srai(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: 0100000..... ..... 101 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x05, rd, rs, ((immediate & 0x1F) | 0x400))); +} + +// SRL RD, RS1, RS2 +static inline void asm_rv32_opcode_srl(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000000 ..... ..... 101 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x05, 0x00, rd, rs1, rs2)); +} + +// SRLI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_srli(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: 0000000..... ..... 101 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x05, rd, rs, immediate & 0x1F)); +} + // SUB RD, RS1, RS2 static inline void asm_rv32_opcode_sub(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { // R: 0100000 ..... ..... 000 ..... 0110011 @@ -435,6 +700,8 @@ void asm_rv32_meta_comparison_ne(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2 void asm_rv32_meta_comparison_lt(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd, bool unsigned_comparison); void asm_rv32_meta_comparison_le(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd, bool unsigned_comparison); +void asm_rv32_emit_optimised_load_immediate(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate); + #ifdef GENERIC_ASM_API void asm_rv32_emit_call_ind(asm_rv32_t *state, mp_uint_t index); @@ -444,10 +711,9 @@ void asm_rv32_emit_jump_if_reg_nonzero(asm_rv32_t *state, mp_uint_t rs, mp_uint_ void asm_rv32_emit_load16_reg_reg_offset(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset); void asm_rv32_emit_load_reg_reg_offset(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset); void asm_rv32_emit_mov_local_reg(asm_rv32_t *state, mp_uint_t local, mp_uint_t rs); -void asm_rv32_emit_mov_reg_local(asm_rv32_t *state, mp_uint_t rd, mp_uint_t local); void asm_rv32_emit_mov_reg_local_addr(asm_rv32_t *state, mp_uint_t rd, mp_uint_t local); +void asm_rv32_emit_mov_reg_local(asm_rv32_t *state, mp_uint_t rd, mp_uint_t local); void asm_rv32_emit_mov_reg_pcrel(asm_rv32_t *state, mp_uint_t rd, mp_uint_t label); -void asm_rv32_emit_optimised_load_immediate(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate); void asm_rv32_emit_optimised_xor(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs); void asm_rv32_emit_store_reg_reg_offset(asm_rv32_t *state, mp_uint_t source, mp_uint_t base, mp_int_t offset); |
