1use crate::isa::data::Fin;
2use crate::isa::rv32::RV32Instr;
3use crate::isa::rv64::RV64Instr;
4use crate::isa::typed::{AQ, Instr, Rd, Reg, RL, RoundingMode, Rs1, Rs2, Rs3};
5use crate::isa::typed::Reg::{F, FCSR, PC, X, ZERO};
6
7pub trait Encode32 {
8 fn encode32(self) -> u32;
9}
10
11impl Encode32 for Instr {
12 fn encode32(self) -> u32 {
13 match self {
14 Instr::RV32(i) => i.encode32(),
15 Instr::RV64(i) => i.encode32(),
16 Instr::NOP => panic!("No nop instruction in 32-bit length encoding"),
17 }
18 }
19}
20
21impl Encode32 for RV32Instr {
22 fn encode32(self) -> u32 {
23 match self {
24 RV32Instr::LUI(rd, imm) => emit_u(0b0110111, rd, imm.decode()),
26 RV32Instr::AUIPC(rd, imm) => emit_u(0b0010111, rd, imm.decode()),
27 RV32Instr::JAL(rd, imm) => emit_j(0b1101111, rd, imm.decode_sext()),
28 RV32Instr::JALR(rd, rs1, imm) => emit_i(0b1100111, 0b000, rd, rs1, imm.decode_sext()),
29 RV32Instr::BEQ(rs1, rs2, imm) => emit_b(0b1100011, 0b000, rs1, rs2, imm.decode_sext()),
30 RV32Instr::BNE(rs1, rs2, imm) => emit_b(0b1100011, 0b001, rs1, rs2, imm.decode_sext()),
31 RV32Instr::BLT(rs1, rs2, imm) => emit_b(0b1100011, 0b100, rs1, rs2, imm.decode_sext()),
32 RV32Instr::BGE(rs1, rs2, imm) => emit_b(0b1100011, 0b101, rs1, rs2, imm.decode_sext()),
33 RV32Instr::BLTU(rs1, rs2, imm) => emit_b(0b1100011, 0b110, rs1, rs2, imm.decode_sext()),
34 RV32Instr::BGEU(rs1, rs2, imm) => emit_b(0b1100011, 0b111, rs1, rs2, imm.decode_sext()),
35 RV32Instr::LB(rd, rs1, imm) => emit_i(0b0000011, 0b000, rd, rs1, imm.decode_sext()),
36 RV32Instr::LH(rd, rs1, imm) => emit_i(0b0000011, 0b001, rd, rs1, imm.decode_sext()),
37 RV32Instr::LW(rd, rs1, imm) => emit_i(0b0000011, 0b010, rd, rs1, imm.decode_sext()),
38 RV32Instr::LBU(rd, rs1, imm) => emit_i(0b0000011, 0b100, rd, rs1, imm.decode_sext()),
39 RV32Instr::LHU(rd, rs1, imm) => emit_i(0b0000011, 0b101, rd, rs1, imm.decode_sext()),
40 RV32Instr::SB(rs1, rs2, imm) => emit_s(0b0100011, 0b000, rs1, rs2, imm.decode_sext()),
41 RV32Instr::SH(rs1, rs2, imm) => emit_s(0b0100011, 0b001, rs1, rs2, imm.decode_sext()),
42 RV32Instr::SW(rs1, rs2, imm) => emit_s(0b0100011, 0b010, rs1, rs2, imm.decode_sext()),
43 RV32Instr::ADDI(rd, rs1, imm) => emit_i(0b0010011, 0b000, rd, rs1, imm.decode_sext()),
44 RV32Instr::SLTI(rd, rs1, imm) => emit_i(0b0010011, 0b010, rd, rs1, imm.decode_sext()),
45 RV32Instr::SLTIU(rd, rs1, imm) => emit_i(0b0010011, 0b011, rd, rs1, imm.decode_sext()),
46 RV32Instr::XORI(rd, rs1, imm) => emit_i(0b0010011, 0b100, rd, rs1, imm.decode_sext()),
47 RV32Instr::ORI(rd, rs1, imm) => emit_i(0b0010011, 0b110, rd, rs1, imm.decode_sext()),
48 RV32Instr::ANDI(rd, rs1, imm) => emit_i(0b0010011, 0b111, rd, rs1, imm.decode_sext()),
49 RV32Instr::SLLI(rd, rs1, shamt5) => emit_r(0b0010011, 0b0000000, 0b001, rd, rs1, Rs2(X(Fin::new(shamt5.0 as u32)))),
50 RV32Instr::SRLI(rd, rs1, shamt5) => emit_r(0b0010011, 0b0000000, 0b101, rd, rs1, Rs2(X(Fin::new(shamt5.0 as u32)))),
51 RV32Instr::SRAI(rd, rs1, shamt5) => emit_r(0b0010011, 0b0100000, 0b101, rd, rs1, Rs2(X(Fin::new(shamt5.0 as u32)))),
52 RV32Instr::ADD(rd, rs1, rs2) => emit_r(0b0110011, 0b0000000, 0b000, rd, rs1, rs2),
53 RV32Instr::SUB(rd, rs1, rs2) => emit_r(0b0110011, 0b0100000, 0b000, rd, rs1, rs2),
54 RV32Instr::SLL(rd, rs1, rs2) => emit_r(0b0110011, 0b0000000, 0b001, rd, rs1, rs2),
55 RV32Instr::SLT(rd, rs1, rs2) => emit_r(0b0110011, 0b0000000, 0b010, rd, rs1, rs2),
56 RV32Instr::SLTU(rd, rs1, rs2) => emit_r(0b0110011, 0b0000000, 0b011, rd, rs1, rs2),
57 RV32Instr::XOR(rd, rs1, rs2) => emit_r(0b0110011, 0b0000000, 0b100, rd, rs1, rs2),
58 RV32Instr::SRL(rd, rs1, rs2) => emit_r(0b0110011, 0b0000000, 0b101, rd, rs1, rs2),
59 RV32Instr::SRA(rd, rs1, rs2) => emit_r(0b0110011, 0b0100000, 0b101, rd, rs1, rs2),
60 RV32Instr::OR(rd, rs1, rs2) => emit_r(0b0110011, 0b0000000, 0b110, rd, rs1, rs2),
61 RV32Instr::AND(rd, rs1, rs2) => emit_r(0b0110011, 0b0000000, 0b111, rd, rs1, rs2),
62 RV32Instr::FENCE(rd, rs1, succ, pred, fm) => {
63 0b0001111
65 | ((rd.encode32() & 0b11111) << 7)
66 | ((rs1.encode32() & 0b11111) << 15)
67 | ((succ.0 & 0b1111) << 20)
68 | ((pred.0 & 0b1111) << 24)
69 | ((fm.0 & 0b1111) << 28)
70 }
71 RV32Instr::FENCE_TSO => 0b1000_0011_0011_00000_000_00000_0001111,
72 RV32Instr::PAUSE => 0b0000_0001_0000_00000_000_00000_0001111,
73 RV32Instr::ECALL => 0b000000000000_00000_000_00000_1110011,
74 RV32Instr::EBREAK => 0b000000000001_00000_000_00000_1110011,
75 RV32Instr::MUL(rd, rs1, rs2) => emit_r(0b0110011, 0b0000001, 0b000, rd, rs1, rs2),
77 RV32Instr::MULH(rd, rs1, rs2) => emit_r(0b0110011, 0b0000001, 0b001, rd, rs1, rs2),
78 RV32Instr::MULHSU(rd, rs1, rs2) => emit_r(0b0110011, 0b0000001, 0b010, rd, rs1, rs2),
79 RV32Instr::MULHU(rd, rs1, rs2) => emit_r(0b0110011, 0b0000001, 0b011, rd, rs1, rs2),
80 RV32Instr::DIV(rd, rs1, rs2) => emit_r(0b0110011, 0b0000001, 0b100, rd, rs1, rs2),
81 RV32Instr::DIVU(rd, rs1, rs2) => emit_r(0b0110011, 0b0000001, 0b101, rd, rs1, rs2),
82 RV32Instr::REM(rd, rs1, rs2) => emit_r(0b0110011, 0b0000001, 0b110, rd, rs1, rs2),
83 RV32Instr::REMU(rd, rs1, rs2) => emit_r(0b0110011, 0b0000001, 0b111, rd, rs1, rs2),
84 RV32Instr::LR_W(rd, rs1, aq, rl) => emit_r_amo(0b0101111, 0b00010, 0b010, aq, rl, rd, rs1, Rs2(ZERO)),
86 RV32Instr::SC_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b00011, 0b010, aq, rl, rd, rs1, rs2),
87 RV32Instr::AMOSWAP_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b00001, 0b010, aq, rl, rd, rs1, rs2),
88 RV32Instr::AMOADD_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b00000, 0b010, aq, rl, rd, rs1, rs2),
89 RV32Instr::AMOXOR_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b00100, 0b010, aq, rl, rd, rs1, rs2),
90 RV32Instr::AMOAND_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b01100, 0b010, aq, rl, rd, rs1, rs2),
91 RV32Instr::AMOOR_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b01000, 0b010, aq, rl, rd, rs1, rs2),
92 RV32Instr::AMOMIN_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b10000, 0b010, aq, rl, rd, rs1, rs2),
93 RV32Instr::AMOMAX_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b10100, 0b010, aq, rl, rd, rs1, rs2),
94 RV32Instr::AMOMINU_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b11000, 0b010, aq, rl, rd, rs1, rs2),
95 RV32Instr::AMOMAXU_W(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b11100, 0b010, aq, rl, rd, rs1, rs2),
96 RV32Instr::FLW(rd, rs1, imm) => emit_i(0b0000111, 0b010, rd, rs1, imm.decode_sext()),
98 RV32Instr::FSW(rs1, rs2, imm) => emit_s(0b0100111, 0b010, rs1, rs2, imm.decode_sext()),
99 RV32Instr::FMADD_S(rd, rs1, rs2, rs3, rm) => emit_r4(0b1000011, 0b00, rm.encode32(), rd, rs1, rs2, rs3),
100 RV32Instr::FMSUB_S(rd, rs1, rs2, rs3, rm) => emit_r4(0b1000111, 0b00, rm.encode32(), rd, rs1, rs2, rs3),
101 RV32Instr::FNMSUB_S(rd, rs1, rs2, rs3, rm) => emit_r4(0b1001011, 0b00, rm.encode32(), rd, rs1, rs2, rs3),
102 RV32Instr::FNMADD_S(rd, rs1, rs2, rs3, rm) => emit_r4(0b1001111, 0b00, rm.encode32(), rd, rs1, rs2, rs3),
103 RV32Instr::FADD_S(rd, rs1, rs2, rm) => emit_r(0b1010011, 0b0000000, rm.encode32(), rd, rs1, rs2),
104 RV32Instr::FSUB_S(rd, rs1, rs2, rm) => emit_r(0b1010011, 0b0000100, rm.encode32(), rd, rs1, rs2),
105 RV32Instr::FMUL_S(rd, rs1, rs2, rm) => emit_r(0b1010011, 0b0001000, rm.encode32(), rd, rs1, rs2),
106 RV32Instr::FDIV_S(rd, rs1, rs2, rm) => emit_r(0b1010011, 0b0001100, rm.encode32(), rd, rs1, rs2),
107 RV32Instr::FSQRT_S(rd, rs1, rm) => emit_r(0b1010011, 0b0101100, rm.encode32(), rd, rs1, Rs2(ZERO)),
108 RV32Instr::FSGNJ_S(rd, rs1, rs2) => emit_r(0b1010011, 0b0010000, 0b000, rd, rs1, rs2),
109 RV32Instr::FSGNJN_S(rd, rs1, rs2) => emit_r(0b1010011, 0b0010000, 0b001, rd, rs1, rs2),
110 RV32Instr::FSGNJX_S(rd, rs1, rs2) => emit_r(0b1010011, 0b0010000, 0b010, rd, rs1, rs2),
111 RV32Instr::FMIN_S(rd, rs1, rs2) => emit_r(0b1010011, 0b0010100, 0b000, rd, rs1, rs2),
112 RV32Instr::FMAX_S(rd, rs1, rs2) => emit_r(0b1010011, 0b0010100, 0b001, rd, rs1, rs2),
113 RV32Instr::FCVT_W_S(rd, rs1, rm) => emit_r(0b1010011, 0b1100000, rm.encode32(), rd, rs1, Rs2(ZERO)),
114 RV32Instr::FCVT_WU_S(rd, rs1, rm) => emit_r(0b1010011, 0b1100000, rm.encode32(), rd, rs1, Rs2(X(Fin::new(1)))),
115 RV32Instr::FMV_X_W(rd, rs1) => emit_r(0b1010011, 0b1110000, 0b000, rd, rs1, Rs2(ZERO)),
116 RV32Instr::FEQ_S(rd, rs1, rs2) => emit_r(0b1010011, 0b1010000, 0b010, rd, rs1, rs2),
117 RV32Instr::FLT_S(rd, rs1, rs2) => emit_r(0b1010011, 0b1010000, 0b001, rd, rs1, rs2),
118 RV32Instr::FLE_S(rd, rs1, rs2) => emit_r(0b1010011, 0b1010000, 0b000, rd, rs1, rs2),
119 RV32Instr::FCLASS_S(rd, rs1) => emit_r(0b1010011, 0b1110000, 0b001, rd, rs1, Rs2(ZERO)),
120 RV32Instr::FCVT_S_W(rd, rs1, rm) => emit_r(0b1010011, 0b1101000, rm.encode32(), rd, rs1, Rs2(ZERO)),
121 RV32Instr::FCVT_S_WU(rd, rs1, rm) => emit_r(0b1010011, 0b1101000, rm.encode32(), rd, rs1, Rs2(X(Fin::new(1)))),
122 RV32Instr::FMV_W_X(rd, rs1) => emit_r(0b1010011, 0b1111000, 0b000, rd, rs1, Rs2(ZERO)),
123 RV32Instr::FLD(rd, rs1, imm) => emit_i(0b0000111, 0b011, rd, rs1, imm.decode_sext()),
125 RV32Instr::FSD(rs1, rs2, imm) => emit_s(0b0100111, 0b011, rs1, rs2, imm.decode_sext()),
126 RV32Instr::FMADD_D(rd, rs1, r2, rs3, rm) => emit_r4(0b1000011, 0b01, rm.encode32(), rd, rs1, r2, rs3),
127 RV32Instr::FMSUB_D(rd, rs1, r2, rs3, rm) => emit_r4(0b1000111, 0b01, rm.encode32(), rd, rs1, r2, rs3),
128 RV32Instr::FNMSUB_D(rd, rs1, r2, rs3, rm) => emit_r4(0b1001011, 0b01, rm.encode32(), rd, rs1, r2, rs3),
129 RV32Instr::FNMADD_D(rd, rs1, r2, rs3, rm) => emit_r4(0b1001111, 0b01, rm.encode32(), rd, rs1, r2, rs3),
130 RV32Instr::FADD_D(rd, rs1, rs2, rm) => emit_r(0b1010011, 0b0000001, rm.encode32(), rd, rs1, rs2),
131 RV32Instr::FSUB_D(rd, rs1, rs2, rm) => emit_r(0b1010011, 0b0000101, rm.encode32(), rd, rs1, rs2),
132 RV32Instr::FMUL_D(rd, rs1, rs2, rm) => emit_r(0b1010011, 0b0001001, rm.encode32(), rd, rs1, rs2),
133 RV32Instr::FDIV_D(rd, rs1, rs2, rm) => emit_r(0b1010011, 0b0001101, rm.encode32(), rd, rs1, rs2),
134 RV32Instr::FSQRT_D(rd, rs1, rm) => emit_r(0b1010011, 0b0101101, rm.encode32(), rd, rs1, Rs2(ZERO)),
135 RV32Instr::FSGNJ_D(rd, rs1, rs2) => emit_r(0b1010011, 0b0010001, 0b000, rd, rs1, rs2),
136 RV32Instr::FSGNJN_D(rd, rs1, rs2) => emit_r(0b1010011, 0b0010001, 0b001, rd, rs1, rs2),
137 RV32Instr::FSGNJX_D(rd, rs1, rs2) => emit_r(0b1010011, 0b0010001, 0b010, rd, rs1, rs2),
138 RV32Instr::FMIN_D(rd, rs1, rs2) => emit_r(0b1010011, 0b0010101, 0b000, rd, rs1, rs2),
139 RV32Instr::FMAX_D(rd, rs1, rs2) => emit_r(0b1010011, 0b0010101, 0b001, rd, rs1, rs2),
140 RV32Instr::FCVT_S_D(rd, rs1, rm) => emit_r(0b1010011, 0b0100000, rm.encode32(), rd, rs1, Rs2(X(Fin::new(1)))),
141 RV32Instr::FCVT_D_S(rd, rs1, rm) => emit_r(0b1010011, 0b0100001, rm.encode32(), rd, rs1, Rs2(ZERO)),
142 RV32Instr::FEQ_D(rd, rs1, rs2) => emit_r(0b1010011, 0b1010001, 0b010, rd, rs1, rs2),
143 RV32Instr::FLT_D(rd, rs1, rs2) => emit_r(0b1010011, 0b1010001, 0b001, rd, rs1, rs2),
144 RV32Instr::FLE_D(rd, rs1, rs2) => emit_r(0b1010011, 0b1010001, 0b000, rd, rs1, rs2),
145 RV32Instr::FCLASS_D(rd, rs1) => emit_r(0b1010011, 0b1110001, 0b001, rd, rs1, Rs2(ZERO)),
146 RV32Instr::FCVT_W_D(rd, rs1, rm) => emit_r(0b1010011, 0b1100001, rm.encode32(), rd, rs1, Rs2(ZERO)),
147 RV32Instr::FCVT_WU_D(rd, rs1, rm) => emit_r(0b1010011, 0b1100001, rm.encode32(), rd, rs1, Rs2(X(Fin::new(1)))),
148 RV32Instr::FCVT_D_W(rd, rs1, rm) => emit_r(0b1010011, 0b1101001, rm.encode32(), rd, rs1, Rs2(ZERO)),
149 RV32Instr::FCVT_D_WU(rd, rs1, rm) => emit_r(0b1010011, 0b1101001, rm.encode32(), rd, rs1, Rs2(X(Fin::new(1)))),
150 }
151 }
152}
153
154impl Encode32 for RV64Instr {
155 fn encode32(self) -> u32 {
156 match self {
157 RV64Instr::LWU(rd, rs1, imm) => emit_i(0b0000011, 0b110, rd, rs1, imm.decode_sext()),
159 RV64Instr::LD(rd, rs1, imm) => emit_i(0b0000011, 0b011, rd, rs1, imm.decode_sext()),
160 RV64Instr::SD(rs1, rs2, imm) => emit_s(0b0100011, 0b011, rs1, rs2, imm.decode_sext()),
161 RV64Instr::SLLI(rd, rs1, shamt6) => emit_r_shamt6(0b0010011, 0b000000, 0b001, rd, rs1, shamt6.0 as u32),
162 RV64Instr::SRLI(rd, rs1, shamt6) => emit_r_shamt6(0b0010011, 0b000000, 0b101, rd, rs1, shamt6.0 as u32),
163 RV64Instr::SRAI(rd, rs1, shamt6) => emit_r_shamt6(0b0010011, 0b010000, 0b101, rd, rs1, shamt6.0 as u32),
164 RV64Instr::ADDIW(rd, rs1, imm) => emit_i(0b0011011, 0b000, rd, rs1, imm.decode_sext()),
165 RV64Instr::SLLIW(rd, rs1, shamt5) => emit_r(0b0011011, 0b0000000, 0b001, rd, rs1, Rs2(X(Fin::new(shamt5.0 as u32)))),
166 RV64Instr::SRLIW(rd, rs1, shamt5) => emit_r(0b0011011, 0b0000000, 0b101, rd, rs1, Rs2(X(Fin::new(shamt5.0 as u32)))),
167 RV64Instr::SRAIW(rd, rs1, shamt5) => emit_r(0b0011011, 0b0100000, 0b101, rd, rs1, Rs2(X(Fin::new(shamt5.0 as u32)))),
168 RV64Instr::ADDW(rd, rs1, rs2) => emit_r(0b0111011, 0b0000000, 0b000, rd, rs1, rs2),
169 RV64Instr::SUBW(rd, rs1, rs2) => emit_r(0b0111011, 0b0100000, 0b000, rd, rs1, rs2),
170 RV64Instr::SLLW(rd, rs1, rs2) => emit_r(0b0111011, 0b0000000, 0b001, rd, rs1, rs2),
171 RV64Instr::SRLW(rd, rs1, rs2) => emit_r(0b0111011, 0b0000000, 0b101, rd, rs1, rs2),
172 RV64Instr::SRAW(rd, rs1, rs2) => emit_r(0b0111011, 0b0100000, 0b101, rd, rs1, rs2),
173 RV64Instr::MULW(rd, rs1, rs2) => emit_r(0b0111011, 0b0000001, 0b000, rd, rs1, rs2),
175 RV64Instr::DIVW(rd, rs1, rs2) => emit_r(0b0111011, 0b0000001, 0b100, rd, rs1, rs2),
176 RV64Instr::DIVUW(rd, rs1, rs2) => emit_r(0b0111011, 0b0000001, 0b101, rd, rs1, rs2),
177 RV64Instr::REMW(rd, rs1, rs2) => emit_r(0b0111011, 0b0000001, 0b110, rd, rs1, rs2),
178 RV64Instr::REMUW(rd, rs1, rs2) => emit_r(0b0111011, 0b0000001, 0b111, rd, rs1, rs2),
179 RV64Instr::LR_D(rd, rs1, aq, rl) => emit_r_amo(0b0101111, 0b00010, 0b011, aq, rl, rd, rs1, Rs2(ZERO)),
181 RV64Instr::SC_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b00011, 0b011, aq, rl, rd, rs1, rs2),
182 RV64Instr::AMOSWAP_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b00001, 0b011, aq, rl, rd, rs1, rs2),
183 RV64Instr::AMOADD_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b00000, 0b011, aq, rl, rd, rs1, rs2),
184 RV64Instr::AMOXOR_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b00100, 0b011, aq, rl, rd, rs1, rs2),
185 RV64Instr::AMOAND_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b01100, 0b011, aq, rl, rd, rs1, rs2),
186 RV64Instr::AMOOR_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b01000, 0b011, aq, rl, rd, rs1, rs2),
187 RV64Instr::AMOMIN_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b10000, 0b011, aq, rl, rd, rs1, rs2),
188 RV64Instr::AMOMAX_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b10100, 0b011, aq, rl, rd, rs1, rs2),
189 RV64Instr::AMOMINU_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b11000, 0b011, aq, rl, rd, rs1, rs2),
190 RV64Instr::AMOMAXU_D(rd, rs1, rs2, aq, rl) => emit_r_amo(0b0101111, 0b11100, 0b011, aq, rl, rd, rs1, rs2),
191 RV64Instr::FCVT_L_S(rd, rs1, rm) => emit_r(0b1010011, 0b1100000, rm.encode32(), rd, rs1, Rs2(X(Fin::new(0b00010)))),
193 RV64Instr::FCVT_LU_S(rd, rs1, rm) => emit_r(0b1010011, 0b1100000, rm.encode32(), rd, rs1, Rs2(X(Fin::new(0b00011)))),
194 RV64Instr::FCVT_S_L(rd, rs1, rm) => emit_r(0b1010011, 0b1101000, rm.encode32(), rd, rs1, Rs2(X(Fin::new(0b00010)))),
195 RV64Instr::FCVT_S_LU(rd, rs1, rm) => emit_r(0b1010011, 0b1101000, rm.encode32(), rd, rs1, Rs2(X(Fin::new(0b00011)))),
196 RV64Instr::FCVT_L_D(rd, rs1, rm) => emit_r(0b1010011, 0b1100001, rm.encode32(), rd, rs1, Rs2(X(Fin::new(0b00010)))),
198 RV64Instr::FCVT_LU_D(rd, rs1, rm) => emit_r(0b1010011, 0b1100001, rm.encode32(), rd, rs1, Rs2(X(Fin::new(0b00011)))),
199 RV64Instr::FMV_X_D(rd, rs1) => emit_r(0b1010011, 0b1111001, 0b000, rd, rs1, Rs2(ZERO)),
200 RV64Instr::FCVT_D_L(rd, rs1, rm) => emit_r(0b1010011, 0b1101001, rm.encode32(), rd, rs1, Rs2(X(Fin::new(0b00010)))),
201 RV64Instr::FCVT_D_LU(rd, rs1, rm) => emit_r(0b1010011, 0b1101001, rm.encode32(), rd, rs1, Rs2(X(Fin::new(0b00011)))),
202 RV64Instr::FMV_D_X(rd, rs1) => emit_r(0b1010011, 0b1111001, 0b000, rd, rs1, Rs2(ZERO)),
203 RV64Instr::CSRRW(rd, rs1, csr) => emit_i(0b1110011, 0b001, rd, rs1, csr.value() as i32),
205 RV64Instr::CSRRS(rd, rs1, csr) => emit_i(0b1110011, 0b010, rd, rs1, csr.value() as i32),
206 RV64Instr::CSRRC(rd, rs1, csr) => emit_i(0b1110011, 0b011, rd, rs1, csr.value() as i32),
207 RV64Instr::CSRRWI(rd, uimm, csr) => emit_i(0b1110011, 0b101, rd, Rs1(X(Fin::new(uimm.value()))), csr.value() as i32),
208 RV64Instr::CSRRSI(rd, uimm, csr) => emit_i(0b1110011, 0b110, rd, Rs1(X(Fin::new(uimm.value()))), csr.value() as i32),
209 RV64Instr::CSRRCI(rd, uimm, csr) => emit_i(0b1110011, 0b111, rd, Rs1(X(Fin::new(uimm.value()))), csr.value() as i32),
210 RV64Instr::FENCE_I(rd, rs1, imm) => emit_i(0b0001111, 0b001, rd, rs1, imm.decode_sext()),
212 RV64Instr::SRET => 0b0001000_00010_00000_000_00000_1110011,
214 RV64Instr::MRET => 0b0011000_00010_00000_000_00000_1110011,
215 RV64Instr::WFI => 0b0001000_00010_00000_000_00000_1110011,
216 RV64Instr::SFENCE_VMA(rs1, rs2) => emit_r(0b1110011, 0b0001001, 0b000, Rd(ZERO), rs1, rs2),
217 RV64Instr::SINVAL_VMA(rs1, rs2) => emit_r(0b1110011, 0b0001011, 0b000, Rd(ZERO), rs1, rs2),
218 RV64Instr::SFENCE_W_INVAL => 0b0001100_00000_00000_000_00000_1110011,
219 RV64Instr::SFENCE_INVAL_IR => 0b0001100_00001_00000_000_00000_1110011,
220 }
221 }
222}
223
224impl Encode32 for Reg {
225 fn encode32(self) -> u32 {
226 match self {
227 ZERO => 0,
228 X(x) => x.value(),
229 F(f) => f.value(),
230 PC => panic!("No direct pc access in RISC-V instruction encoding"),
231 FCSR => panic!("No direct fcsr access in RISC-V instruction encoding"),
232 }
233 }
234}
235
236impl Encode32 for Rd {
237 fn encode32(self) -> u32 {
238 self.0.encode32()
239 }
240}
241
242impl Encode32 for Rs1 {
243 fn encode32(self) -> u32 {
244 self.0.encode32()
245 }
246}
247
248impl Encode32 for Rs2 {
249 fn encode32(self) -> u32 {
250 self.0.encode32()
251 }
252}
253
254impl Encode32 for Rs3 {
255 fn encode32(self) -> u32 {
256 self.0.encode32()
257 }
258}
259
260impl Encode32 for RoundingMode {
261 fn encode32(self) -> u32 {
262 match self {
263 RoundingMode::RNE => 0b000,
264 RoundingMode::RTZ => 0b001,
265 RoundingMode::RDN => 0b010,
266 RoundingMode::RUP => 0b011,
267 RoundingMode::RMM => 0b100,
268 RoundingMode::DYN => 0b111,
269 }
270 }
271}
272
273fn emit_r(opcode: u32, funct7: u32, funct3: u32, rd: Rd, rs1: Rs1, rs2: Rs2) -> u32 {
277 (opcode & 0b1111111)
279 | ((rd.encode32() & 0b11111) << 7)
280 | ((funct3 & 0b111) << 12)
281 | ((rs1.encode32() & 0b11111) << 15)
282 | ((rs2.encode32() & 0b11111) << 20)
283 | ((funct7 & 0b1111111) << 25)
284}
285
286fn emit_r_shamt6(opcode: u32, funct6: u32, funct3: u32, rd: Rd, rs1: Rs1, shamt6: u32) -> u32 {
288 (opcode & 0b1111111)
290 | ((rd.encode32() & 0b11111) << 7)
291 | ((funct3 & 0b111) << 12)
292 | ((rs1.encode32() & 0b11111) << 15)
293 | ((shamt6 & 0b111111) << 20)
294 | ((funct6 & 0b111111) << 26)
295}
296
297fn emit_r_amo(opcode: u32, funct5: u32, funct3: u32, aq: AQ, rl: RL, rd: Rd, rs1: Rs1, rs2: Rs2) -> u32 {
299 (opcode & 0b1111111)
301 | ((rd.encode32() & 0b11111) << 7)
302 | ((funct3 & 0b111) << 12)
303 | ((rs1.encode32() & 0b11111) << 15)
304 | ((rs2.encode32() & 0b11111) << 20)
305 | ((rl.0 as u32) << 25)
306 | ((aq.0 as u32) << 26)
307 | ((funct5 & 0b1111111) << 27)
308}
309
310fn emit_i(opcode: u32, funct3: u32, rd: Rd, rs1: Rs1, imm: i32) -> u32 {
312 (opcode & 0b1111111)
314 | ((rd.encode32() & 0b11111) << 7)
315 | ((funct3 & 0b111) << 12)
316 | ((rs1.encode32() & 0b11111) << 15)
317 | ((imm as u32 & 0b111111111111) << 20)
318}
319
320fn emit_s(opcode: u32, funct3: u32, rs1: Rs1, rs2: Rs2, imm: i32) -> u32 {
322 (opcode & 0b1111111)
324 | ((imm as u32 & 0b11111) << 7)
325 | ((funct3 & 0b111) << 12)
326 | ((rs1.encode32() & 0b11111) << 15)
327 | ((rs2.encode32() & 0b11111) << 20)
328 | ((imm as u32 & 0b111111100000) << 20)
329}
330
331fn emit_r4(opcode: u32, funct2: u32, funct3: u32, rd: Rd, rs1: Rs1, rs2: Rs2, rs3: Rs3) -> u32 {
333 (opcode & 0b1111111)
335 | ((rd.encode32() & 0b11111) << 7)
336 | ((funct3 & 0b111) << 12)
337 | ((rs1.encode32() & 0b11111) << 15)
338 | ((rs2.encode32() & 0b11111) << 20)
339 | ((funct2 & 0b11) << 25)
340 | ((rs3.encode32() & 0b11111) << 27)
341}
342
343fn emit_u(opcode: u32, rd: Rd, imm: u32) -> u32 {
345 (opcode & 0b1111111)
347 | ((rd.encode32() & 0b11111) << 7)
348 | ((imm as u32 & 0b11111111111111111111) << 12)
349}
350
351fn emit_b(opcode: u32, funct3: u32, rs1: Rs1, rs2: Rs2, imm: i32) -> u32 {
353 (opcode & 0b1111111)
355 | ((imm as u32 & 0b1) << 7)
356 | ((imm as u32 & 0b11110) << 7)
357 | ((funct3 & 0b111) << 12)
358 | ((rs1.encode32() & 0b11111) << 15)
359 | ((rs2.encode32() & 0b11111) << 20)
360 | ((imm as u32 & 0b11111100000) << 20)
361 | ((imm as u32 & 0b100000000000) << 19)
362 | ((imm as u32 & 0b111111000000000000000) << 12)
363}
364
365fn emit_j(opcode: u32, rd: Rd, imm: i32) -> u32 {
367 (opcode & 0b1111111)
369 | ((rd.encode32() & 0b11111) << 7)
370 | ((imm as u32 & 0b11111111) << 12)
371 | ((imm as u32 & 0b111111110000000000000) << 12)
372 | ((imm as u32 & 0b100000000000000000000) << 11)
373 | ((imm as u32 & 0b1000000000000000000000) << 9)
374 | ((imm as u32 & 0b11111100000000000000000000000000) >> 11)
375}
376
377#[cfg(test)]
378mod tests {
379 use crate::asm::encode32::Encode32;
380 use crate::isa::data::Fin;
381 use crate::isa::rv32::RV32Instr;
382 use crate::isa::typed::{Instr, Rd, RoundingMode, Rs1, Rs2, Rs3};
383 use crate::isa::typed::Reg::{F, X};
384
385 #[test]
386 pub fn xlb_step2() {
387 let x = vec![
388 (RV32Instr::FADD_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2))), RoundingMode::DYN), "FADD_D"),
389 (RV32Instr::FSUB_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2))), RoundingMode::DYN), "FSUB_D"),
390 (RV32Instr::FMUL_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2))), RoundingMode::DYN), "FMUL_D"),
391 (RV32Instr::FDIV_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2))), RoundingMode::DYN), "FDIV_D"),
392 (RV32Instr::FSGNJ_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FSGNJ_D"),
393 (RV32Instr::FSGNJN_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FSGNJN_D"),
394 (RV32Instr::FSGNJX_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FSGNJX_D"),
395 (RV32Instr::FSGNJX_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FSGNJX_D"),
396 (RV32Instr::FMIN_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FMIN_D"),
397 (RV32Instr::FMIN_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FMIN_D"),
398 (RV32Instr::FMIN_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FMIN_D"),
399 (RV32Instr::FMAX_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FMAX_D"),
400 (RV32Instr::FMAX_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FMAX_D"),
401 (RV32Instr::FMAX_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FMAX_D"),
402 (RV32Instr::FEQ_D(Rd(X(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FEQ_D"),
403 (RV32Instr::FEQ_D(Rd(X(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FEQ_D"),
404 (RV32Instr::FEQ_D(Rd(X(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FEQ_D"),
405 (RV32Instr::FEQ_D(Rd(X(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FEQ_D"),
406 (RV32Instr::FLT_D(Rd(X(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FLT_D"),
407 (RV32Instr::FLT_D(Rd(X(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FLT_D"),
408 (RV32Instr::FLE_D(Rd(X(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FLE_D"),
409 (RV32Instr::FLE_D(Rd(X(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2)))), "FLE_D"),
410 (RV32Instr::FMADD_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2))), Rs3(F(Fin::new(8))), RoundingMode::DYN), "FMADD_D"),
411 (RV32Instr::FMSUB_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2))), Rs3(F(Fin::new(8))), RoundingMode::DYN), "FMSUB_D"),
412 (RV32Instr::FNMSUB_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2))), Rs3(F(Fin::new(8))), RoundingMode::DYN), "FNMSUB_D"),
413 (RV32Instr::FNMADD_D(Rd(F(Fin::new(4))), Rs1(F(Fin::new(3))), Rs2(F(Fin::new(2))), Rs3(F(Fin::new(8))), RoundingMode::DYN), "FNMADD_D"),
414 ];
415
416 for (i, _) in x {
417 let asm = i.encode32();
418 let ii = Instr::decode32(asm).unwrap();
419 assert_eq!(Instr::RV32(i), ii);
420 }
421 }
422}