use crate::{
- ConditionRegister, InstructionInput, InstructionOutput, InstructionResult, OverflowFlags,
+ ConditionRegister, InstructionInput, InstructionOutput, InstructionResult,
+ MissingInstructionInput, OverflowFlags,
};
+fn propagate_so(
+ mut overflow: OverflowFlags,
+ inputs: InstructionInput,
+) -> Result<OverflowFlags, MissingInstructionInput> {
+ if inputs.try_get_overflow()?.so {
+ overflow.so = true;
+ }
+ Ok(overflow)
+}
+
macro_rules! create_instr_variants_ov_cr {
($fn:ident, $fno:ident, $fn_:ident, $fno_:ident, $iwidth:ident) => {
- pub fn $fn(inputs: InstructionInput) -> InstructionResult {
+ pub fn $fn(mut inputs: InstructionInput) -> InstructionResult {
+ inputs.overflow = Some(OverflowFlags::default());
Ok(InstructionOutput {
overflow: None,
..$fno(inputs)?
pub fn $fn_(inputs: InstructionInput) -> InstructionResult {
let mut retval = $fno_(inputs)?;
let mut cr0 = retval.cr0.as_mut().expect("expected cr0 to be set");
- cr0.so = false;
+ cr0.so = inputs.try_get_overflow()?.so;
retval.overflow = None;
Ok(retval)
}
pub fn $fn_(inputs: InstructionInput) -> InstructionResult {
let mut retval = $fn(inputs)?;
let result = retval.rt.expect("expected rt to be set");
- let cr0 = ConditionRegister::from_signed_int(result as $iwidth, false);
+ let cr0 = ConditionRegister::from_signed_int(
+ result as $iwidth,
+ inputs.try_get_overflow()?.so,
+ );
retval.cr0 = Some(cr0);
Ok(retval)
}
let ov32 = (ra as i32).overflowing_add(rb as i32).1;
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags { so: ov, ov, ov32 }),
+ overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
..InstructionOutput::default()
})
}
let ov32 = (rb as i32).overflowing_sub(ra as i32).1;
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags { so: ov, ov, ov32 }),
+ overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
..InstructionOutput::default()
})
}
}
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}
}
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}
}
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}
}
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}
}
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}
}
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}
}
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}
}
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}
let overflow = result as i32 as i64 != result as i64;
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}
let overflow = ra.checked_mul(rb).is_none();
Ok(InstructionOutput {
rt: Some(result),
- overflow: Some(OverflowFlags::from_overflow(overflow)),
+ overflow: Some(propagate_so(
+ OverflowFlags::from_overflow(overflow),
+ inputs,
+ )?),
..InstructionOutput::default()
})
}