emu: make $name optional in step!-internal calls
Gearing up to change modrm code to no longer push its directives onto the main processing stack. This also necessitates making the function's $form/width/tyargs-thingy a child of $name. It might be nice to revisit this at some point if we want to merge all the different form=word[0,1,2,3] arities together. I had hoped that FarPtr could become parameterized on its pointee width (u8 or u16) and that would obviate the need for turbofishing the op function directly. Unfortunately, the string operations need disambiguation regardless as they construct their pointers internally. But perhaps that could've been solved with some PhantomData. Regardless, this kind of approach becomes more difficult after this commit as the width is now tied to the function name.
This commit is contained in:
@@ -46,65 +46,72 @@ pub enum RepPrefix {
|
||||
|
||||
macro_rules! step {
|
||||
// Base case: all args processed and ready to call op
|
||||
(@code $(form=($($tyargs:tt),*),)? ( $($done:tt)* ),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal,
|
||||
(@code ( $($done:tt)* ),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt,
|
||||
$(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal,
|
||||
()) => {
|
||||
ops::$name$(::<$($tyargs),*>)?($($done),*);
|
||||
$(ops::$name$(::<$($tyargs),*>)?)?($($done),*);
|
||||
};
|
||||
|
||||
// Inductive case: decode next arg to be placed in list
|
||||
(@code $(form=$form:tt,)? ( $($done:tt)* ),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal,
|
||||
(@code ( $($done:tt)* ),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt,
|
||||
$(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal,
|
||||
($next:ident $(= $nextrhs:tt)? $($rest:ident $(= $restrhs:tt)?)*)) => {
|
||||
step!(@$next$(= $nextrhs)?
|
||||
// "cookie" tt to be passed thru to @arg so we have all the args for the recursive step
|
||||
( $(form=$form,)? ($($done)*), $cpu, $bus, $prefix, $modrm, $name, $cycles, ($($rest $(= $restrhs)?)*) ),
|
||||
( ($($done)*), $cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $cycles, ($($rest $(= $restrhs)?)*) ),
|
||||
$cpu, $bus, $prefix, $modrm)
|
||||
};
|
||||
|
||||
// accept an argument from a decoder and recur to look for next arg
|
||||
(@arg ( $(form=$form:tt,)? ($($done:tt)*),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal,
|
||||
(@arg ( ($($done:tt)*),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt,
|
||||
$(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal,
|
||||
$rest:tt )
|
||||
$(, $arg:expr)?) => {
|
||||
step!(@code $(form=$form,)? ($($done)* $($arg)?), $cpu, $bus, $prefix, $modrm, $name, $cycles, $rest)
|
||||
step!(@code ($($done)* $($arg)?), $cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $cycles, $rest)
|
||||
};
|
||||
|
||||
// decoder deferring to sub-decoders, push them onto the decoder stack to process next
|
||||
(@push ( $(form=$form:tt,)? ($($done:tt)*),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, ( $($rest:tt)* ) ),
|
||||
(@push ( ($($done:tt)*),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt,
|
||||
$(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal,
|
||||
( $($rest:tt)* ) ),
|
||||
( $($args:tt)* )) => {
|
||||
step!(@code $(form=$form,)? ($($done)*), $cpu, $bus, $prefix, $modrm, $name, $cycles, ( $($args)* $($rest)* ))
|
||||
step!(@code ($($done)*), $cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $cycles, ( $($args)* $($rest)* ))
|
||||
};
|
||||
|
||||
// Set the type arguments for operations that cannot infer width
|
||||
(@form ( $done:tt,
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal,
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, name=$name:ident, $cycles:literal,
|
||||
$rest:tt ),
|
||||
form=$form:tt) => {
|
||||
step!(@code form=$form, $done, $cpu, $bus, $prefix, $modrm, $name, $cycles, $rest)
|
||||
form=<$($tyargs:tt),*> ) => {
|
||||
step!(@code $done, $cpu, $bus, $prefix, $modrm, name=$name<$($tyargs),*>, $cycles, $rest)
|
||||
};
|
||||
|
||||
// Adds tokens to the last argument. Used by @convert to append ".into()" to the last arg
|
||||
(@append-to-last ($($done:tt)*)
|
||||
( $(form=$form:tt,)? ($last:tt),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal,
|
||||
( ($last:tt),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt,
|
||||
$(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal,
|
||||
$rest:tt ) { $($conv:tt)+ } ) => {
|
||||
step!(@code $(form=$form,)? ($($done)* ($last$($conv)+)),
|
||||
$cpu, $bus, $prefix, $modrm, $name, $cycles,
|
||||
step!(@code ($($done)* ($last$($conv)+)),
|
||||
$cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $cycles,
|
||||
$rest )
|
||||
};
|
||||
|
||||
// Recursive case for @append-to-last, walks through already
|
||||
// processed args to find the last one for appending
|
||||
(@append-to-last ($($done:tt)*)
|
||||
( $(form=$form:tt,)? ($next:tt $($restdone:tt)+),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal,
|
||||
( ($next:tt $($restdone:tt)+),
|
||||
$cpu:expr, $bus:expr, $prefix:tt, $modrm:tt,
|
||||
$(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal,
|
||||
$rest:tt ) { $($conv:tt)+ } ) => {
|
||||
step!(@append-to-last ($($done)* $next)
|
||||
( $(form=$form,)? ($($restdone)+),
|
||||
$cpu, $bus, $prefix, $modrm, $name, $cycles,
|
||||
$rest ) { $($conv)+ } )
|
||||
( ($($restdone)+),
|
||||
$cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $cycles,
|
||||
$rest ) { $($conv)+ } )
|
||||
};
|
||||
|
||||
// === OP DIRECTIVES ===
|
||||
@@ -179,27 +186,27 @@ macro_rules! step {
|
||||
};
|
||||
|
||||
(@form=byte0 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => {
|
||||
step!(@form $cookie, form=(u8))
|
||||
step!(@form $cookie, form=<u8>)
|
||||
};
|
||||
|
||||
(@form=byte1 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => {
|
||||
step!(@form $cookie, form=(u8, _))
|
||||
step!(@form $cookie, form=<u8, _>)
|
||||
};
|
||||
|
||||
(@form=byte3 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => {
|
||||
step!(@form $cookie, form=(u8, _, _, _))
|
||||
step!(@form $cookie, form=<u8, _, _, _>)
|
||||
};
|
||||
|
||||
(@form=word0 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => {
|
||||
step!(@form $cookie, form=(u16))
|
||||
step!(@form $cookie, form=<u16>)
|
||||
};
|
||||
|
||||
(@form=word1 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => {
|
||||
step!(@form $cookie, form=(u16, _))
|
||||
step!(@form $cookie, form=<u16, _>)
|
||||
};
|
||||
|
||||
(@form=word3 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => {
|
||||
step!(@form $cookie, form=(u16, _, _, _))
|
||||
step!(@form $cookie, form=<u16, _, _, _>)
|
||||
};
|
||||
|
||||
(@mem $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => {
|
||||
@@ -347,7 +354,7 @@ macro_rules! step {
|
||||
$name:ident[$($args:ident $(= $argrhs:tt)?),*] / $cycles:literal),*$(,)? } ) => { {
|
||||
let subcode = $modrm_val & 0x38;
|
||||
match subcode {
|
||||
$( $subcode => step!(@code (), $cpu, $bus, $prefix, ($modrm_val, $modrm, $modrm16, $modrm8), $name, $cycles, ($($args $(= $argrhs)?)*)) ),*,
|
||||
$( $subcode => step!(@code (), $cpu, $bus, $prefix, ($modrm_val, $modrm, $modrm16, $modrm8), name=$name, $cycles, ($($args $(= $argrhs)?)*)) ),*,
|
||||
_ => unimplemented!("opcode: {:02X} {:02X}({:02X})\ncpu: {:#X?}", $code, $modrm_val, subcode, $cpu)
|
||||
} }
|
||||
};
|
||||
@@ -380,7 +387,7 @@ macro_rules! step {
|
||||
$( $( $code => {
|
||||
$( let $ext = (); /* No-op just to trigger expansion. */
|
||||
modrm_val = i8088::next_ip($cpu.cs.get(), &mut $cpu.ip, $bus); )?
|
||||
step!(@code (), $cpu, $bus, (segment, repeat, 'prefix_loop), (modrm_val, $modrm, $modrm16, $modrm8), $name, $cycles, ($($args $(= $argrhs)?)*))
|
||||
step!(@code (), $cpu, $bus, (segment, repeat, 'prefix_loop), (modrm_val, $modrm, $modrm16, $modrm8), name=$name, $cycles, ($($args $(= $argrhs)?)*))
|
||||
}
|
||||
)?
|
||||
$( $code => {
|
||||
|
||||
@@ -216,6 +216,7 @@ impl<'a> From<FarPtr<'_>> for DynLValue<'a> {
|
||||
DynLValue::FarPtr { segment: farptr.segment, offset: farptr.offset }
|
||||
}
|
||||
}
|
||||
|
||||
impl<LVal: LValue<T>, T> LValue<T> for &mut LVal {
|
||||
fn write(&mut self, val: T) {
|
||||
(**self).write(val);
|
||||
|
||||
Reference in New Issue
Block a user