Open l3773l opened 3 months ago
enum RiscVInst {
BEGIN_RV64IM,
MV,
NOP,
// 64:
NEG,
ADD,
ADDI,
SUB,
MUL,
DIV,
REM,
// 32:
NEGW,
// BITWISE 按位逻辑运算
AND,
ANDI,
XOR,
XORI,
NOT,
OR,
ORI,
// SHIFT 移位指令
// S{L/R}{L/A} 第一个 {L/R} 表示左右,第个 {L/A}
// (LOGICAL/ARITHMETIC)表示逻辑和算数(算数保持符号) 没有 SLA 是因为它和
// SLL 是等价的
SLL,
SLLI,
SRL,
SRLI,
SRA,
SRAI,
// BRANCH
BEQ,
// BGE,
// BGT,
// BLE,
// BLT,
BNE,
// CMP
// 无符号比较跟有符号一样
// 没有 SEQ, 它等价于 XOR A, A, B; SEQZ DST, A
SLT,
SLTI,
// 处理 PC 高位偏移
/**
* 在 RISC-V 里,由于指令长度的问题(64
* 位指令可能存有多个参数/立即数,指令中提供给立即数的长度有限),偏移有时无法完全加载(比如
* 63 位长的偏移),这时要分为高位和低位分开加载。 比如 JALR
* DST,OFFSET(SRC) OFFSET 只能是 12 位立即数
* 在加载地址类偏移时,理想的状况是 DST = PC + OFFSET 得到偏移后的地址
* 加载高位和低位情况时 DST = PC + OFFSETHI + OFFSETLO (OFFSET = OFFSETHI +
* OFFSETLO) 可以使用 DST1 = PC + OFFSETHI; JALR DST, OFFSETLO(DST1) 来解决
* 但是由于 RISC-V 的设计,你不能直接访问 PC
* 那么(PC + OFFSETHI)部分就产生了一个指令 AUIPC(ADD UI TO PC)
* AUIPC RD, OFFSET <=> RD = PC + (OFFSET << 12)
*/
AUIPC,
// JUMP
// L 指 LINK(把下一条指令的地址加载到寄存器里用做返回地址),R 指寄存器跳转
// JAL,
// JALR,
J,
// JR,
// 函数调用/返回
CALL,
TAIL,
RET,
// LOAD & STORE
// LA 和 LLA 都是加载符号地址,LLA RD, SYMBOL <=> RD = &SYMBOL
// 特别地 当编译位置无关代码时,LA 会去加载 GOT(全局偏移表中的地址),而
// LLA 始终如上(LLA 的第二个 L 指 LOCAL)。 (PIC)LA RD, SYMBOL <=> RD =
// GOT[PC + SYMBOL_GOT_OFFSET] (NON-PIC) 非 PIC 时 LA 和 LLA 一样。
LA,
// LLA,
// 加载,没有 U 则符号扩展,32/64 位没有 LWU/LDU 因为 LW/LD
// 在对应位架构直接一整个全加载了
LW,
SW,
// 加载立即数
// 对 LI,汇编器会根据 立即数的大小 自动生成对应加载指令
LI,
LUI,
// SYSTEM CALL
// ECALL, // 环境调用异常
// EBREAK, // 调试器断点异常
END_RV64IM,
BEGIN_RV64FD,
// FLOAT
FNEG_S,
FADD_S,
FSUB_S,
FMUL_S,
FDIV_S,
// 浮点转换 S 单精度 D 双精度 W 字 L 64 位整数(指 LP64 LONG)
FCVT_S_W,
FCVT_W_S,
// LOAD & STORE
FLW,
FSW,
// CMP
FEQ_S,
FLE_S,
FLT_S,
// FLOAT MV, X 指整数寄存器
FMV_S,
FMV_W_X,
FMV_X_W,
END_RV64FD,
};
// i 指 整数寄存器
// f 值 浮点数寄存器
// 12-bits im/20-bits im 指 12/20 位长的(有符号/无符号)立即数
// symbol 指汇编中类似 .main(函数符号) .L1(跳转地址符号),可能有替换的需求(变量)
#define DECL(...)
// i32
// i -> i
#define DECL1(name)
DECL1(NEG)
DECL1(NEGW)
DECL1(NOT)
// (i, i) -> i
#define DECLR(name)
DECLR(ADD)
DECLR(SUB)
DECLR(MUL)
DECLR(DIV)
DECLR(REM)
DECLR(AND)
DECLR(XOR)
DECLR(OR)
DECLR(SLL)
DECLR(SRL)
DECLR(SRA)
DECLR(SLT)
// (i, 12bits signed imm) -> i
#define DECLI(name)
DECLI(ADDI)
DECLI(ANDI)
DECLI(XORI)
DECLI(ORI)
DECLI(SLLI)
DECLI(SRLI)
DECLI(SRAI)
DECLI(SLTI)
// (i, symbol) -> void
#define DECLB(name)
DECLB(BEQ)
DECLB(BNE)
// 不定型的指令
DECL(i, AUIPC, 20-bits im)
DECL(void, J, symbol)
DECL(void, CALL, symbol)
DECL(void, TAIL, symbol)
DECL(void, RET)
DECL(i, LA, symbol)
// lw rd, offset(rs)
DECL(i, LW, 12-bits im, i)
// sw rs2, offset(rs1)
DECL(void, SW, i, 12-bits im, i)
DECL(i, LI, 12-bits im)
DECL(i, LUI, 20-bits im)
// float
// f -> f
#define DECL1F(name)
DECL1F(FNEG_S)
// (f, f) -> f
#define DECLRF(name)
DECLRF(FADD_S)
DECLRF(FSUB_S)
DECLRF(FMUL_S)
DECLRF(FDIV_S)
// 浮点转换 S 单精度 D 双精度 W 字 L 64 位整数(指 LP64 LONG)
DECL(i, FCVT_S_W, f)
DECL(f, FCVT_W_S, i)
// LOAD & STORE
DECL(f, FLW, 12-bits im, i)
DECL(void, FSW, f, 12-bits im, i)
// CMP
DECL(i, FEQ_S, f, f)
DECL(i, FLE_S, f, f)
DECL(i, FLT_S, f, f)
// FLOAT MV, X 指整数寄存器
DECL(f, FMV_S, f)
DECL(i, FMV_W_X, f)
DECL(f, FMV_X_W, i)
// END_RV64FD,
IR 和 MIR:一些需求
* [x] IR 的 Inst 加入 RISCVInst * [x] var_symbol 加入 x0~x31 和 f0~f31 寄存器(有可能不满足 SSA 性质)
未测试版本 509ab59423bdea887968cd8bccab9f1969f8ee22 已完成。
TASK
架构
中端 IR