From c766d34b6aff1f3bb664ef38b5faf3c11a23618d Mon Sep 17 00:00:00 2001 From: shadow cat Date: Sun, 23 Mar 2025 15:19:34 -0400 Subject: [PATCH] more asm cleanup --- src/compiler/arch/riscv/asm.rs | 9 ++++-- src/compiler/arch/riscv/compile.rs | 11 ++++---- src/compiler/arch/riscv/instr/base.rs | 10 +++---- src/compiler/arch/riscv/instr/mod.rs | 2 ++ src/compiler/arch/riscv/instr/rv32i.rs | 34 ++++++++++++++++++++-- src/compiler/arch/riscv/mod.rs | 2 -- src/compiler/arch/riscv/single.rs | 39 -------------------------- src/parser/v3/lower/arch/riscv64.rs | 4 +-- 8 files changed, 52 insertions(+), 59 deletions(-) delete mode 100644 src/compiler/arch/riscv/single.rs diff --git a/src/compiler/arch/riscv/asm.rs b/src/compiler/arch/riscv/asm.rs index 91dfb1f..350325b 100644 --- a/src/compiler/arch/riscv/asm.rs +++ b/src/compiler/arch/riscv/asm.rs @@ -54,7 +54,8 @@ pub enum LinkerInstruction { Call(S), J(S), Ret, - Ecall, + ECall, + EBreak, Li { dest: R, imm: i32, @@ -132,7 +133,8 @@ impl Instr for LinkerInstruction { } } Self::Ret => ret(), - Self::Ecall => ecall(), + Self::ECall => ecall(), + Self::EBreak => ebreak(), Self::Li { dest, imm } => addi(*dest, zero, BitsI32::new(*imm)), }; data.extend(last.to_le_bytes()); @@ -170,7 +172,8 @@ impl LinkerInstruction { impl std::fmt::Debug for LinkerInstruction { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::Ecall => write!(f, "ecall"), + Self::ECall => write!(f, "ecall"), + Self::EBreak => write!(f, "ebreak"), Self::Li { dest, imm } => write!(f, "li {dest:?}, {imm:?}"), Self::Mv { dest, src } => write!(f, "mv {dest:?}, {src:?}"), Self::La { dest, src } => write!(f, "la {dest:?}, {src:?}"), diff --git a/src/compiler/arch/riscv/compile.rs b/src/compiler/arch/riscv/compile.rs index ce8ec80..892e6a8 100644 --- a/src/compiler/arch/riscv/compile.rs +++ b/src/compiler/arch/riscv/compile.rs @@ -134,7 +134,8 @@ pub fn compile(program: IRLProgram) -> (Vec, Option) { } for i in instructions { match *i { - AI::Ecall => v.push(LI::Ecall), + AI::ECall => v.push(LI::ECall), + AI::EBreak => v.push(LI::EBreak), AI::Li { dest, imm } => v.push(LI::Li { dest: r(dest), imm }), AI::Mv { dest, src } => v.push(LI::Mv { dest: r(dest), @@ -149,7 +150,7 @@ pub fn compile(program: IRLProgram) -> (Vec, Option) { } => v.push(LI::Load { width, dest: r(dest), - offset: offset as i32, + offset, base: r(base), }), AI::Store { @@ -160,7 +161,7 @@ pub fn compile(program: IRLProgram) -> (Vec, Option) { } => v.push(LI::Store { width, src: r(src), - offset: offset as i32, + offset, base: r(base), }), AI::Op { @@ -180,7 +181,7 @@ pub fn compile(program: IRLProgram) -> (Vec, Option) { op, dest: r(dest), src: r(src), - imm: imm as i32, + imm, }), AI::OpImmF7 { op, @@ -193,7 +194,7 @@ pub fn compile(program: IRLProgram) -> (Vec, Option) { funct, dest: r(dest), src: r(src), - imm: imm as i32, + imm, }), AI::Ret => v.push(LI::Ret), AI::Call(s) => todo!(), diff --git a/src/compiler/arch/riscv/instr/base.rs b/src/compiler/arch/riscv/instr/base.rs index b748afb..79722a1 100644 --- a/src/compiler/arch/riscv/instr/base.rs +++ b/src/compiler/arch/riscv/instr/base.rs @@ -5,8 +5,6 @@ use crate::{ pub struct RawInstruction(u32); -use RawInstruction as I; - impl RawInstruction { pub fn to_le_bytes(&self) -> impl IntoIterator { self.0.to_le_bytes().into_iter() @@ -28,6 +26,8 @@ pub const JALR: u32 = 0b1100111; pub type Funct3 = Bits32<2, 0>; pub type Funct7 = Bits32<6, 0>; +use RawInstruction as I; + pub const fn r_type( funct7: Bits32<6, 0>, rs2: Reg, @@ -77,16 +77,16 @@ pub const fn j_type(imm: Bits32<20, 1>, rd: Reg, opcode: u32) -> I { } pub fn opr(op: Funct3, funct: Funct7, dest: Reg, src1: Reg, src2: Reg) -> I { - r_type(funct, src2, src1, op.into(), dest, OP) + r_type(funct, src2, src1, op, 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) + i_type(imm.to_u(), src, op, 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(), + op, dest, IMM_OP, ) diff --git a/src/compiler/arch/riscv/instr/mod.rs b/src/compiler/arch/riscv/instr/mod.rs index 858e2c8..c398dbe 100644 --- a/src/compiler/arch/riscv/instr/mod.rs +++ b/src/compiler/arch/riscv/instr/mod.rs @@ -1,3 +1,5 @@ +use super::*; + mod base; mod rv32i; mod rv32m; diff --git a/src/compiler/arch/riscv/instr/rv32i.rs b/src/compiler/arch/riscv/instr/rv32i.rs index 968bd5e..a3eeb26 100644 --- a/src/compiler/arch/riscv/instr/rv32i.rs +++ b/src/compiler/arch/riscv/instr/rv32i.rs @@ -1,6 +1,6 @@ use crate::{compiler::arch::riscv::Reg, util::Bits32}; -use super::{opr, Funct3, Funct7, RawInstruction}; +use super::*; pub mod op32i { use super::*; @@ -63,6 +63,34 @@ pub mod width { } } -pub fn opr32i(op: Funct3, dest: Reg, src1: Reg, src2: Reg) -> RawInstruction { - opr(op, Bits32::new(0), dest, src1, src2) +pub const fn ecall() -> RawInstruction { + i_type(Bits32::new(0), zero, Bits32::new(0), zero, SYSTEM) +} +pub const fn ebreak() -> RawInstruction { + i_type(Bits32::new(1), zero, Bits32::new(0), zero, SYSTEM) +} +pub const fn auipc(dest: Reg, imm: BitsI32<31, 12>) -> RawInstruction { + u_type(imm.to_u(), dest, AUIPC) +} + +pub const fn load(width: Funct3, dest: Reg, offset: BitsI32<11, 0>, base: Reg) -> RawInstruction { + i_type(offset.to_u(), base, width, dest, LOAD) +} + +pub const fn store(width: Funct3, src: Reg, offset: BitsI32<11, 0>, base: Reg) -> RawInstruction { + s_type(src, base, width, offset.to_u(), STORE) +} + +pub const fn jal(dest: Reg, offset: BitsI32<20, 1>) -> RawInstruction { + j_type(offset.to_u(), dest, JAL) +} +pub const fn jalr(dest: Reg, offset: BitsI32<11, 0>, base: Reg) -> RawInstruction { + i_type(offset.to_u(), base, Bits32::new(0), dest, JALR) +} + +pub const fn j(offset: BitsI32<20, 1>) -> RawInstruction { + jal(zero, offset) +} +pub const fn ret() -> RawInstruction { + jalr(zero, BitsI32::new(0), ra) } diff --git a/src/compiler/arch/riscv/mod.rs b/src/compiler/arch/riscv/mod.rs index bf762e7..275dcdc 100644 --- a/src/compiler/arch/riscv/mod.rs +++ b/src/compiler/arch/riscv/mod.rs @@ -1,11 +1,9 @@ mod asm; mod compile; mod reg; -mod single; mod instr; use crate::util::BitsI32; -use single::*; pub use asm::*; pub use compile::*; diff --git a/src/compiler/arch/riscv/single.rs b/src/compiler/arch/riscv/single.rs deleted file mode 100644 index 0e89008..0000000 --- a/src/compiler/arch/riscv/single.rs +++ /dev/null @@ -1,39 +0,0 @@ -use crate::util::{Bits32, BitsI32}; - -use super::*; - -use RawInstruction as I; - -pub const fn ecall() -> I { - i_type(Bits32::new(0), zero, Bits32::new(0), zero, SYSTEM) -} -pub const fn ebreak() -> I { - i_type(Bits32::new(1), zero, Bits32::new(0), zero, SYSTEM) -} -pub const fn auipc(dest: Reg, imm: BitsI32<31, 12>) -> I { - u_type(imm.to_u(), dest, AUIPC) -} - -pub const fn load(width: Funct3, dest: Reg, offset: BitsI32<11, 0>, base: Reg) -> I { - i_type(offset.to_u(), base, width, dest, LOAD) -} - -pub const fn store(width: Funct3, src: Reg, offset: BitsI32<11, 0>, base: Reg) -> I { - s_type(src, base, width, offset.to_u(), STORE) -} - -pub const fn jal(dest: Reg, offset: BitsI32<20, 1>) -> I { - j_type(offset.to_u(), dest, JAL) -} -pub const fn jalr(dest: Reg, offset: BitsI32<11, 0>, base: Reg) -> I { - i_type(offset.to_u(), base, Bits32::new(0), dest, JALR) -} - -// pseudoinstructions that map to a single instruction - -pub const fn j(offset: BitsI32<20, 1>) -> I { - jal(zero, offset) -} -pub const fn ret() -> I { - jalr(zero, BitsI32::new(0), ra) -} diff --git a/src/parser/v3/lower/arch/riscv64.rs b/src/parser/v3/lower/arch/riscv64.rs index 2407d31..f4b4401 100644 --- a/src/parser/v3/lower/arch/riscv64.rs +++ b/src/parser/v3/lower/arch/riscv64.rs @@ -70,7 +70,7 @@ impl RV64Instruction { }; let load = |ctx: &mut FnLowerCtx<'_, '_>, width: Funct3| -> Option { let [dest, offset, base] = args else { - ctx.err("ld requires 3 arguments".to_string()); + ctx.err(format!("{opstr} requires 3 arguments")); return None; }; let dest = RegRef::from_arg(dest, ctx)?; @@ -84,7 +84,7 @@ impl RV64Instruction { }) }; Some(match opstr { - "ecall" => Self::Ecall, + "ecall" => Self::ECall, "li" => { let [dest, imm] = args else { ctx.err("li requires 2 arguments".to_string());