Skip to content

Commit

Permalink
Merge pull request #76 from Y-Nak/int-ptr-conversion
Browse files Browse the repository at this point in the history
Int ptr conversion
  • Loading branch information
Y-Nak authored Oct 16, 2024
2 parents 495e3f7 + 22720cc commit b29623d
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 60 deletions.
104 changes: 52 additions & 52 deletions crates/interpreter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub mod machine;
#[cfg(test)]
mod tests {
use machine::Machine;
use sonatina_ir::{module::FuncRef, Module};
use sonatina_ir::{module::FuncRef, Immediate, Module, Type};

use super::*;

Expand Down Expand Up @@ -232,68 +232,68 @@ mod tests {
assert_eq!(result.as_imm().unwrap().as_i256().trunc_to_i8(), -1);
}

// #[test]
// fn gep() {
// let input = "
// target = \"evm-ethereum-london\"

// type %s1 = {i32, i64, i1};

// func private %test() -> *i1 {
// block0:
// v0.*%s1 = alloca %s1;
// v1.*i1 = gep v0 2.i8;
// return v1;
// }
// ";

// let state = parse_module_make_state(input);
#[test]
fn gep() {
let input = "
target = \"evm-ethereum-london\"
// let elem_ptr = state.run();
type @s1 = {i32, i64, i1};
// assert_eq!(elem_ptr.into_usize(), 12usize);
// }
func private %test(v0.i256) -> *i1 {
block0:
v1.*@s1 = int_to_ptr v0 *@s1;
v2.*i1 = gep v1 0.i256 2.i256;
return v2;
}
";

// #[cfg(target_arch = "aarch64")]
// #[test]
// fn gep_ptr_ty() {
// let input = "
// target = \"evm-ethereum-london\"
let (mut machine, funcs) = setup(input);
let arg = Immediate::zero(Type::I256);
let result = machine.run(funcs[0], vec![arg.into()]);

// func private %test() -> **i32 {
// block0:
// v0.*[*i32; 3] = alloca [*i32; 3];
// v1.**i32 = gep v0 2.i8;
// return v1;
// }
// ";
assert_eq!(result.as_imm().unwrap().as_i256().trunc_to_i64(), 12);
}

// let state = parse_module_make_state(input);
#[cfg(target_arch = "aarch64")]
#[test]
fn gep_ptr_ty() {
let input = "
target = \"evm-ethereum-london\"
// let elem_ptr = state.run();
func private %test(v0.i256) -> **i32 {
block0:
v1.*[*i32; 3] = int_to_ptr v0 *[*i32; 3];
v2.**i32 = gep v1 0.i256 2.i256;
return v2;
}
";

// assert_eq!(elem_ptr.into_usize(), 16usize);
// }
let (mut machine, funcs) = setup(input);
let arg = Immediate::zero(Type::I256);
let result = machine.run(funcs[0], vec![arg.into()]);

// #[test]
// fn gep_nested_aggr_ty() {
// let input = "
// target = \"evm-ethereum-london\"
assert_eq!(result.as_imm().unwrap().as_i256().trunc_to_i64(), 64);
}

// type %s1 = {i32, [i16; 3], [i8; 2]};
#[test]
fn gep_nested_aggr_ty() {
let input = "
target = \"evm-ethereum-london\"
// func private %test() -> *i8 {
// block0:
// v0.*%s1 = alloca %s1;
// v1.*i8 = gep v0 2.i8 1.i8;
// return v1;
// }
// ";
type @s1 = {i32, [i16; 3], [i8; 2]};
// let state = parse_module_make_state(input);
func private %test(v0.i256) -> *i8 {
block0:
v1.*@s1 = int_to_ptr v0 *@s1;
v2.*i8 = gep v1 0.i256 2.i256 1.i256;
return v2;
}
";

// let elem_ptr = state.run();
let (mut machine, funcs) = setup(input);
let arg = Immediate::zero(Type::I256);
let result = machine.run(funcs[0], vec![arg.into()]);

// assert_eq!(elem_ptr.into_usize(), 11usize);
// }
assert_eq!(result.as_imm().unwrap().as_i256().trunc_to_i64(), 11);
}
}
16 changes: 16 additions & 0 deletions crates/ir/src/inst/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,19 @@ pub struct Bitcast {
ty: Type,
}
impl_inst_write!(Bitcast, (from: ValueId, ty: Type));

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Inst)]
pub struct IntToPtr {
#[inst(value)]
from: ValueId,
ty: Type,
}
impl_inst_write!(IntToPtr, (from: ValueId, ty: Type));

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Inst)]
pub struct PtrToInt {
#[inst(value)]
from: ValueId,
ty: Type,
}
impl_inst_write!(PtrToInt, (from: ValueId, ty: Type));
2 changes: 2 additions & 0 deletions crates/ir/src/inst/evm/inst_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pub struct EvmInstSet(
cast::Zext,
cast::Trunc,
cast::Bitcast,
cast::IntToPtr,
cast::PtrToInt,
cmp::Lt,
cmp::Gt,
cmp::Slt,
Expand Down
2 changes: 2 additions & 0 deletions crates/ir/src/inst/inst_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ define_inst_set_base! {
cast::Zext,
cast::Trunc,
cast::Bitcast,
cast::IntToPtr,
cast::PtrToInt,
data::Mload,
data::Mstore,
data::Gep,
Expand Down
40 changes: 38 additions & 2 deletions crates/ir/src/interpret/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ use crate::inst::cast::*;

impl Interpret for Sext {
fn interpret(&self, state: &mut dyn State) -> EvalValue {
state.set_action(Action::Continue);

let value = state.lookup_val(*self.from());
let ty = self.ty();
state.set_action(Action::Continue);

value.with_imm(|value| value.sext(*ty))
}
}

impl Interpret for Zext {
fn interpret(&self, state: &mut dyn State) -> EvalValue {
state.set_action(Action::Continue);

let value = state.lookup_val(*self.from());
let ty = self.ty();
state.set_action(Action::Continue);

value.with_imm(|value| value.zext(*ty))
}
Expand All @@ -30,3 +32,37 @@ impl Interpret for Trunc {
value.with_imm(|value| value.trunc(*ty))
}
}

impl Interpret for IntToPtr {
fn interpret(&self, state: &mut dyn State) -> EvalValue {
state.set_action(Action::Continue);
let value = state.lookup_val(*self.from());
let ty = self.ty();

value.with_imm(|value| {
let ptr_repr = state.dfg().ctx.type_layout.pointer_repl();
if *ty > ptr_repr {
value.trunc(ptr_repr)
} else {
value.zext(ptr_repr)
}
})
}
}

impl Interpret for PtrToInt {
fn interpret(&self, state: &mut dyn State) -> EvalValue {
state.set_action(Action::Continue);
let value = state.lookup_val(*self.from());
let ty = self.ty();

value.with_imm(|value| {
let ptr_repr = state.dfg().ctx.type_layout.pointer_repl();
if *ty > ptr_repr {
value.zext(*ty)
} else {
value.trunc(*ty)
}
})
}
}
2 changes: 1 addition & 1 deletion crates/ir/src/interpret/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl Interpret for Gep {

CompoundTypeData::Struct(s) => {
let mut local_offset = 0;
for i in 0..idx_value.saturating_sub(1) {
for i in 0..idx_value {
let field_ty = s.fields[i];
let size = state.dfg().ctx.size_of(field_ty);
let align = state.dfg().ctx.align_of(field_ty);
Expand Down
2 changes: 2 additions & 0 deletions crates/ir/src/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub trait Interpret {
inst::cast::Sext,
inst::cast::Zext,
inst::cast::Trunc,
inst::cast::IntToPtr,
inst::cast::PtrToInt,
inst::cmp::Lt,
inst::cmp::Gt,
inst::cmp::Slt,
Expand Down
13 changes: 9 additions & 4 deletions crates/ir/src/isa/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ struct EvmTypeLayout {}
impl TypeLayout for EvmTypeLayout {
fn size_of(&self, ty: crate::Type, ctx: &ModuleCtx) -> usize {
match ty {
Type::Unit => 0,
Type::I1 => 1,
Type::I8 => 1,
Type::I16 => 2,
Type::I32 => 4,
Type::I64 => 8,
Type::I128 => 16,
Type::I256 => 32,

Type::Compound(cmpd) => {
let cmpd_data = ctx.with_ty_store(|s| s.resolve_compound(cmpd).clone());
match cmpd_data {
Expand All @@ -60,10 +69,6 @@ impl TypeLayout for EvmTypeLayout {
}
}
}

Type::Unit => 0,

_ => 32,
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/ir/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl Immediate {
Self::I32(val) => (val as u32).into(),
Self::I64(val) => (val as u64).into(),
Self::I128(val) => (val as u128).into(),
Self::I256(_) => unreachable!(),
Self::I256(val) => val,
};

Self::from_i256(i256, ty)
Expand Down
2 changes: 2 additions & 0 deletions crates/parser/src/inst/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ super::impl_inst_build! {Sext, has_sext, (from: ValueId, ty: Type)}
super::impl_inst_build! {Zext, has_zext, (from: ValueId, ty: Type)}
super::impl_inst_build! {Trunc, has_trunc, (from: ValueId, ty: Type)}
super::impl_inst_build! {Bitcast, has_bitcast, (from: ValueId, ty: Type)}
super::impl_inst_build! {IntToPtr, has_int_to_ptr, (from: ValueId, ty: Type)}
super::impl_inst_build! {PtrToInt, has_ptr_to_int, (from: ValueId, ty: Type)}

0 comments on commit b29623d

Please sign in to comment.