create_instr_variants_ov_cr!(subfe, subfeo, subfe_, subfeo_, i64);
pub fn subfeo(inputs: InstructionInput) -> InstructionResult {
- let ra = inputs.try_get_ra()?;
- let rb = inputs.try_get_rb()?;
+ let ra: u64 = inputs.try_get_ra()?;
+ let rb: u64 = inputs.try_get_rb()?;
+ let carry_in = inputs.try_get_carry()?.ca;
+ let not_ra = !ra;
+ let result_i128 = not_ra as i64 as i128 + rb as i64 as i128 + carry_in as i128;
+ let result_u128 = not_ra as u128 + rb as u128 + carry_in as u128;
+ let result32_i128 = not_ra as i32 as i128 + rb as i32 as i128 + carry_in as i128;
+ let result32_u128 = not_ra as u32 as u128 + rb as u32 as u128 + carry_in as u128;
+ let result = result_u128 as u64;
+ let ov = i64::try_from(result_i128).is_err();
+ let ov32 = i32::try_from(result32_i128).is_err();
+ let ca = u64::try_from(result_u128).is_err();
+ let ca32 = u32::try_from(result32_u128).is_err();
+ Ok(InstructionOutput {
+ rt: Some(result),
+ overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
+ carry: Some(CarryFlags { ca, ca32 }),
+ ..InstructionOutput::default()
+ })
+}
+
+create_instr_variants_ov_cr!(addme, addmeo, addme_, addmeo_, i64);
+
+pub fn addmeo(inputs: InstructionInput) -> InstructionResult {
+ let ra: u64 = inputs.try_get_ra()?;
+ let rb: u64 = !0;
+ let carry_in = inputs.try_get_carry()?.ca;
+ let result_i128 = ra as i64 as i128 + rb as i64 as i128 + carry_in as i128;
+ let result_u128 = ra as u128 + rb as u128 + carry_in as u128;
+ let result32_i128 = ra as i32 as i128 + rb as i32 as i128 + carry_in as i128;
+ let result32_u128 = ra as u32 as u128 + rb as u32 as u128 + carry_in as u128;
+ let result = result_u128 as u64;
+ let ov = i64::try_from(result_i128).is_err();
+ let ov32 = i32::try_from(result32_i128).is_err();
+ let ca = u64::try_from(result_u128).is_err();
+ let ca32 = u32::try_from(result32_u128).is_err();
+ Ok(InstructionOutput {
+ rt: Some(result),
+ overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
+ carry: Some(CarryFlags { ca, ca32 }),
+ ..InstructionOutput::default()
+ })
+}
+
+create_instr_variants_ov_cr!(subfme, subfmeo, subfme_, subfmeo_, i64);
+
+pub fn subfmeo(inputs: InstructionInput) -> InstructionResult {
+ let ra: u64 = inputs.try_get_ra()?;
+ let rb: u64 = !0;
let carry_in = inputs.try_get_carry()?.ca;
let not_ra = !ra;
let result_i128 = not_ra as i64 as i128 + rb as i64 as i128 + carry_in as i128;
})
}
+create_instr_variants_ov_cr!(addze, addzeo, addze_, addzeo_, i64);
+
+pub fn addzeo(inputs: InstructionInput) -> InstructionResult {
+ let ra: u64 = inputs.try_get_ra()?;
+ let carry_in = inputs.try_get_carry()?.ca;
+ let result_i128 = ra as i64 as i128 + carry_in as i128;
+ let result_u128 = ra as u128 + carry_in as u128;
+ let result32_i128 = ra as i32 as i128 + carry_in as i128;
+ let result32_u128 = ra as u32 as u128 + carry_in as u128;
+ let result = result_u128 as u64;
+ let ov = i64::try_from(result_i128).is_err();
+ let ov32 = i32::try_from(result32_i128).is_err();
+ let ca = u64::try_from(result_u128).is_err();
+ let ca32 = u32::try_from(result32_u128).is_err();
+ Ok(InstructionOutput {
+ rt: Some(result),
+ overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
+ carry: Some(CarryFlags { ca, ca32 }),
+ ..InstructionOutput::default()
+ })
+}
+
+create_instr_variants_ov_cr!(subfze, subfzeo, subfze_, subfzeo_, i64);
+
+pub fn subfzeo(inputs: InstructionInput) -> InstructionResult {
+ let ra: u64 = inputs.try_get_ra()?;
+ let carry_in = inputs.try_get_carry()?.ca;
+ let not_ra = !ra;
+ let result_i128 = not_ra as i64 as i128 + carry_in as i128;
+ let result_u128 = not_ra as u128 + carry_in as u128;
+ let result32_i128 = not_ra as i32 as i128 + carry_in as i128;
+ let result32_u128 = not_ra as u32 as u128 + carry_in as u128;
+ let result = result_u128 as u64;
+ let ov = i64::try_from(result_i128).is_err();
+ let ov32 = i32::try_from(result32_i128).is_err();
+ let ca = u64::try_from(result_u128).is_err();
+ let ca32 = u32::try_from(result32_u128).is_err();
+ Ok(InstructionOutput {
+ rt: Some(result),
+ overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
+ carry: Some(CarryFlags { ca, ca32 }),
+ ..InstructionOutput::default()
+ })
+}
+
create_instr_variants_ov_cr!(divde, divdeo, divde_, divdeo_, i64);
pub fn divdeo(inputs: InstructionInput) -> InstructionResult {
"subfeo."
}
+ // addme
+ #[enumerant = AddME]
+ fn addme(Ra, Carry) -> (Rt, Carry) {
+ "addme"
+ }
+ #[enumerant = AddMEO]
+ fn addmeo(Ra, Overflow, Carry) -> (Rt, Carry, Overflow) {
+ "addmeo"
+ }
+ #[enumerant = AddME_]
+ fn addme_(Ra, Overflow, Carry) -> (Rt, Carry, CR0) {
+ "addme."
+ }
+ #[enumerant = AddMEO_]
+ fn addmeo_(Ra, Overflow, Carry) -> (Rt, Carry, Overflow, CR0) {
+ "addmeo."
+ }
+
+ // subfme
+ #[enumerant = SubFME]
+ fn subfme(Ra, Carry) -> (Rt, Carry) {
+ "subfme"
+ }
+ #[enumerant = SubFMEO]
+ fn subfmeo(Ra, Overflow, Carry) -> (Rt, Carry, Overflow) {
+ "subfmeo"
+ }
+ #[enumerant = SubFME_]
+ fn subfme_(Ra, Overflow, Carry) -> (Rt, Carry, CR0) {
+ "subfme."
+ }
+ #[enumerant = SubFMEO_]
+ fn subfmeo_(Ra, Overflow, Carry) -> (Rt, Carry, Overflow, CR0) {
+ "subfmeo."
+ }
+
+ // addze
+ #[enumerant = AddZE]
+ fn addze(Ra, Carry) -> (Rt, Carry) {
+ "addze"
+ }
+ #[enumerant = AddZEO]
+ fn addzeo(Ra, Overflow, Carry) -> (Rt, Carry, Overflow) {
+ "addzeo"
+ }
+ #[enumerant = AddZE_]
+ fn addze_(Ra, Overflow, Carry) -> (Rt, Carry, CR0) {
+ "addze."
+ }
+ #[enumerant = AddZEO_]
+ fn addzeo_(Ra, Overflow, Carry) -> (Rt, Carry, Overflow, CR0) {
+ "addzeo."
+ }
+
+ // subfze
+ #[enumerant = SubFZE]
+ fn subfze(Ra, Carry) -> (Rt, Carry) {
+ "subfze"
+ }
+ #[enumerant = SubFZEO]
+ fn subfzeo(Ra, Overflow, Carry) -> (Rt, Carry, Overflow) {
+ "subfzeo"
+ }
+ #[enumerant = SubFZE_]
+ fn subfze_(Ra, Overflow, Carry) -> (Rt, Carry, CR0) {
+ "subfze."
+ }
+ #[enumerant = SubFZEO_]
+ fn subfzeo_(Ra, Overflow, Carry) -> (Rt, Carry, Overflow, CR0) {
+ "subfzeo."
+ }
+
// divde
#[enumerant = DivDE]
fn divde(Ra, Rb) -> (Rt) {