more asm cleanup
This commit is contained in:
@@ -54,7 +54,8 @@ pub enum LinkerInstruction<R = Reg, S = Symbol> {
|
|||||||
Call(S),
|
Call(S),
|
||||||
J(S),
|
J(S),
|
||||||
Ret,
|
Ret,
|
||||||
Ecall,
|
ECall,
|
||||||
|
EBreak,
|
||||||
Li {
|
Li {
|
||||||
dest: R,
|
dest: R,
|
||||||
imm: i32,
|
imm: i32,
|
||||||
@@ -132,7 +133,8 @@ impl Instr for LinkerInstruction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Ret => ret(),
|
Self::Ret => ret(),
|
||||||
Self::Ecall => ecall(),
|
Self::ECall => ecall(),
|
||||||
|
Self::EBreak => ebreak(),
|
||||||
Self::Li { dest, imm } => addi(*dest, zero, BitsI32::new(*imm)),
|
Self::Li { dest, imm } => addi(*dest, zero, BitsI32::new(*imm)),
|
||||||
};
|
};
|
||||||
data.extend(last.to_le_bytes());
|
data.extend(last.to_le_bytes());
|
||||||
@@ -170,7 +172,8 @@ impl LinkerInstruction {
|
|||||||
impl<R: std::fmt::Debug, S: std::fmt::Debug> std::fmt::Debug for LinkerInstruction<R, S> {
|
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 {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
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::Li { dest, imm } => write!(f, "li {dest:?}, {imm:?}"),
|
||||||
Self::Mv { dest, src } => write!(f, "mv {dest:?}, {src:?}"),
|
Self::Mv { dest, src } => write!(f, "mv {dest:?}, {src:?}"),
|
||||||
Self::La { dest, src } => write!(f, "la {dest:?}, {src:?}"),
|
Self::La { dest, src } => write!(f, "la {dest:?}, {src:?}"),
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ pub fn compile(program: IRLProgram) -> (Vec<u8>, Option<Addr>) {
|
|||||||
}
|
}
|
||||||
for i in instructions {
|
for i in instructions {
|
||||||
match *i {
|
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::Li { dest, imm } => v.push(LI::Li { dest: r(dest), imm }),
|
||||||
AI::Mv { dest, src } => v.push(LI::Mv {
|
AI::Mv { dest, src } => v.push(LI::Mv {
|
||||||
dest: r(dest),
|
dest: r(dest),
|
||||||
@@ -149,7 +150,7 @@ pub fn compile(program: IRLProgram) -> (Vec<u8>, Option<Addr>) {
|
|||||||
} => v.push(LI::Load {
|
} => v.push(LI::Load {
|
||||||
width,
|
width,
|
||||||
dest: r(dest),
|
dest: r(dest),
|
||||||
offset: offset as i32,
|
offset,
|
||||||
base: r(base),
|
base: r(base),
|
||||||
}),
|
}),
|
||||||
AI::Store {
|
AI::Store {
|
||||||
@@ -160,7 +161,7 @@ pub fn compile(program: IRLProgram) -> (Vec<u8>, Option<Addr>) {
|
|||||||
} => v.push(LI::Store {
|
} => v.push(LI::Store {
|
||||||
width,
|
width,
|
||||||
src: r(src),
|
src: r(src),
|
||||||
offset: offset as i32,
|
offset,
|
||||||
base: r(base),
|
base: r(base),
|
||||||
}),
|
}),
|
||||||
AI::Op {
|
AI::Op {
|
||||||
@@ -180,7 +181,7 @@ pub fn compile(program: IRLProgram) -> (Vec<u8>, Option<Addr>) {
|
|||||||
op,
|
op,
|
||||||
dest: r(dest),
|
dest: r(dest),
|
||||||
src: r(src),
|
src: r(src),
|
||||||
imm: imm as i32,
|
imm,
|
||||||
}),
|
}),
|
||||||
AI::OpImmF7 {
|
AI::OpImmF7 {
|
||||||
op,
|
op,
|
||||||
@@ -193,7 +194,7 @@ pub fn compile(program: IRLProgram) -> (Vec<u8>, Option<Addr>) {
|
|||||||
funct,
|
funct,
|
||||||
dest: r(dest),
|
dest: r(dest),
|
||||||
src: r(src),
|
src: r(src),
|
||||||
imm: imm as i32,
|
imm,
|
||||||
}),
|
}),
|
||||||
AI::Ret => v.push(LI::Ret),
|
AI::Ret => v.push(LI::Ret),
|
||||||
AI::Call(s) => todo!(),
|
AI::Call(s) => todo!(),
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ use crate::{
|
|||||||
|
|
||||||
pub struct RawInstruction(u32);
|
pub struct RawInstruction(u32);
|
||||||
|
|
||||||
use RawInstruction as I;
|
|
||||||
|
|
||||||
impl RawInstruction {
|
impl RawInstruction {
|
||||||
pub fn to_le_bytes(&self) -> impl IntoIterator<Item = u8> {
|
pub fn to_le_bytes(&self) -> impl IntoIterator<Item = u8> {
|
||||||
self.0.to_le_bytes().into_iter()
|
self.0.to_le_bytes().into_iter()
|
||||||
@@ -28,6 +26,8 @@ pub const JALR: u32 = 0b1100111;
|
|||||||
pub type Funct3 = Bits32<2, 0>;
|
pub type Funct3 = Bits32<2, 0>;
|
||||||
pub type Funct7 = Bits32<6, 0>;
|
pub type Funct7 = Bits32<6, 0>;
|
||||||
|
|
||||||
|
use RawInstruction as I;
|
||||||
|
|
||||||
pub const fn r_type(
|
pub const fn r_type(
|
||||||
funct7: Bits32<6, 0>,
|
funct7: Bits32<6, 0>,
|
||||||
rs2: Reg,
|
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 {
|
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 {
|
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 {
|
pub fn opif7(op: Funct3, funct: Funct7, dest: Reg, src: Reg, imm: BitsI32<4, 0>) -> I {
|
||||||
i_type(
|
i_type(
|
||||||
Bits32::new(imm.to_u().val() + (funct.val() << 5)),
|
Bits32::new(imm.to_u().val() + (funct.val() << 5)),
|
||||||
src,
|
src,
|
||||||
op.into(),
|
op,
|
||||||
dest,
|
dest,
|
||||||
IMM_OP,
|
IMM_OP,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
mod base;
|
mod base;
|
||||||
mod rv32i;
|
mod rv32i;
|
||||||
mod rv32m;
|
mod rv32m;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{compiler::arch::riscv::Reg, util::Bits32};
|
use crate::{compiler::arch::riscv::Reg, util::Bits32};
|
||||||
|
|
||||||
use super::{opr, Funct3, Funct7, RawInstruction};
|
use super::*;
|
||||||
|
|
||||||
pub mod op32i {
|
pub mod op32i {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -63,6 +63,34 @@ pub mod width {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opr32i(op: Funct3, dest: Reg, src1: Reg, src2: Reg) -> RawInstruction {
|
pub const fn ecall() -> RawInstruction {
|
||||||
opr(op, Bits32::new(0), dest, src1, src2)
|
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
mod asm;
|
mod asm;
|
||||||
mod compile;
|
mod compile;
|
||||||
mod reg;
|
mod reg;
|
||||||
mod single;
|
|
||||||
mod instr;
|
mod instr;
|
||||||
|
|
||||||
use crate::util::BitsI32;
|
use crate::util::BitsI32;
|
||||||
use single::*;
|
|
||||||
|
|
||||||
pub use asm::*;
|
pub use asm::*;
|
||||||
pub use compile::*;
|
pub use compile::*;
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -70,7 +70,7 @@ impl RV64Instruction {
|
|||||||
};
|
};
|
||||||
let load = |ctx: &mut FnLowerCtx<'_, '_>, width: Funct3| -> Option<Self> {
|
let load = |ctx: &mut FnLowerCtx<'_, '_>, width: Funct3| -> Option<Self> {
|
||||||
let [dest, offset, base] = args else {
|
let [dest, offset, base] = args else {
|
||||||
ctx.err("ld requires 3 arguments".to_string());
|
ctx.err(format!("{opstr} requires 3 arguments"));
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let dest = RegRef::from_arg(dest, ctx)?;
|
let dest = RegRef::from_arg(dest, ctx)?;
|
||||||
@@ -84,7 +84,7 @@ impl RV64Instruction {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
Some(match opstr {
|
Some(match opstr {
|
||||||
"ecall" => Self::Ecall,
|
"ecall" => Self::ECall,
|
||||||
"li" => {
|
"li" => {
|
||||||
let [dest, imm] = args else {
|
let [dest, imm] = args else {
|
||||||
ctx.err("li requires 2 arguments".to_string());
|
ctx.err("li requires 2 arguments".to_string());
|
||||||
|
|||||||
Reference in New Issue
Block a user