more asm refactor

This commit is contained in:
2025-03-23 15:05:28 -04:00
parent aa07ee638c
commit a5a5f64c49
4 changed files with 80 additions and 118 deletions

View File

@@ -5,59 +5,59 @@ use crate::{
use super::*; use super::*;
#[derive(Debug, Clone)] #[derive(Clone, Copy)]
pub enum LinkerInstruction { pub enum LinkerInstruction<R = Reg, S = Symbol> {
Op { Op {
op: Funct3, op: Funct3,
funct: Funct7, funct: Funct7,
dest: Reg, dest: R,
src1: Reg, src1: R,
src2: Reg, src2: R,
}, },
OpImm { OpImm {
op: Funct3, op: Funct3,
dest: Reg, dest: R,
src: Reg, src: R,
imm: i32, imm: i32,
}, },
OpImmF7 { OpImmF7 {
op: Funct3, op: Funct3,
funct: Funct7, funct: Funct7,
dest: Reg, dest: R,
src: Reg, src: R,
imm: i32, imm: i32,
}, },
Store { Store {
width: Funct3, width: Funct3,
src: Reg, src: R,
offset: i32, offset: i32,
base: Reg, base: R,
}, },
Load { Load {
width: Funct3, width: Funct3,
dest: Reg, dest: R,
offset: i32, offset: i32,
base: Reg, base: R,
}, },
Mv { Mv {
dest: Reg, dest: R,
src: Reg, src: R,
}, },
La { La {
dest: Reg, dest: R,
src: Symbol, src: S,
}, },
Jal { Jal {
dest: Reg, dest: R,
offset: i32, offset: i32,
}, },
Call(Symbol), Call(S),
J(Symbol), J(S),
Ret, Ret,
Ecall, Ecall,
Li { Li {
dest: Reg, dest: R,
imm: i64, imm: i32,
}, },
} }
@@ -133,7 +133,7 @@ impl Instr for LinkerInstruction {
} }
Self::Ret => ret(), Self::Ret => ret(),
Self::Ecall => ecall(), Self::Ecall => ecall(),
Self::Li { dest, imm } => addi(*dest, zero, BitsI32::new(*imm as i32)), Self::Li { dest, imm } => addi(*dest, zero, BitsI32::new(*imm)),
}; };
data.extend(last.to_le_bytes()); data.extend(last.to_le_bytes());
None None
@@ -166,3 +166,47 @@ impl LinkerInstruction {
} }
} }
} }
impl<R: std::fmt::Debug, S: std::fmt::Debug> std::fmt::Debug for LinkerInstruction<R, S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Ecall => write!(f, "ecall"),
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:?}"),
Self::Load {
width,
dest,
offset,
base,
} => write!(f, "l{} {dest:?}, {offset}({base:?})", width::str(*width)),
Self::Store {
width,
src,
offset,
base,
} => write!(f, "s{} {src:?}, {offset}({base:?})", width::str(*width)),
Self::Op {
op,
funct,
dest,
src1,
src2,
} => write!(f, "{} {dest:?}, {src1:?}, {src2:?}", opstr(*op, *funct)),
Self::OpImm { op, dest, src, imm } => {
write!(f, "{}i {dest:?}, {src:?}, {imm}", opstr(*op, op32i::FUNCT7))
}
Self::OpImmF7 {
op,
funct,
dest,
src,
imm,
} => write!(f, "{}i {dest:?}, {src:?}, {imm}", opstr(*op, *funct)),
Self::Jal { dest, offset } => write!(f, "jal {dest:?}, {offset:?}"),
Self::Call(s) => write!(f, "call {s:?}"),
Self::J(s) => write!(f, "j {s:?}"),
Self::Ret => write!(f, "ret"),
}
}
}

View File

@@ -195,6 +195,10 @@ pub fn compile(program: IRLProgram) -> (Vec<u8>, Option<Addr>) {
src: r(src), src: r(src),
imm: imm as i32, imm: imm as i32,
}), }),
AI::Ret => v.push(LI::Ret),
AI::Call(s) => todo!(),
AI::Jal { dest, offset } => todo!(),
AI::J(s) => todo!(),
} }
} }
} }

View File

