Open fitzgen opened 3 weeks ago
cc @fitzgen
.github/subscribe-to-label.json
configuration file.
[Learn more.](https://github.com/bytecodealliance/subscribe-to-label-action)
define_opcode_handler! { fn xadd32( state: &mut MachineState, mut pc: UnsafeBytecodeStream, ) { // The
decode
module will need to be extended with methods to decode // an instructions immediates and operands, assuming that the associated // opcode has already been deecoded. let BinaryOperands { dst, src1, src2 } = decode::xadd32_imms_and_operands(&mut pc).unwrap();let a = state[src1].get_i32(); let b = state[src[src2]].get_i32(); state[dst].set_i32(a.wrapping_add(b)); Ok(pc) }
}
Why is a separate decoder function for the arguments needed? Why can't the existing decoder functions be used?
Oh and how can we verify that the tailcall optimization does indeed result in the desired assembly (ie each opcode handler does an indirect branch to the next handler, rather than a branch back to the top of the loop)? Copy/pasting the code into Compiler Explorer and looking at the output is doable, but not automatable.
For the verification, I think that's a property of the become
keyword and the compiler implementation? There's no actual loop in the source itself and become
is defined as always performing a tail call, so pending compiler bugs I think we can probably skip the automated verification and just spot-check some disassembly of profiles perhaps to confirm it's happening?
Why is a separate decoder function for the arguments needed? Why can't the existing decoder functions be used?
Just so that we don't have to manually remember "xadd32
takes BinaryOperands<XReg>
as its only operands and no immediates" and can have that stuff stay in sync with the instruction definition by construction. Especially if/when we tweak an instruction's definition so that the compiler tells us all the places we need to update, rather than trying to remember and hoping we got all the right places.
I fully expect these would be macro-generated like most stuff in this crate and defer to the underlying Decode
implementations.
Does that make sense?
We should rewrite the core of the interpreter and its main loop such that we can easily flip a cargo feature on to start using nightly Rust's
feature(explicit_tail_calls)
.The way I am imagining this would be done (warning: super rough ideas incoming) is something like this:
cc @Kmeakin, since you've been doing some Pulley stuff