+
+create_instr_variants_ov_cr!(mullw, mullwo, mullw_, mullwo_, i32);
+
+pub fn mullwo(inputs: InstructionInput) -> InstructionResult {
+ let ra = inputs.ra as i32 as i64;
+ let rb = inputs.rb as i32 as i64;
+ let result = ra.wrapping_mul(rb) as u64;
+ let overflow = result as i32 as i64 != result as i64;
+ InstructionResult {
+ rt: Some(result),
+ overflow: Some(OverflowFlags::from_overflow(overflow)),
+ ..InstructionResult::default()
+ }
+}
+
+create_instr_variants_cr!(mulhw, mulhw_, i32);
+
+pub fn mulhw(inputs: InstructionInput) -> InstructionResult {
+ let ra = inputs.ra as i32 as i64;
+ let rb = inputs.rb as i32 as i64;
+ let result = ((ra * rb) >> 32) as i32;
+ let result = result as u64;
+ InstructionResult {
+ rt: Some(result),
+ ..InstructionResult::default()
+ }
+}
+
+create_instr_variants_cr!(mulhwu, mulhwu_, i32);
+
+pub fn mulhwu(inputs: InstructionInput) -> InstructionResult {
+ let ra = inputs.ra as u32 as u64;
+ let rb = inputs.rb as u32 as u64;
+ let result = ((ra * rb) >> 32) as u32;
+ let result = result as u64;
+ InstructionResult {
+ rt: Some(result),
+ ..InstructionResult::default()
+ }
+}
+
+create_instr_variants_ov_cr!(mulld, mulldo, mulld_, mulldo_, i64);
+
+pub fn mulldo(inputs: InstructionInput) -> InstructionResult {
+ let ra = inputs.ra as i64;
+ let rb = inputs.rb as i64;
+ let result = ra.wrapping_mul(rb) as u64;
+ let overflow = ra.checked_mul(rb).is_none();
+ InstructionResult {
+ rt: Some(result),
+ overflow: Some(OverflowFlags::from_overflow(overflow)),
+ ..InstructionResult::default()
+ }
+}
+
+create_instr_variants_cr!(mulhd, mulhd_, i64);
+
+pub fn mulhd(inputs: InstructionInput) -> InstructionResult {
+ let ra = inputs.ra as i64 as i128;
+ let rb = inputs.rb as i64 as i128;
+ let result = ((ra * rb) >> 64) as i64;
+ let result = result as u64;
+ InstructionResult {
+ rt: Some(result),
+ ..InstructionResult::default()
+ }
+}
+
+create_instr_variants_cr!(mulhdu, mulhdu_, i64);
+
+pub fn mulhdu(inputs: InstructionInput) -> InstructionResult {
+ let ra = inputs.ra as u128;
+ let rb = inputs.rb as u128;
+ let result = ((ra * rb) >> 64) as u64;
+ InstructionResult {
+ rt: Some(result),
+ ..InstructionResult::default()
+ }
+}
+
+pub fn maddhd(inputs: InstructionInput) -> InstructionResult {
+ let ra = inputs.ra as i64 as i128;
+ let rb = inputs.rb as i64 as i128;
+ let rc = inputs.rc as i64 as i128;
+ let result = ((ra * rb + rc) >> 64) as u64;
+ InstructionResult {
+ rt: Some(result),
+ ..InstructionResult::default()
+ }
+}
+
+pub fn maddhdu(inputs: InstructionInput) -> InstructionResult {
+ let ra = inputs.ra as u128;
+ let rb = inputs.rb as u128;
+ let rc = inputs.rc as u128;
+ let result = ((ra * rb + rc) >> 64) as u64;
+ InstructionResult {
+ rt: Some(result),
+ ..InstructionResult::default()
+ }
+}
+
+pub fn maddld(inputs: InstructionInput) -> InstructionResult {
+ let ra = inputs.ra as i64;
+ let rb = inputs.rb as i64;
+ let rc = inputs.rc as i64;
+ let result = ra.wrapping_mul(rb).wrapping_add(rc) as u64;
+ InstructionResult {
+ rt: Some(result),
+ ..InstructionResult::default()
+ }
+}