@@ -1,53 +1,6 @@
use crate::{compiler::arch::riscv::*, ir::VarInst}; use crate::{compiler::arch::riscv::*, ir::VarInst};
#[derive(Copy, Clone)] pub type RV64Instruction = LinkerInstruction<RegRef, VarInst>;
pub enum RV64Instruction {
Ecall,
Li {
dest: RegRef,
imm: i64,
},
Mv {
dest: RegRef,
src: RegRef,
},
La {
dest: RegRef,
src: VarInst,
},
Load {
width: Funct3,
dest: RegRef,
offset: i64,
base: RegRef,
},
Store {
width: Funct3,
src: RegRef,
offset: i64,
base: RegRef,
},
Op {
op: Funct3,
funct: Funct7,
dest: RegRef,
src1: RegRef,
src2: RegRef,
},
OpImm {
op: Funct3,
dest: RegRef,
src: RegRef,
imm: i64,
},
OpImmF7 {
op: Funct3,
funct: Funct7,
dest: RegRef,
src: RegRef,
imm: i64,
},
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum RegRef { pub enum RegRef {
@@ -64,42 +17,3 @@ impl std::fmt::Debug for RegRef {
} }
} }
impl std::fmt::Debug for RV64Instruction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Ecall => write!(f, "ecall"),
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:?}"),
Self::Load {
width,
dest,
offset,
base,
} => write!(f, "l{} {dest:?}, {offset}({base:?})", width::str(*width)),
Self::Store {
width,
src,
offset,
base,
} => write!(f, "s{} {src:?}, {offset}({base:?})", width::str(*width)),
Self::Op {
op,
funct,
dest,
src1,
src2,
} => write!(f, "{} {dest:?}, {src1:?}, {src2:?}", opstr(*op, *funct)),
Self::OpImm { op, dest, src, imm } => {
write!(f, "{}i {dest:?}, {src:?}, {imm}", opstr(*op, op32i::FUNCT7))
}
Self::OpImmF7 {
op,
funct,
dest,
src,
imm,
} => write!(f, "{}i {dest:?}, {src:?}, {imm}", opstr(*op, *funct)),
}
}
}

View File

@@ -18,7 +18,7 @@ impl RV64Instruction {
}; };
let dest = RegRef::from_arg(dest, ctx)?; let dest = RegRef::from_arg(dest, ctx)?;
let src = RegRef::from_arg(src, ctx)?; let src = RegRef::from_arg(src, ctx)?;
let imm = i64_from_arg(imm, ctx)?; let imm = i32_from_arg(imm, ctx)?;
Some(Self::OpImm { op, dest, src, imm }) Some(Self::OpImm { op, dest, src, imm })
}; };
let op = |ctx: &mut FnLowerCtx<'_, '_>, op: Funct3, funct: Funct7| -> Option<Self> { let op = |ctx: &mut FnLowerCtx<'_, '_>, op: Funct3, funct: Funct7| -> Option<Self> {
@@ -44,7 +44,7 @@ impl RV64Instruction {
}; };
let dest = RegRef::from_arg(dest, ctx)?; let dest = RegRef::from_arg(dest, ctx)?;
let src = RegRef::from_arg(src, ctx)?; let src = RegRef::from_arg(src, ctx)?;
let imm = i64_from_arg(imm, ctx)?; let imm = i32_from_arg(imm, ctx)?;
Some(Self::OpImmF7 { Some(Self::OpImmF7 {
op, op,
funct, funct,
@@ -59,7 +59,7 @@ impl RV64Instruction {
return None; return None;
}; };
let src = RegRef::from_arg(src, ctx)?; let src = RegRef::from_arg(src, ctx)?;
let offset = i64_from_arg(offset, ctx)?; let offset = i32_from_arg(offset, ctx)?;
let base = RegRef::from_arg(base, ctx)?; let base = RegRef::from_arg(base, ctx)?;
Some(Self::Store { Some(Self::Store {
width, width,
@@ -74,7 +74,7 @@ impl RV64Instruction {
return None; return None;
}; };
let dest = RegRef::from_arg(dest, ctx)?; let dest = RegRef::from_arg(dest, ctx)?;
let offset = i64_from_arg(offset, ctx)?; let offset = i32_from_arg(offset, ctx)?;
let base = RegRef::from_arg(base, ctx)?; let base = RegRef::from_arg(base, ctx)?;
Some(Self::Load { Some(Self::Load {
width, width,
@@ -91,7 +91,7 @@ impl RV64Instruction {
return None; return None;
}; };
let dest = RegRef::from_arg(dest, ctx)?; let dest = RegRef::from_arg(dest, ctx)?;
let imm = i64_from_arg(imm, ctx)?; let imm = i32_from_arg(imm, ctx)?;
Self::Li { dest, imm } Self::Li { dest, imm }
} }
"la" => { "la" => {
@@ -199,13 +199,13 @@ impl Reg {
} }
} }
fn i64_from_arg(node: &Node<PAsmArg>, ctx: &mut FnLowerCtx) -> Option<i64> { fn i32_from_arg(node: &Node<PAsmArg>, ctx: &mut FnLowerCtx) -> Option<i32> {
let PAsmArg::Value(node) = node.inner.as_ref()? else { let PAsmArg::Value(node) = node.inner.as_ref()? else {
ctx.err_at(node.span, "Expected an i64, found reference".to_string()); ctx.err_at(node.span, "Expected an i32, found reference".to_string());
return None; return None;
}; };
let word = node.inner.as_ref()?; let word = node.inner.as_ref()?;
match word.parse::<i64>() { match word.parse::<i32>() {
Ok(x) => Some(x), Ok(x) => Some(x),
Err(_) => { Err(_) => {
ctx.err_at(node.span, format!("Expected an i64, found {}", word)); ctx.err_at(node.span, format!("Expected an i64, found {}", word));