refactor asm more
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
use crate::{
|
||||
compiler::arch::riscv::Reg,
|
||||
util::{Bits32, BitsI32},
|
||||
};
|
||||
|
||||
pub struct RawInstruction(u32);
|
||||
|
||||
use RawInstruction as I;
|
||||
|
||||
impl RawInstruction {
|
||||
pub fn to_le_bytes(&self) -> impl IntoIterator<Item = u8> {
|
||||
self.0.to_le_bytes().into_iter()
|
||||
}
|
||||
pub fn to_be_bytes(&self) -> impl IntoIterator<Item = u8> {
|
||||
self.0.to_be_bytes().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
pub const SYSTEM: u32 = 0b1110011;
|
||||
pub const LOAD: u32 = 0b0000011;
|
||||
pub const STORE: u32 = 0b0100011;
|
||||
pub const AUIPC: u32 = 0b0010111;
|
||||
pub const IMM_OP: u32 = 0b0010011;
|
||||
pub const OP: u32 = 0b0110011;
|
||||
pub const JAL: u32 = 0b1101111;
|
||||
pub const JALR: u32 = 0b1100111;
|
||||
|
||||
pub type Funct3 = Bits32<2, 0>;
|
||||
pub type Funct7 = Bits32<6, 0>;
|
||||
|
||||
pub const fn r_type(
|
||||
funct7: Bits32<6, 0>,
|
||||
rs2: Reg,
|
||||
rs1: Reg,
|
||||
funct3: Bits32<2, 0>,
|
||||
rd: Reg,
|
||||
opcode: u32,
|
||||
) -> I {
|
||||
I((funct7.val() << 25)
|
||||
+ (rs2.val() << 20)
|
||||
+ (rs1.val() << 15)
|
||||
+ (funct3.val() << 12)
|
||||
+ (rd.val() << 7)
|
||||
+ opcode)
|
||||
}
|
||||
pub const fn i_type(imm: Bits32<11, 0>, rs1: Reg, funct: Funct3, rd: Reg, opcode: u32) -> I {
|
||||
I((imm.val() << 20) + (rs1.val() << 15) + (funct.val() << 12) + (rd.val() << 7) + opcode)
|
||||
}
|
||||
pub const fn s_type(rs2: Reg, rs1: Reg, funct3: Funct3, imm: Bits32<11, 0>, opcode: u32) -> I {
|
||||
I((imm.bits(11, 5) << 25)
|
||||
+ (rs2.val() << 20)
|
||||
+ (rs1.val() << 15)
|
||||
+ (funct3.val() << 12)
|
||||
+ (imm.bits(4, 0) << 7)
|
||||
+ opcode)
|
||||
}
|
||||
pub const fn b_type(rs2: Reg, rs1: Reg, funct3: Funct3, imm: Bits32<12, 1>, opcode: u32) -> I {
|
||||
I((imm.bit(12) << 31)
|
||||
+ (imm.bits(10, 5) << 25)
|
||||
+ (rs2.val() << 20)
|
||||
+ (rs1.val() << 15)
|
||||
+ (funct3.val() << 8)
|
||||
+ (imm.bits(4, 1) << 8)
|
||||
+ (imm.bit(11) << 7)
|
||||
+ opcode)
|
||||
}
|
||||
pub const fn u_type(imm: Bits32<31, 12>, rd: Reg, opcode: u32) -> I {
|
||||
I((imm.bits(31, 12) << 12) + (rd.val() << 7) + opcode)
|
||||
}
|
||||
pub const fn j_type(imm: Bits32<20, 1>, rd: Reg, opcode: u32) -> I {
|
||||
I((imm.bit(20) << 31)
|
||||
+ (imm.bits(10, 1) << 21)
|
||||
+ (imm.bit(11) << 20)
|
||||
+ (imm.bits(19, 12) << 12)
|
||||
+ (rd.val() << 7)
|
||||
+ opcode)
|
||||
}
|
||||
|
||||
pub fn opr(op: Funct3, funct: Funct7, dest: Reg, src1: Reg, src2: Reg) -> I {
|
||||
r_type(funct, src2, src1, op.into(), dest, OP)
|
||||
}
|
||||
pub fn opi(op: Funct3, dest: Reg, src: Reg, imm: BitsI32<11, 0>) -> RawInstruction {
|
||||
i_type(imm.to_u(), src, op.into(), dest, IMM_OP)
|
||||
}
|
||||
pub fn opif7(op: Funct3, funct: Funct7, dest: Reg, src: Reg, imm: BitsI32<4, 0>) -> I {
|
||||
i_type(
|
||||
Bits32::new(imm.to_u().val() + (funct.val() << 5)),
|
||||
src,
|
||||
op.into(),
|
||||
dest,
|
||||
IMM_OP,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
mod base;
|
||||
mod rv32i;
|
||||
mod rv32m;
|
||||
mod string;
|
||||
pub use base::*;
|
||||
pub use rv32i::*;
|
||||
pub use rv32m::*;
|
||||
pub use string::*;
|
||||
@@ -0,0 +1,68 @@
|
||||
use crate::{compiler::arch::riscv::Reg, util::Bits32};
|
||||
|
||||
use super::{opr, Funct3, Funct7, RawInstruction};
|
||||
|
||||
pub mod op32i {
|
||||
use super::*;
|
||||
|
||||
pub const ADD: Funct3 = Funct3::new(0b000);
|
||||
pub const SL: Funct3 = Funct3::new(0b001);
|
||||
pub const SLT: Funct3 = Funct3::new(0b010);
|
||||
pub const SLTU: Funct3 = Funct3::new(0b011);
|
||||
pub const XOR: Funct3 = Funct3::new(0b100);
|
||||
pub const SR: Funct3 = Funct3::new(0b101);
|
||||
pub const OR: Funct3 = Funct3::new(0b110);
|
||||
pub const AND: Funct3 = Funct3::new(0b111);
|
||||
|
||||
pub const LOGICAL: Funct7 = Funct7::new(0b0000000);
|
||||
pub const ARITHMETIC: Funct7 = Funct7::new(0b0100000);
|
||||
pub const F7ADD: Funct7 = Funct7::new(0b0000000);
|
||||
pub const F7SUB: Funct7 = Funct7::new(0b0100000);
|
||||
|
||||
pub const FUNCT7: Funct7 = Funct7::new(0b0000000);
|
||||
}
|
||||
|
||||
pub mod width {
|
||||
use crate::ir::Len;
|
||||
|
||||
use super::*;
|
||||
pub const MAIN: [Funct3; 4] = [B, H, W, D];
|
||||
|
||||
pub const B: Funct3 = Funct3::new(0b000);
|
||||
pub const H: Funct3 = Funct3::new(0b001);
|
||||
pub const W: Funct3 = Funct3::new(0b010);
|
||||
pub const D: Funct3 = Funct3::new(0b011);
|
||||
pub const BU: Funct3 = Funct3::new(0b100);
|
||||
pub const HU: Funct3 = Funct3::new(0b101);
|
||||
pub const WU: Funct3 = Funct3::new(0b110);
|
||||
|
||||
pub const fn str(w: Funct3) -> &'static str {
|
||||
match w {
|
||||
B => "b",
|
||||
H => "h",
|
||||
W => "w",
|
||||
D => "d",
|
||||
BU => "bu",
|
||||
HU => "hu",
|
||||
WU => "wu",
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn len(w: Funct3) -> Len {
|
||||
match w {
|
||||
B => 1,
|
||||
H => 2,
|
||||
W => 4,
|
||||
D => 8,
|
||||
BU => 1,
|
||||
HU => 2,
|
||||
WU => 4,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opr32i(op: Funct3, dest: Reg, src1: Reg, src2: Reg) -> RawInstruction {
|
||||
opr(op, Bits32::new(0), dest, src1, src2)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
use super::{Funct3, Funct7};
|
||||
|
||||
pub mod op32m {
|
||||
use super::*;
|
||||
pub const MUL: Funct3 = Funct3::new(0b000);
|
||||
pub const MULH: Funct3 = Funct3::new(0b001);
|
||||
pub const MULHSU: Funct3 = Funct3::new(0b010);
|
||||
pub const MULHU: Funct3 = Funct3::new(0b011);
|
||||
pub const DIV: Funct3 = Funct3::new(0b100);
|
||||
pub const DIVU: Funct3 = Funct3::new(0b101);
|
||||
pub const REM: Funct3 = Funct3::new(0b110);
|
||||
pub const REMU: Funct3 = Funct3::new(0b111);
|
||||
|
||||
pub const FUNCT7: Funct7 = Funct7::new(0b0000001);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
use super::*;
|
||||
|
||||
pub fn opstr(op: Funct3, funct: Funct7) -> &'static str {
|
||||
match (op, funct) {
|
||||
(op32i::SLT, op32i::FUNCT7) => "slt",
|
||||
(op32i::SLTU, op32i::FUNCT7) => "sltu",
|
||||
(op32i::XOR, op32i::FUNCT7) => "xor",
|
||||
(op32i::OR, op32i::FUNCT7) => "or",
|
||||
(op32i::AND, op32i::FUNCT7) => "and",
|
||||
|
||||
(op32i::ADD, op32i::F7ADD) => "add",
|
||||
(op32i::ADD, op32i::F7SUB) => "sub",
|
||||
(op32i::SL, op32i::LOGICAL) => "sll",
|
||||
(op32i::SR, op32i::LOGICAL) => "srl",
|
||||
(op32i::SR, op32i::ARITHMETIC) => "sra",
|
||||
|
||||
(op32m::MUL, op32m::FUNCT7) => "mul",
|
||||
(op32m::MULH, op32m::FUNCT7) => "mulh",
|
||||
(op32m::MULHSU, op32m::FUNCT7) => "mulhsu",
|
||||
(op32m::MULHU, op32m::FUNCT7) => "mulhu",
|
||||
(op32m::DIV, op32m::FUNCT7) => "div",
|
||||
(op32m::DIVU, op32m::FUNCT7) => "divu",
|
||||
(op32m::REM, op32m::FUNCT7) => "rem",
|
||||
(op32m::REMU, op32m::FUNCT7) => "remu",
|
||||
_ => "unknown",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user