diff --git a/src/as/arch/aarch64/asm_code.c b/src/as/arch/aarch64/asm_code.c index 5b3bf9f28..1743aa97a 100644 --- a/src/as/arch/aarch64/asm_code.c +++ b/src/as/arch/aarch64/asm_code.c @@ -8,14 +8,6 @@ #include "parse_asm.h" #include "util.h" -#ifndef MAKE_CODE16 -#define MAKE_CODE16(inst, code, ...) do { unsigned short buf[] = {__VA_ARGS__}; make_code16(inst, code, buf, sizeof(buf)); } while (0) -#endif - -#ifndef MAKE_CODE32 -#define MAKE_CODE32(inst, code, ...) do { unsigned int buf[] = {__VA_ARGS__}; make_code32(inst, code, buf, sizeof(buf)); } while (0) -#endif - void make_code16(Inst *inst, Code *code, unsigned short *buf, int len) { assert(code->len + len <= (int)sizeof(code->buf)); code->inst = inst; diff --git a/src/as/arch/riscv64/asm_code.c b/src/as/arch/riscv64/asm_code.c index 2bb5f4629..41249b2d6 100644 --- a/src/as/arch/riscv64/asm_code.c +++ b/src/as/arch/riscv64/asm_code.c @@ -6,16 +6,9 @@ #include "inst.h" #include "parse_asm.h" +#include "riscv64_code.h" #include "util.h" -#ifndef MAKE_CODE16 -#define MAKE_CODE16(inst, code, ...) do { unsigned short buf[] = {__VA_ARGS__}; make_code16(inst, code, buf, sizeof(buf)); } while (0) -#endif - -#ifndef MAKE_CODE32 -#define MAKE_CODE32(inst, code, ...) do { unsigned int buf[] = {__VA_ARGS__}; make_code32(inst, code, buf, sizeof(buf)); } while (0) -#endif - void make_code16(Inst *inst, Code *code, unsigned short *buf, int len) { assert(code->len + len <= (int)sizeof(code->buf)); code->inst = inst; @@ -45,168 +38,6 @@ inline bool assemble_error(const ParseInfo *info, const char *message) { // -#define ZERO 0 -#define RA 1 -#define SP 2 - -#define IMM(imm, t, b) (((imm) >> (b)) & ((1 << (t - b + 1)) - 1)) -#define RTYPE(funct7, rs2, rs1, funct3, rd, opcode) MAKE_CODE32(inst, code, ((funct7) << 25) | ((rs2) << 20) | ((rs1) << 15) | ((funct3) << 12) | ((rd) << 7) | (opcode)) // R-type -#define ITYPE(imm, rs1, funct3, rd, opcode) MAKE_CODE32(inst, code, (IMM(imm, 11, 0) << 20) | ((rs1) << 15) | ((funct3) << 12) | ((rd) << 7) | (opcode)) // I-type -#define STYPE(imm, rs2, rs1, funct3, opcode) MAKE_CODE32(inst, code, (IMM(imm, 11, 5) << 25) | ((rs2) << 20) | ((rs1) << 15) | ((funct3) << 12) | (IMM(imm, 4, 0) << 7) | (opcode)) // S-type -#define BTYPE(imm, rs2, rs1, funct3, opcode) MAKE_CODE32(inst, code, (IMM(imm, 12, 12) << 31) | (IMM(imm, 10, 5) << 25) | ((rs2) << 20) | ((rs1) << 15) | ((funct3) << 12) | (IMM(imm, 4, 0) << 7) | (opcode)) // B-type -#define UTYPE(imm, rd, opcode) MAKE_CODE32(inst, code, (IMM(imm, 31, 12) << 12) | ((rd) << 7) | (opcode)) // U-type -#define JTYPE(imm, rd, opcode) MAKE_CODE32(inst, code, (IMM(imm, 20, 20) << 31) | (IMM(imm, 10, 1) << 20) | (IMM(imm, 11, 11) << 19) | (IMM(imm, 19, 12) << 12) | ((rd) << 7) | (opcode)) // J-type - -#define W_ADD(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x00, rd, 0x33) -#define W_ADDW(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x00, rd, 0x3b) -#define W_ADDI(rd, rs, imm) ITYPE(imm, rs, 0x00, rd, 0x13) -#define W_ADDIW(rd, rs, imm) ITYPE(imm, rs, 0x00, rd, 0x1b) -#define W_SUB(rd, rs1, rs2) RTYPE(0x20, rs2, rs1, 0x00, rd, 0x33) -#define W_SUBW(rd, rs1, rs2) RTYPE(0x20, rs2, rs1, 0x00, rd, 0x3b) -#define W_MUL(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x00, rd, 0x33) -#define W_MULW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x00, rd, 0x3b) -#define W_DIV(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x04, rd, 0x33) -#define W_DIVU(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x05, rd, 0x33) -#define W_DIVW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x04, rd, 0x3b) -#define W_DIVUW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x05, rd, 0x3b) -#define W_REM(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x06, rd, 0x33) -#define W_REMU(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x07, rd, 0x33) -#define W_REMW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x06, rd, 0x3b) -#define W_REMUW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x07, rd, 0x3b) -#define W_AND(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x07, rd, 0x33) -#define W_ANDI(rd, rs, imm) ITYPE(imm, rs, 0x07, rd, 0x13) -#define W_OR(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x06, rd, 0x33) -#define W_ORI(rd, rs, imm) ITYPE(imm, rs, 0x06, rd, 0x13) -#define W_XOR(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x04, rd, 0x33) -#define W_XORI(rd, rs, imm) ITYPE(imm, rs, 0x04, rd, 0x13) -#define W_SLL(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x01, rd, 0x33) -#define W_SLLI(rd, rs, imm) ITYPE((imm) & 63, rs, 0x01, rd, 0x13) -#define W_SLLIW(rd, rs, imm) ITYPE((imm) & 31, rs, 0x01, rd, 0x1b) -#define W_SRL(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x05, rd, 0x33) -#define W_SRLI(rd, rs, imm) ITYPE((imm) & 63, rs, 0x05, rd, 0x13) -#define W_SRA(rd, rs1, rs2) RTYPE(0x20, rs2, rs1, 0x05, rd, 0x33) -#define W_SRAI(rd, rs, imm) ITYPE(0x400 | ((imm) & 63), rs, 0x05, rd, 0x13) -#define W_SLT(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x02, rd, 0x33) -#define W_SLTU(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x03, rd, 0x33) -#define W_SLTI(rd, rs, imm) ITYPE(imm, rs, 0x02, rd, 0x13) -#define W_SLTIU(rd, rs, imm) ITYPE(imm, rs, 0x03, rd, 0x13) -#define W_LB(rd, ofs, rs) ITYPE(ofs, rs, 0x00, rd, 0x03) -#define W_LH(rd, ofs, rs) ITYPE(ofs, rs, 0x01, rd, 0x03) -#define W_LW(rd, ofs, rs) ITYPE(ofs, rs, 0x02, rd, 0x03) -#define W_LD(rd, ofs, rs) ITYPE(ofs, rs, 0x03, rd, 0x03) -#define W_LBU(rd, ofs, rs) ITYPE(ofs, rs, 0x04, rd, 0x03) -#define W_LHU(rd, ofs, rs) ITYPE(ofs, rs, 0x05, rd, 0x03) -#define W_LWU(rd, ofs, rs) ITYPE(ofs, rs, 0x06, rd, 0x03) -#define W_SB(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x00, 0x23) -#define W_SH(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x01, 0x23) -#define W_SW(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x02, 0x23) -#define W_SD(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x03, 0x23) -#define W_LUI(rd, imm) UTYPE(imm, rd, 0x37) -#define W_AUIPC(rd, imm) UTYPE(imm, rd, 0x17) -#define W_JALR(rd, rs, imm) ITYPE(imm, rs, 0x00, rd, 0x67) -#define W_BXX(funct3, rs1, rs2, ofs) STYPE(ofs, rs2, rs1, funct3, 0x63) - -#define W_FADD_D(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x07, rd, 0x53) -#define W_FSUB_D(rd, rs1, rs2) RTYPE(0x05, rs2, rs1, 0x07, rd, 0x53) -#define W_FMUL_D(rd, rs1, rs2) RTYPE(0x09, rs2, rs1, 0x07, rd, 0x53) -#define W_FDIV_D(rd, rs1, rs2) RTYPE(0x0d, rs2, rs1, 0x07, rd, 0x53) -#define W_FADD_S(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x07, rd, 0x53) -#define W_FSUB_S(rd, rs1, rs2) RTYPE(0x04, rs2, rs1, 0x07, rd, 0x53) -#define W_FMUL_S(rd, rs1, rs2) RTYPE(0x08, rs2, rs1, 0x07, rd, 0x53) -#define W_FDIV_S(rd, rs1, rs2) RTYPE(0x0c, rs2, rs1, 0x07, rd, 0x53) -#define W_FEQ_D(rd, rs1, rs2) RTYPE(0x51, rs2, rs1, 0x02, rd, 0x53) -#define W_FLT_D(rd, rs1, rs2) RTYPE(0x51, rs2, rs1, 0x01, rd, 0x53) -#define W_FLE_D(rd, rs1, rs2) RTYPE(0x51, rs2, rs1, 0x00, rd, 0x53) -#define W_FEQ_S(rd, rs1, rs2) RTYPE(0x50, rs2, rs1, 0x02, rd, 0x53) -#define W_FLT_S(rd, rs1, rs2) RTYPE(0x50, rs2, rs1, 0x01, rd, 0x53) -#define W_FLE_S(rd, rs1, rs2) RTYPE(0x50, rs2, rs1, 0x00, rd, 0x53) -#define W_FLD(rd, ofs, rs) ITYPE(ofs, rs, 0x03, rd, 0x07) -#define W_FLW(rd, ofs, rs) ITYPE(ofs, rs, 0x02, rd, 0x07) -#define W_FSD(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x03, 0x27) -#define W_FSW(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x02, 0x27) -#define W_FSGNJ_D(rd, rs1, rs2) RTYPE(0x11, rs2, rs1, 0x00, rd, 0x53) -#define W_FSGNJ_S(rd, rs1, rs2) RTYPE(0x10, rs2, rs1, 0x00, rd, 0x53) -#define W_FSGNJN_D(rd, rs1, rs2) RTYPE(0x11, rs2, rs1, 0x01, rd, 0x53) -#define W_FSGNJN_S(rd, rs1, rs2) RTYPE(0x10, rs2, rs1, 0x01, rd, 0x53) - -#define W_FCVT_D_W(rd, rs) RTYPE(0x69, 0, rs, 0x00, rd, 0x53) -#define W_FCVT_D_WU(rd, rs) RTYPE(0x69, 1, rs, 0x00, rd, 0x53) -#define W_FCVT_D_L(rd, rs) RTYPE(0x69, 2, rs, 0x07, rd, 0x53) -#define W_FCVT_D_LU(rd, rs) RTYPE(0x69, 3, rs, 0x07, rd, 0x53) -#define W_FCVT_S_W(rd, rs) RTYPE(0x68, 0, rs, 0x07, rd, 0x53) -#define W_FCVT_S_WU(rd, rs) RTYPE(0x68, 1, rs, 0x07, rd, 0x53) -#define W_FCVT_S_L(rd, rs) RTYPE(0x68, 2, rs, 0x07, rd, 0x53) -#define W_FCVT_S_LU(rd, rs) RTYPE(0x68, 3, rs, 0x07, rd, 0x53) - -#define W_FCVT_W_D(rd, rs, rm) RTYPE(0x61, 0, rs, rm, rd, 0x53) -#define W_FCVT_WU_D(rd, rs, rm) RTYPE(0x61, 1, rs, rm, rd, 0x53) -#define W_FCVT_L_D(rd, rs, rm) RTYPE(0x61, 2, rs, rm, rd, 0x53) -#define W_FCVT_LU_D(rd, rs, rm) RTYPE(0x61, 3, rs, rm, rd, 0x53) -#define W_FCVT_W_S(rd, rs, rm) RTYPE(0x60, 0, rs, rm, rd, 0x53) -#define W_FCVT_WU_S(rd, rs, rm) RTYPE(0x60, 1, rs, rm, rd, 0x53) -#define W_FCVT_L_S(rd, rs, rm) RTYPE(0x60, 2, rs, rm, rd, 0x53) -#define W_FCVT_LU_S(rd, rs, rm) RTYPE(0x60, 3, rs, rm, rd, 0x53) - -#define W_FCVT_D_S(rd, rs) RTYPE(0x21, 0, rs, 0x00, rd, 0x53) -#define W_FCVT_S_D(rd, rs) RTYPE(0x20, 1, rs, 0x07, rd, 0x53) - -#define W_FMV_X_D(rd, rs) RTYPE(0x71, 0, rs, 0x00, rd, 0x53) -#define W_FMV_X_W(rd, rs) RTYPE(0x70, 0, rs, 0x00, rd, 0x53) - -#define C_MV(rd, rs) MAKE_CODE16(inst, code, 0x8002 | ((rd) << 7) | ((rs) << 2)) -#define C_LI(rd, imm) MAKE_CODE16(inst, code, 0x4001 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 0) << 2)) -#define C_LUI(rd, imm) MAKE_CODE16(inst, code, 0x6001 | (IMM(imm, 17, 17) << 12) | ((rd) << 7) | (IMM(imm, 16, 12) << 2)) -#define C_ADD(rd, rs) MAKE_CODE16(inst, code, 0x9002 | ((rd) << 7) | ((rs) << 2)) -#define C_ADDW(rd, rs) MAKE_CODE16(inst, code, 0x9c21 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) -#define C_ADDI(rd, imm) MAKE_CODE16(inst, code, 0x0001 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 0) << 2)) -#define C_ADDIW(rd, imm) MAKE_CODE16(inst, code, 0x2001 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 0) << 2)) -#define C_ADDI16SP(imm) MAKE_CODE16(inst, code, 0x6101 | (IMM(imm, 9, 9) << 12) | (IMM(imm, 4, 4) << 6) | (IMM(imm, 6, 6) << 5) | (IMM(imm, 8, 7) << 3) | (IMM(imm, 5, 5) << 2)) -#define C_SUB(rd, rs) MAKE_CODE16(inst, code, 0x8c01 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) -#define C_SUBW(rd, rs) MAKE_CODE16(inst, code, 0x9c01 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) -#define C_AND(rd, rs) MAKE_CODE16(inst, code, 0x8c61 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) -#define C_ANDI(rd, imm) MAKE_CODE16(inst, code, 0x8801 | (IMM(imm, 5, 5) << 12) | (to_rvc_reg(rd) << 7) | (IMM(imm, 4, 0) << 2)) -#define C_OR(rd, rs) MAKE_CODE16(inst, code, 0x8c41 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) -#define C_XOR(rd, rs) MAKE_CODE16(inst, code, 0x8c21 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) -#define C_SLLI(rd, imm) MAKE_CODE16(inst, code, 0x0002 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 0) << 2)) -#define C_SRLI(rd, imm) MAKE_CODE16(inst, code, 0x8001 | (IMM(imm, 5, 5) << 12) | (to_rvc_reg(rd) << 7) | (IMM(imm, 4, 0) << 2)) -#define C_SRAI(rd, imm) MAKE_CODE16(inst, code, 0x8401 | (IMM(imm, 5, 5) << 12) | (to_rvc_reg(rd) << 7) | (IMM(imm, 4, 0) << 2)) -#define C_LW(rd, imm, rs) MAKE_CODE16(inst, code, 0x4000 | (IMM(imm, 5, 3) << 10) | (to_rvc_reg(rs) << 7) | (IMM(imm, 2, 2) << 6) | (IMM(imm, 6, 6) << 5) | (to_rvc_reg(rd) << 2)) -#define C_LD(rd, imm, rs) MAKE_CODE16(inst, code, 0x6000 | (IMM(imm, 5, 3) << 10) | (to_rvc_reg(rs) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_reg(rd) << 2)) -#define C_SW(rs2, imm, rs1) MAKE_CODE16(inst, code, 0xc000 | (IMM(imm, 5, 3) << 10) | (to_rvc_reg(rs1) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_reg(rs2) << 2)) -#define C_SD(rs2, imm, rs1) MAKE_CODE16(inst, code, 0xe000 | (IMM(imm, 5, 3) << 10) | (to_rvc_reg(rs1) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_reg(rs2) << 2)) -#define C_LDSP(rd, imm) MAKE_CODE16(inst, code, 0x6002 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 3) << 5) | (IMM(imm, 8, 6) << 2)) -#define C_SDSP(rs, imm) MAKE_CODE16(inst, code, 0xe002 | (IMM(imm, 5, 3) << 10) | (IMM(imm, 8, 6) << 7) | ((rs) << 2)) -#define C_J() MAKE_CODE16(inst, code, 0xa001) -#define C_JR(rs) MAKE_CODE16(inst, code, 0x8002 | ((rs) << 7)) -#define C_JALR(rs) MAKE_CODE16(inst, code, 0x9002 | ((rs) << 7)) -#define C_BEQZ(rs) MAKE_CODE16(inst, code, 0xc001 | (to_rvc_reg(rs) << 7)) -#define C_BNEZ(rs) MAKE_CODE16(inst, code, 0xe001 | (to_rvc_reg(rs) << 7)) - -#define C_FLD(rd, imm, rs) MAKE_CODE16(inst, code, 0x2000 | (IMM(imm, 5, 3) << 10) | (to_rvc_freg(rs) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_freg(rd) << 2)) -#define C_FSD(rs2, imm, rs1) MAKE_CODE16(inst, code, 0xa000 | (IMM(imm, 5, 3) << 10) | (to_rvc_freg(rs1) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_freg(rs2) << 2)) -#define C_FLDSP(rd, imm) MAKE_CODE16(inst, code, 0x2002 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 3) << 5) | (IMM(imm, 8, 6) << 2)) -#define C_FSDSP(rs, imm) MAKE_CODE16(inst, code, 0xa002 | (IMM(imm, 5, 3) << 10) | (IMM(imm, 8, 6) << 7) | ((rs) << 2)) - -#define P_RET() C_JR(RA) -#define P_LI(rd, imm) W_ADDI(rd, ZERO, imm) -#define P_NEG(rd, rs) W_SUB(rd, ZERO, rs) -#define P_NOT(rd, rs) W_XORI(rd, rs, -1) -#define P_SEXT_B(rd, rs) do { if ((rd) == (rs) && (rs) != 0) C_SLLI(rd, 56); else W_SLLI(rd, rs, 56); C_SRAI(rd, 56); } while (0) -#define P_SEXT_H(rd, rs) do { if ((rd) == (rs) && (rs) != 0) C_SLLI(rd, 48); else W_SLLI(rd, rs, 48); C_SRAI(rd, 48); } while (0) -#define P_SEXT_W(rd, rs) do { if ((rd) == (rs)) C_ADDIW(rd, 0); else W_ADDIW(rd, rs, 0); } while (0) -#define P_ZEXT_B(rd, rs) W_ANDI(rd, rs, 0xff) -#define P_ZEXT_H(rd, rs) do { if ((rd) == (rs) && (rs) != 0) C_SLLI(rd, 48); else W_SLLI(rd, rs, 48); C_SRLI(rd, 48); } while (0) -#define P_ZEXT_W(rd, rs) do { if ((rd) == (rs) && (rs) != 0) C_SLLI(rd, 32); else W_SLLI(rd, rs, 32); C_SRLI(rd, 32); } while (0) -#define P_SEQZ(rd, rs) W_SLTIU(rd, rs, 1) -#define P_SNEZ(rd, rs) W_SLTU(rd, ZERO, rs) -#define P_SLTZ(rd, rs) W_SLT(rd, rs, ZERO) -#define P_SGTZ(rd, rs) W_SLT(rd, ZERO, rs) - -#define P_FMV_D(rd, rs) W_FSGNJ_D(rd, rs, rs) -#define P_FMV_S(rd, rs) W_FSGNJ_S(rd, rs, rs) -#define P_FNEG_D(rd, rs) W_FSGNJN_D(rd, rs, rs) -#define P_FNEG_S(rd, rs) W_FSGNJN_S(rd, rs, rs) - extern inline bool is_rvc_reg(int reg); extern inline int to_rvc_reg(int reg); diff --git a/src/as/arch/riscv64/inst.h b/src/as/arch/riscv64/inst.h index dd6b11a72..70c1ac1f8 100644 --- a/src/as/arch/riscv64/inst.h +++ b/src/as/arch/riscv64/inst.h @@ -114,8 +114,3 @@ typedef struct Inst { Operand opr2; Operand opr3; } Inst; - -inline bool is_rvc_reg(int reg) { return reg >= 8 && reg <= 15; } // X8~X15 -inline int to_rvc_reg(int reg) { return reg - 8; } -#define is_rvc_freg is_rvc_reg -#define to_rvc_freg to_rvc_reg diff --git a/src/as/arch/riscv64/ir_asm.c b/src/as/arch/riscv64/ir_asm.c index f8795234e..2a9437e7a 100644 --- a/src/as/arch/riscv64/ir_asm.c +++ b/src/as/arch/riscv64/ir_asm.c @@ -7,6 +7,7 @@ #include "gen_section.h" #include "inst.h" #include "parse_asm.h" +#include "riscv64_code.h" #include "table.h" #include "util.h" @@ -153,16 +154,6 @@ bool calc_label_address(uintptr_t start_address, Vector **section_irs, Table *la return settle; } -#ifndef MAKE_CODE32 -#define MAKE_CODE32(inst, code, ...) do { unsigned int buf[] = {__VA_ARGS__}; make_code32(inst, code, buf, sizeof(buf)); } while (0) -#endif -void make_code32(Inst *inst, Code *code, unsigned int *buf, int len); - -#define ZERO 0 -#define IMM(imm, t, b) (((imm) >> (b)) & ((1 << (t - b + 1)) - 1)) -#define UTYPE(imm, rd, opcode) MAKE_CODE32(inst, code, (IMM(imm, 31, 12) << 12) | ((rd) << 7) | (opcode)) // U-type -#define W_JAL(rd, imm) UTYPE(imm, rd, 0x6f) - static bool make_jmp_long(IR *ir) { if (ir->code.flag & INST_LONG_OFFSET) return false; diff --git a/src/as/arch/riscv64/riscv64_code.h b/src/as/arch/riscv64/riscv64_code.h new file mode 100644 index 000000000..eccc3ed04 --- /dev/null +++ b/src/as/arch/riscv64/riscv64_code.h @@ -0,0 +1,176 @@ +// riscv64 Code macros + +#pragma once + +#define ZERO 0 +#define RA 1 +#define SP 2 + +#define IMM(imm, t, b) (((imm) >> (b)) & ((1 << (t - b + 1)) - 1)) + +// Instruction formats: 32bit=[7|5|5|3|5|7] +#define RTYPE(funct7, rs2, rs1, funct3, rd, opcode) MAKE_CODE32(inst, code, ((funct7) << 25) | ((rs2) << 20) | ((rs1) << 15) | ((funct3) << 12) | ((rd) << 7) | (opcode)) +#define ITYPE(imm, rs1, funct3, rd, opcode) MAKE_CODE32(inst, code, (IMM(imm, 11, 0) << 20) | ((rs1) << 15) | ((funct3) << 12) | ((rd) << 7) | (opcode)) +#define STYPE(imm, rs2, rs1, funct3, opcode) MAKE_CODE32(inst, code, (IMM(imm, 11, 5) << 25) | ((rs2) << 20) | ((rs1) << 15) | ((funct3) << 12) | (IMM(imm, 4, 0) << 7) | (opcode)) +#define BTYPE(imm, rs2, rs1, funct3, opcode) MAKE_CODE32(inst, code, (IMM(imm, 12, 12) << 31) | (IMM(imm, 10, 5) << 25) | ((rs2) << 20) | ((rs1) << 15) | ((funct3) << 12) | (IMM(imm, 4, 0) << 7) | (opcode)) +#define UTYPE(imm, rd, opcode) MAKE_CODE32(inst, code, (IMM(imm, 31, 12) << 12) | ((rd) << 7) | (opcode)) +#define JTYPE(imm, rd, opcode) MAKE_CODE32(inst, code, (IMM(imm, 20, 20) << 31) | (IMM(imm, 10, 1) << 20) | (IMM(imm, 11, 11) << 19) | (IMM(imm, 19, 12) << 12) | ((rd) << 7) | (opcode)) + +// 32-bit instructions +#define W_ADD(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x00, rd, 0x33) +#define W_ADDW(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x00, rd, 0x3b) +#define W_ADDI(rd, rs, imm) ITYPE(imm, rs, 0x00, rd, 0x13) +#define W_ADDIW(rd, rs, imm) ITYPE(imm, rs, 0x00, rd, 0x1b) +#define W_SUB(rd, rs1, rs2) RTYPE(0x20, rs2, rs1, 0x00, rd, 0x33) +#define W_SUBW(rd, rs1, rs2) RTYPE(0x20, rs2, rs1, 0x00, rd, 0x3b) +#define W_MUL(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x00, rd, 0x33) +#define W_MULW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x00, rd, 0x3b) +#define W_DIV(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x04, rd, 0x33) +#define W_DIVU(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x05, rd, 0x33) +#define W_DIVW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x04, rd, 0x3b) +#define W_DIVUW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x05, rd, 0x3b) +#define W_REM(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x06, rd, 0x33) +#define W_REMU(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x07, rd, 0x33) +#define W_REMW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x06, rd, 0x3b) +#define W_REMUW(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x07, rd, 0x3b) +#define W_AND(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x07, rd, 0x33) +#define W_ANDI(rd, rs, imm) ITYPE(imm, rs, 0x07, rd, 0x13) +#define W_OR(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x06, rd, 0x33) +#define W_ORI(rd, rs, imm) ITYPE(imm, rs, 0x06, rd, 0x13) +#define W_XOR(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x04, rd, 0x33) +#define W_XORI(rd, rs, imm) ITYPE(imm, rs, 0x04, rd, 0x13) +#define W_SLL(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x01, rd, 0x33) +#define W_SLLI(rd, rs, imm) ITYPE((imm) & 63, rs, 0x01, rd, 0x13) +#define W_SLLIW(rd, rs, imm) ITYPE((imm) & 31, rs, 0x01, rd, 0x1b) +#define W_SRL(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x05, rd, 0x33) +#define W_SRLI(rd, rs, imm) ITYPE((imm) & 63, rs, 0x05, rd, 0x13) +#define W_SRA(rd, rs1, rs2) RTYPE(0x20, rs2, rs1, 0x05, rd, 0x33) +#define W_SRAI(rd, rs, imm) ITYPE(0x400 | ((imm) & 63), rs, 0x05, rd, 0x13) +#define W_SLT(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x02, rd, 0x33) +#define W_SLTU(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x03, rd, 0x33) +#define W_SLTI(rd, rs, imm) ITYPE(imm, rs, 0x02, rd, 0x13) +#define W_SLTIU(rd, rs, imm) ITYPE(imm, rs, 0x03, rd, 0x13) +#define W_LB(rd, ofs, rs) ITYPE(ofs, rs, 0x00, rd, 0x03) +#define W_LH(rd, ofs, rs) ITYPE(ofs, rs, 0x01, rd, 0x03) +#define W_LW(rd, ofs, rs) ITYPE(ofs, rs, 0x02, rd, 0x03) +#define W_LD(rd, ofs, rs) ITYPE(ofs, rs, 0x03, rd, 0x03) +#define W_LBU(rd, ofs, rs) ITYPE(ofs, rs, 0x04, rd, 0x03) +#define W_LHU(rd, ofs, rs) ITYPE(ofs, rs, 0x05, rd, 0x03) +#define W_LWU(rd, ofs, rs) ITYPE(ofs, rs, 0x06, rd, 0x03) +#define W_SB(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x00, 0x23) +#define W_SH(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x01, 0x23) +#define W_SW(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x02, 0x23) +#define W_SD(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x03, 0x23) +#define W_LUI(rd, imm) UTYPE(imm, rd, 0x37) +#define W_AUIPC(rd, imm) UTYPE(imm, rd, 0x17) +#define W_JAL(rd, imm) UTYPE(imm, rd, 0x6f) +#define W_JALR(rd, rs, imm) ITYPE(imm, rs, 0x00, rd, 0x67) +#define W_BXX(xx, rs1, rs2, ofs) STYPE(ofs, rs2, rs1, xx, 0x63) + +#define W_FADD_D(rd, rs1, rs2) RTYPE(0x01, rs2, rs1, 0x07, rd, 0x53) +#define W_FSUB_D(rd, rs1, rs2) RTYPE(0x05, rs2, rs1, 0x07, rd, 0x53) +#define W_FMUL_D(rd, rs1, rs2) RTYPE(0x09, rs2, rs1, 0x07, rd, 0x53) +#define W_FDIV_D(rd, rs1, rs2) RTYPE(0x0d, rs2, rs1, 0x07, rd, 0x53) +#define W_FADD_S(rd, rs1, rs2) RTYPE(0x00, rs2, rs1, 0x07, rd, 0x53) +#define W_FSUB_S(rd, rs1, rs2) RTYPE(0x04, rs2, rs1, 0x07, rd, 0x53) +#define W_FMUL_S(rd, rs1, rs2) RTYPE(0x08, rs2, rs1, 0x07, rd, 0x53) +#define W_FDIV_S(rd, rs1, rs2) RTYPE(0x0c, rs2, rs1, 0x07, rd, 0x53) +#define W_FEQ_D(rd, rs1, rs2) RTYPE(0x51, rs2, rs1, 0x02, rd, 0x53) +#define W_FLT_D(rd, rs1, rs2) RTYPE(0x51, rs2, rs1, 0x01, rd, 0x53) +#define W_FLE_D(rd, rs1, rs2) RTYPE(0x51, rs2, rs1, 0x00, rd, 0x53) +#define W_FEQ_S(rd, rs1, rs2) RTYPE(0x50, rs2, rs1, 0x02, rd, 0x53) +#define W_FLT_S(rd, rs1, rs2) RTYPE(0x50, rs2, rs1, 0x01, rd, 0x53) +#define W_FLE_S(rd, rs1, rs2) RTYPE(0x50, rs2, rs1, 0x00, rd, 0x53) +#define W_FLD(rd, ofs, rs) ITYPE(ofs, rs, 0x03, rd, 0x07) +#define W_FLW(rd, ofs, rs) ITYPE(ofs, rs, 0x02, rd, 0x07) +#define W_FSD(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x03, 0x27) +#define W_FSW(rs2, ofs, rs1) STYPE(ofs, rs2, rs1, 0x02, 0x27) +#define W_FSGNJ_D(rd, rs1, rs2) RTYPE(0x11, rs2, rs1, 0x00, rd, 0x53) +#define W_FSGNJ_S(rd, rs1, rs2) RTYPE(0x10, rs2, rs1, 0x00, rd, 0x53) +#define W_FSGNJN_D(rd, rs1, rs2) RTYPE(0x11, rs2, rs1, 0x01, rd, 0x53) +#define W_FSGNJN_S(rd, rs1, rs2) RTYPE(0x10, rs2, rs1, 0x01, rd, 0x53) + +#define W_FCVT_D_W(rd, rs) RTYPE(0x69, 0, rs, 0x00, rd, 0x53) +#define W_FCVT_D_WU(rd, rs) RTYPE(0x69, 1, rs, 0x00, rd, 0x53) +#define W_FCVT_D_L(rd, rs) RTYPE(0x69, 2, rs, 0x07, rd, 0x53) +#define W_FCVT_D_LU(rd, rs) RTYPE(0x69, 3, rs, 0x07, rd, 0x53) +#define W_FCVT_S_W(rd, rs) RTYPE(0x68, 0, rs, 0x07, rd, 0x53) +#define W_FCVT_S_WU(rd, rs) RTYPE(0x68, 1, rs, 0x07, rd, 0x53) +#define W_FCVT_S_L(rd, rs) RTYPE(0x68, 2, rs, 0x07, rd, 0x53) +#define W_FCVT_S_LU(rd, rs) RTYPE(0x68, 3, rs, 0x07, rd, 0x53) + +#define W_FCVT_W_D(rd, rs, rm) RTYPE(0x61, 0, rs, rm, rd, 0x53) +#define W_FCVT_WU_D(rd, rs, rm) RTYPE(0x61, 1, rs, rm, rd, 0x53) +#define W_FCVT_L_D(rd, rs, rm) RTYPE(0x61, 2, rs, rm, rd, 0x53) +#define W_FCVT_LU_D(rd, rs, rm) RTYPE(0x61, 3, rs, rm, rd, 0x53) +#define W_FCVT_W_S(rd, rs, rm) RTYPE(0x60, 0, rs, rm, rd, 0x53) +#define W_FCVT_WU_S(rd, rs, rm) RTYPE(0x60, 1, rs, rm, rd, 0x53) +#define W_FCVT_L_S(rd, rs, rm) RTYPE(0x60, 2, rs, rm, rd, 0x53) +#define W_FCVT_LU_S(rd, rs, rm) RTYPE(0x60, 3, rs, rm, rd, 0x53) + +#define W_FCVT_D_S(rd, rs) RTYPE(0x21, 0, rs, 0x00, rd, 0x53) +#define W_FCVT_S_D(rd, rs) RTYPE(0x20, 1, rs, 0x07, rd, 0x53) + +#define W_FMV_X_D(rd, rs) RTYPE(0x71, 0, rs, 0x00, rd, 0x53) +#define W_FMV_X_W(rd, rs) RTYPE(0x70, 0, rs, 0x00, rd, 0x53) + +// Compressed instructions +#define C_MV(rd, rs) MAKE_CODE16(inst, code, 0x8002 | ((rd) << 7) | ((rs) << 2)) +#define C_LI(rd, imm) MAKE_CODE16(inst, code, 0x4001 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 0) << 2)) +#define C_LUI(rd, imm) MAKE_CODE16(inst, code, 0x6001 | (IMM(imm, 17, 17) << 12) | ((rd) << 7) | (IMM(imm, 16, 12) << 2)) +#define C_ADD(rd, rs) MAKE_CODE16(inst, code, 0x9002 | ((rd) << 7) | ((rs) << 2)) +#define C_ADDW(rd, rs) MAKE_CODE16(inst, code, 0x9c21 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) +#define C_ADDI(rd, imm) MAKE_CODE16(inst, code, 0x0001 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 0) << 2)) +#define C_ADDIW(rd, imm) MAKE_CODE16(inst, code, 0x2001 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 0) << 2)) +#define C_ADDI16SP(imm) MAKE_CODE16(inst, code, 0x6101 | (IMM(imm, 9, 9) << 12) | (IMM(imm, 4, 4) << 6) | (IMM(imm, 6, 6) << 5) | (IMM(imm, 8, 7) << 3) | (IMM(imm, 5, 5) << 2)) +#define C_SUB(rd, rs) MAKE_CODE16(inst, code, 0x8c01 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) +#define C_SUBW(rd, rs) MAKE_CODE16(inst, code, 0x9c01 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) +#define C_AND(rd, rs) MAKE_CODE16(inst, code, 0x8c61 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) +#define C_ANDI(rd, imm) MAKE_CODE16(inst, code, 0x8801 | (IMM(imm, 5, 5) << 12) | (to_rvc_reg(rd) << 7) | (IMM(imm, 4, 0) << 2)) +#define C_OR(rd, rs) MAKE_CODE16(inst, code, 0x8c41 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) +#define C_XOR(rd, rs) MAKE_CODE16(inst, code, 0x8c21 | (to_rvc_reg(rd) << 7) | (to_rvc_reg(rs) << 2)) +#define C_SLLI(rd, imm) MAKE_CODE16(inst, code, 0x0002 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 0) << 2)) +#define C_SRLI(rd, imm) MAKE_CODE16(inst, code, 0x8001 | (IMM(imm, 5, 5) << 12) | (to_rvc_reg(rd) << 7) | (IMM(imm, 4, 0) << 2)) +#define C_SRAI(rd, imm) MAKE_CODE16(inst, code, 0x8401 | (IMM(imm, 5, 5) << 12) | (to_rvc_reg(rd) << 7) | (IMM(imm, 4, 0) << 2)) +#define C_LW(rd, imm, rs) MAKE_CODE16(inst, code, 0x4000 | (IMM(imm, 5, 3) << 10) | (to_rvc_reg(rs) << 7) | (IMM(imm, 2, 2) << 6) | (IMM(imm, 6, 6) << 5) | (to_rvc_reg(rd) << 2)) +#define C_LD(rd, imm, rs) MAKE_CODE16(inst, code, 0x6000 | (IMM(imm, 5, 3) << 10) | (to_rvc_reg(rs) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_reg(rd) << 2)) +#define C_SW(rs2, imm, rs1) MAKE_CODE16(inst, code, 0xc000 | (IMM(imm, 5, 3) << 10) | (to_rvc_reg(rs1) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_reg(rs2) << 2)) +#define C_SD(rs2, imm, rs1) MAKE_CODE16(inst, code, 0xe000 | (IMM(imm, 5, 3) << 10) | (to_rvc_reg(rs1) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_reg(rs2) << 2)) +#define C_LDSP(rd, imm) MAKE_CODE16(inst, code, 0x6002 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 3) << 5) | (IMM(imm, 8, 6) << 2)) +#define C_SDSP(rs, imm) MAKE_CODE16(inst, code, 0xe002 | (IMM(imm, 5, 3) << 10) | (IMM(imm, 8, 6) << 7) | ((rs) << 2)) +#define C_J() MAKE_CODE16(inst, code, 0xa001) +#define C_JR(rs) MAKE_CODE16(inst, code, 0x8002 | ((rs) << 7)) +#define C_JALR(rs) MAKE_CODE16(inst, code, 0x9002 | ((rs) << 7)) +#define C_BEQZ(rs) MAKE_CODE16(inst, code, 0xc001 | (to_rvc_reg(rs) << 7)) +#define C_BNEZ(rs) MAKE_CODE16(inst, code, 0xe001 | (to_rvc_reg(rs) << 7)) + +#define C_FLD(rd, imm, rs) MAKE_CODE16(inst, code, 0x2000 | (IMM(imm, 5, 3) << 10) | (to_rvc_freg(rs) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_freg(rd) << 2)) +#define C_FSD(rs2, imm, rs1) MAKE_CODE16(inst, code, 0xa000 | (IMM(imm, 5, 3) << 10) | (to_rvc_freg(rs1) << 7) | (IMM(imm, 7, 6) << 5) | (to_rvc_freg(rs2) << 2)) +#define C_FLDSP(rd, imm) MAKE_CODE16(inst, code, 0x2002 | (IMM(imm, 5, 5) << 12) | ((rd) << 7) | (IMM(imm, 4, 3) << 5) | (IMM(imm, 8, 6) << 2)) +#define C_FSDSP(rs, imm) MAKE_CODE16(inst, code, 0xa002 | (IMM(imm, 5, 3) << 10) | (IMM(imm, 8, 6) << 7) | ((rs) << 2)) + +// Pseudo instructions +#define P_RET() C_JR(RA) +#define P_LI(rd, imm) W_ADDI(rd, ZERO, imm) +#define P_NEG(rd, rs) W_SUB(rd, ZERO, rs) +#define P_NOT(rd, rs) W_XORI(rd, rs, -1) +#define P_SEXT_B(rd, rs) do { if ((rd) == (rs) && (rs) != 0) C_SLLI(rd, 56); else W_SLLI(rd, rs, 56); C_SRAI(rd, 56); } while (0) +#define P_SEXT_H(rd, rs) do { if ((rd) == (rs) && (rs) != 0) C_SLLI(rd, 48); else W_SLLI(rd, rs, 48); C_SRAI(rd, 48); } while (0) +#define P_SEXT_W(rd, rs) do { if ((rd) == (rs)) C_ADDIW(rd, 0); else W_ADDIW(rd, rs, 0); } while (0) +#define P_ZEXT_B(rd, rs) W_ANDI(rd, rs, 0xff) +#define P_ZEXT_H(rd, rs) do { if ((rd) == (rs) && (rs) != 0) C_SLLI(rd, 48); else W_SLLI(rd, rs, 48); C_SRLI(rd, 48); } while (0) +#define P_ZEXT_W(rd, rs) do { if ((rd) == (rs) && (rs) != 0) C_SLLI(rd, 32); else W_SLLI(rd, rs, 32); C_SRLI(rd, 32); } while (0) +#define P_SEQZ(rd, rs) W_SLTIU(rd, rs, 1) +#define P_SNEZ(rd, rs) W_SLTU(rd, ZERO, rs) +#define P_SLTZ(rd, rs) W_SLT(rd, rs, ZERO) +#define P_SGTZ(rd, rs) W_SLT(rd, ZERO, rs) + +#define P_FMV_D(rd, rs) W_FSGNJ_D(rd, rs, rs) +#define P_FMV_S(rd, rs) W_FSGNJ_S(rd, rs, rs) +#define P_FNEG_D(rd, rs) W_FSGNJN_D(rd, rs, rs) +#define P_FNEG_S(rd, rs) W_FSGNJN_S(rd, rs, rs) + +inline bool is_rvc_reg(int reg) { return reg >= 8 && reg <= 15; } // X8~X15 +inline int to_rvc_reg(int reg) { return reg - 8; } +#define is_rvc_freg is_rvc_reg +#define to_rvc_freg to_rvc_reg diff --git a/src/as/asm_code.h b/src/as/asm_code.h index b036a1bfe..32c117d7c 100644 --- a/src/as/asm_code.h +++ b/src/as/asm_code.h @@ -26,9 +26,19 @@ void assemble_inst(Inst *inst, const ParseInfo *info, Code *code); #define MAKE_CODE(inst, code, ...) do { unsigned char buf[] = {__VA_ARGS__}; make_code(inst, code, buf, sizeof(buf)); } while (0) #endif +#ifndef MAKE_CODE16 +#define MAKE_CODE16(inst, code, ...) do { unsigned short buf[] = {__VA_ARGS__}; make_code16(inst, code, buf, sizeof(buf)); } while (0) +#endif + +#ifndef MAKE_CODE32 +#define MAKE_CODE32(inst, code, ...) do { unsigned int buf[] = {__VA_ARGS__}; make_code32(inst, code, buf, sizeof(buf)); } while (0) +#endif + #define IM8(x) (x) #define IM16(x) (x), ((x) >> 8) #define IM32(x) (x), ((x) >> 8), ((x) >> 16), ((x) >> 24) #define IM64(x) (x), ((x) >> 8), ((x) >> 16), ((x) >> 24), ((x) >> 32), ((x) >> 40), ((x) >> 48), ((x) >> 56) void make_code(Inst *inst, Code *code, unsigned char *buf, int len); +void make_code16(Inst *inst, Code *code, unsigned short *buf, int len); +void make_code32(Inst *inst, Code *code, unsigned int *buf, int len);