mirror of
https://github.com/micropython/micropython.git
synced 2026-01-06 04:00:28 +01:00
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>
This commit is contained in:
committed by
Damien George
parent
3044233ea3
commit
268acb714d
302
py/asmrv32.h
302
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user