diff --git a/cranelift/filetests/filetests/runtests/pinned-reg.clif b/cranelift/filetests/filetests/runtests/pinned-reg.clif new file mode 100644 index 000000000000..1a4c141ca405 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/pinned-reg.clif @@ -0,0 +1,13 @@ +test interpret +set enable_pinned_reg +target x86_64 + +function %read_write(i64) -> i64 { +block0(v0: i64): + set_pinned_reg v0 + v1 = get_pinned_reg.i64 + return v1 +} +; run: %read_write(0) == 0 +; run: %read_write(-1) == -1 +; run: %read_write(0xDEADBEEF_C0FFEEEE) == 0xDEADBEEF_C0FFEEEE diff --git a/cranelift/interpreter/src/interpreter.rs b/cranelift/interpreter/src/interpreter.rs index f6e4f9f041b3..3d682799f4c1 100644 --- a/cranelift/interpreter/src/interpreter.rs +++ b/cranelift/interpreter/src/interpreter.rs @@ -201,6 +201,7 @@ pub struct InterpreterState<'a> { pub heaps: Vec, pub iflags: HashSet, pub fflags: HashSet, + pub pinned_reg: DataValue, } impl Default for InterpreterState<'_> { @@ -213,6 +214,7 @@ impl Default for InterpreterState<'_> { heaps: Vec::new(), iflags: HashSet::new(), fflags: HashSet::new(), + pinned_reg: DataValue::U64(0), } } } @@ -592,10 +594,18 @@ impl<'a> State<'a, DataValue> for InterpreterState<'a> { } } _ => unimplemented!(), - } + }; Ok(()) } + + fn get_pinned_reg(&self) -> DataValue { + self.pinned_reg.clone() + } + + fn set_pinned_reg(&mut self, v: DataValue) { + self.pinned_reg = v; + } } #[cfg(test)] diff --git a/cranelift/interpreter/src/state.rs b/cranelift/interpreter/src/state.rs index efc1842722b0..b45a3e039066 100644 --- a/cranelift/interpreter/src/state.rs +++ b/cranelift/interpreter/src/state.rs @@ -86,6 +86,11 @@ pub trait State<'a, V> { /// Checks if an address is valid and within a known region of memory fn validate_address(&self, address: &Address) -> Result<(), MemoryError>; + + /// Retrieves the current pinned reg value + fn get_pinned_reg(&self) -> V; + /// Sets a value for the pinned reg + fn set_pinned_reg(&mut self, v: V); } #[derive(Error, Debug)] @@ -187,4 +192,12 @@ where fn validate_address(&self, _addr: &Address) -> Result<(), MemoryError> { unimplemented!() } + + fn get_pinned_reg(&self) -> V { + unimplemented!() + } + + fn set_pinned_reg(&mut self, _v: V) { + unimplemented!() + } } diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index eaff61fd40b9..a578fdfe5f4d 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -407,8 +407,11 @@ where unreachable!() } } - Opcode::GetPinnedReg => unimplemented!("GetPinnedReg"), - Opcode::SetPinnedReg => unimplemented!("SetPinnedReg"), + Opcode::GetPinnedReg => assign(state.get_pinned_reg()), + Opcode::SetPinnedReg => { + state.set_pinned_reg(arg(0)?); + ControlFlow::Continue + } Opcode::TableAddr => { if let InstructionData::TableAddr { table, offset, .. } = inst { let table = &state.get_current_function().tables[table];