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::{ use crate::{
flow::FlowInfo, flow::FlowInfo,
ir::{Block, FrontendBuilder}, ir::Block,
}; };
/// Flat generic register metadata. /// 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)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RegisterDesc<R> { pub struct RegisterDesc<R> {
/// Architecture-defined register identity. /// Architecture-defined register identity.
@ -24,7 +20,7 @@ pub struct RegisterDesc<R> {
pub bits: u16, pub bits: u16,
} }
/// Stable architecture protocol. /// Pure ISA protocol: decoding, flow analysis, and disassembly.
pub trait Arch { pub trait Arch {
/// Architecture execution mode. /// Architecture execution mode.
type Mode: Copy + Eq; type Mode: Copy + Eq;
@ -38,9 +34,6 @@ pub trait Arch {
/// Decode-time error. /// Decode-time error.
type DecodeError; type DecodeError;
/// Architecture-specific disassembly output.
type Disasm;
/// Stable architecture name. /// Stable architecture name.
fn name(&self) -> &'static str; fn name(&self) -> &'static str;
@ -66,18 +59,16 @@ pub trait Arch {
/// Return instruction-level control-flow facts for one decoded instruction. /// Return instruction-level control-flow facts for one decoded instruction.
fn flow_info(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> FlowInfo; fn flow_info(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> FlowInfo;
/// Render one decoded instruction as disassembly. /// Render one decoded instruction as a disassembly string.
fn disasm(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> Self::Disasm; fn disasm(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> String;
} }
/// Translation-session knowledge available during lifting. /// Translation-session knowledge available during lifting.
pub trait LiftEnv { pub trait LiftEnv {
/// Returns the IR block associated with a statically known target address, /// Returns the IR block associated with a statically known target address.
/// if the current translation session has created one.
fn block_for_target(&self, addr: u64) -> Option<Block>; fn block_for_target(&self, addr: u64) -> Option<Block>;
/// Returns the fallthrough block for the current instruction, if one exists /// Returns the fallthrough block for the current instruction, if one exists.
/// in the current translation session.
fn fallthrough_block(&self) -> Option<Block>; fn fallthrough_block(&self) -> Option<Block>;
} }
@ -87,12 +78,15 @@ pub trait LiftArch: Arch {
type LiftError; type LiftError;
/// Per-lift mutable context. /// Per-lift mutable context.
/// type LiftCtx<'ir, 'fb>
/// This is where the large mutable lifting state belongs.
type LiftCtx<'a>
where where
Self: 'a; Self: 'ir,
'ir: 'fb;
/// Lift one decoded instruction into Slonik IR. /// 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 cranelift_entity::{EntityRef, ListPool, PrimaryMap};
use crate::ir::{ use crate::ir::{
Block, BlockCall, BlockData, ParamList, Stmt, StmtData, StmtList, Type, Value, ValueData, Block, BlockCall, BlockData, Stmt, StmtData, Type, Value, ValueData, ValueDef, ValueList,
ValueDef, ValueList,
}; };
/// A normalized SSA body. /// A normalized SSA body.

View file

@ -2,7 +2,7 @@
use core::fmt; use core::fmt;
use crate::ir::{Block, Stmt, Type, Value}; use crate::ir::{Block, Stmt, Type};
/// Memory access width in bytes. /// Memory access width in bytes.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[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 //! block. This ensures memory order is always explicit in the statement stream
//! rather than floating in a sea of pure expressions. //! rather than floating in a sea of pure expressions.
use crate::ir::{ use crate::ir::{BinaryOp, Block, CastOp, FloatCC, IntCC, MemSize, UnaryOp, Value};
BinaryOp, Block, CastOp, FloatCC, IntCC, MemSize, Stmt, UnaryOp, Value,
};
use cranelift_entity::EntityList; use cranelift_entity::EntityList;
/// A compact list of SSA values. /// A compact list of SSA values.

View file

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