arch: decouple from IR

This commit is contained in:
Igor kehrazy 2026-04-07 14:30:55 +03:00
parent fa19fab985
commit 866328ad54
6 changed files with 154 additions and 795 deletions

View file

@ -4,14 +4,10 @@ pub mod arm;
use crate::{
flow::FlowInfo,
ir::{Block, FrontendBuilder},
ir::Block,
};
/// Flat generic register metadata.
///
/// This type intentionally stays small.
/// Architecture-specific aliasing or overlap semantics belong in the concrete
/// architecture module, not here.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RegisterDesc<R> {
/// Architecture-defined register identity.
@ -24,7 +20,7 @@ pub struct RegisterDesc<R> {
pub bits: u16,
}
/// Stable architecture protocol.
/// Pure ISA protocol: decoding, flow analysis, and disassembly.
pub trait Arch {
/// Architecture execution mode.
type Mode: Copy + Eq;
@ -38,9 +34,6 @@ pub trait Arch {
/// Decode-time error.
type DecodeError;
/// Architecture-specific disassembly output.
type Disasm;
/// Stable architecture name.
fn name(&self) -> &'static str;
@ -66,18 +59,16 @@ pub trait Arch {
/// Return instruction-level control-flow facts for one decoded instruction.
fn flow_info(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> FlowInfo;
/// Render one decoded instruction as disassembly.
fn disasm(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> Self::Disasm;
/// Render one decoded instruction as a disassembly string.
fn disasm(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> String;
}
/// Translation-session knowledge available during lifting.
pub trait LiftEnv {
/// Returns the IR block associated with a statically known target address,
/// if the current translation session has created one.
/// Returns the IR block associated with a statically known target address.
fn block_for_target(&self, addr: u64) -> Option<Block>;
/// Returns the fallthrough block for the current instruction, if one exists
/// in the current translation session.
/// Returns the fallthrough block for the current instruction, if one exists.
fn fallthrough_block(&self) -> Option<Block>;
}
@ -87,12 +78,15 @@ pub trait LiftArch: Arch {
type LiftError;
/// Per-lift mutable context.
///
/// This is where the large mutable lifting state belongs.
type LiftCtx<'a>
type LiftCtx<'ir, 'fb>
where
Self: 'a;
Self: 'ir,
'ir: 'fb;
/// Lift one decoded instruction into Slonik IR.
fn lift(&self, cx: &mut Self::LiftCtx<'_>, inst: &Self::Inst) -> Result<(), Self::LiftError>;
fn lift(
&self,
cx: &mut Self::LiftCtx<'_, '_>,
inst: &Self::Inst,
) -> Result<(), Self::LiftError>;
}

File diff suppressed because it is too large Load diff

View file

@ -3,8 +3,7 @@
use cranelift_entity::{EntityRef, ListPool, PrimaryMap};
use crate::ir::{
Block, BlockCall, BlockData, ParamList, Stmt, StmtData, StmtList, Type, Value, ValueData,
ValueDef, ValueList,
Block, BlockCall, BlockData, Stmt, StmtData, Type, Value, ValueData, ValueDef, ValueList,
};
/// A normalized SSA body.

View file

@ -2,7 +2,7 @@
use core::fmt;
use crate::ir::{Block, Stmt, Type, Value};
use crate::ir::{Block, Stmt, Type};
/// Memory access width in bytes.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]

View file

@ -4,9 +4,7 @@
//! block. This ensures memory order is always explicit in the statement stream
//! rather than floating in a sea of pure expressions.
use crate::ir::{
BinaryOp, Block, CastOp, FloatCC, IntCC, MemSize, Stmt, UnaryOp, Value,
};
use crate::ir::{BinaryOp, Block, CastOp, FloatCC, IntCC, MemSize, UnaryOp, Value};
use cranelift_entity::EntityList;
/// A compact list of SSA values.

View file

@ -9,8 +9,6 @@ use clap::{
styling::{AnsiColor, Effects},
},
};
use cranelift_entity::EntityRef;
use crate::{
arch::{
Arch, LiftArch,
@ -42,7 +40,6 @@ fn main() {
0x1E, 0xFF, 0x2F, 0xE1, // bx lr
];
let arm = crate::arch::arm::Arm::default();
let mut body = crate::ir::Body::new();
let mut fb_ctx = crate::ir::FrontendBuilderContext::new();
let env = DummyEnv;
@ -56,25 +53,12 @@ fn main() {
let mut pc = 0x1000u64;
let mut rest = bytes;
let mut cx = crate::arch::arm::ArmLiftCtx::new(
&arm,
&env,
&mut fb,
pc,
crate::arch::arm::ArmMode::Arm,
);
let mut cx = ArmLiftCtx::new(&arm, &env, &mut fb, pc, ArmMode::Arm);
while !rest.is_empty() {
let (len, inst) = arm.decode(rest, crate::arch::arm::ArmMode::Arm).unwrap();
println!(
"{:#x}: {}",
pc,
arm.disasm(&inst, pc, crate::arch::arm::ArmMode::Arm)
);
println!(
" flow: {:?}",
arm.flow_info(&inst, pc, crate::arch::arm::ArmMode::Arm)
);
let (len, inst) = arm.decode(rest, ArmMode::Arm).unwrap();
println!("{:#x}: {}", pc, arm.disasm(&inst, pc, ArmMode::Arm));
println!(" flow: {:?}", arm.flow_info(&inst, pc, ArmMode::Arm));
cx.pc = pc;
arm.lift(&mut cx, &inst).unwrap();