diff --git a/cranelift/codegen/meta/src/isa/x86/recipes.rs b/cranelift/codegen/meta/src/isa/x86/recipes.rs index da602b9973..13d9dcf833 100644 --- a/cranelift/codegen/meta/src/isa/x86/recipes.rs +++ b/cranelift/codegen/meta/src/isa/x86/recipes.rs @@ -2920,21 +2920,9 @@ pub(crate) fn define<'shared>( {{PUT_OP}}(bits, rex2(in_reg0, in_reg1), sink); modrm_rr(in_reg0, in_reg1, sink); // `setCC` instruction, no REX. - use crate::ir::condcodes::IntCC::*; - let setcc = match cond { - Equal => 0x94, - NotEqual => 0x95, - SignedLessThan => 0x9c, - SignedGreaterThanOrEqual => 0x9d, - SignedGreaterThan => 0x9f, - SignedLessThanOrEqual => 0x9e, - UnsignedLessThan => 0x92, - UnsignedGreaterThanOrEqual => 0x93, - UnsignedGreaterThan => 0x97, - UnsignedLessThanOrEqual => 0x96, - }; + let setcc = 0x90 | icc2opc(cond); sink.put1(0x0f); - sink.put1(setcc); + sink.put1(setcc as u8); modrm_rr(out_reg0, 0, sink); "#, ), @@ -2971,21 +2959,9 @@ pub(crate) fn define<'shared>( let imm: i64 = imm.into(); sink.put1(imm as u8); // `setCC` instruction, no REX. - use crate::ir::condcodes::IntCC::*; - let setcc = match cond { - Equal => 0x94, - NotEqual => 0x95, - SignedLessThan => 0x9c, - SignedGreaterThanOrEqual => 0x9d, - SignedGreaterThan => 0x9f, - SignedLessThanOrEqual => 0x9e, - UnsignedLessThan => 0x92, - UnsignedGreaterThanOrEqual => 0x93, - UnsignedGreaterThan => 0x97, - UnsignedLessThanOrEqual => 0x96, - }; + let setcc = 0x90 | icc2opc(cond); sink.put1(0x0f); - sink.put1(setcc); + sink.put1(setcc as u8); modrm_rr(out_reg0, 0, sink); "#, ), @@ -3006,21 +2982,9 @@ pub(crate) fn define<'shared>( let imm: i64 = imm.into(); sink.put4(imm as u32); // `setCC` instruction, no REX. - use crate::ir::condcodes::IntCC::*; - let setcc = match cond { - Equal => 0x94, - NotEqual => 0x95, - SignedLessThan => 0x9c, - SignedGreaterThanOrEqual => 0x9d, - SignedGreaterThan => 0x9f, - SignedLessThanOrEqual => 0x9e, - UnsignedLessThan => 0x92, - UnsignedGreaterThanOrEqual => 0x93, - UnsignedGreaterThan => 0x97, - UnsignedLessThanOrEqual => 0x96, - }; + let setcc = 0x90 | icc2opc(cond); sink.put1(0x0f); - sink.put1(setcc); + sink.put1(setcc as u8); modrm_rr(out_reg0, 0, sink); "#, ), diff --git a/cranelift/codegen/meta/src/shared/immediates.rs b/cranelift/codegen/meta/src/shared/immediates.rs index 0b5e84c521..f9c114a6a0 100644 --- a/cranelift/codegen/meta/src/shared/immediates.rs +++ b/cranelift/codegen/meta/src/shared/immediates.rs @@ -129,6 +129,8 @@ impl Immediates { intcc_values.insert("ugt", "UnsignedGreaterThan"); intcc_values.insert("ule", "UnsignedLessThanOrEqual"); intcc_values.insert("ult", "UnsignedLessThan"); + intcc_values.insert("of", "Overflow"); + intcc_values.insert("nof", "NotOverflow"); Builder::new_enum("intcc", intcc_values) .doc("An integer comparison condition code.") .default_member("cond") diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index 5461aada55..679ee1a2c1 100644 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -1587,6 +1587,7 @@ pub(crate) fn define( let y = &operand("y", Int); // TODO(ryzokuken): Add documentation for unsigned overflow. + // TODO(ryzokuken): Add documentation for signed overflow. ig.push( Inst::new( "icmp", diff --git a/cranelift/codegen/shared/src/condcodes.rs b/cranelift/codegen/shared/src/condcodes.rs index 743e30954d..1171eef2f6 100644 --- a/cranelift/codegen/shared/src/condcodes.rs +++ b/cranelift/codegen/shared/src/condcodes.rs @@ -51,6 +51,10 @@ pub enum IntCC { UnsignedGreaterThan, /// Unsigned `<=`. UnsignedLessThanOrEqual, + /// Signed Overflow. + Overflow, + /// Signed No Overflow. + NotOverflow, } impl CondCode for IntCC { @@ -67,6 +71,8 @@ impl CondCode for IntCC { UnsignedGreaterThanOrEqual => UnsignedLessThan, UnsignedGreaterThan => UnsignedLessThanOrEqual, UnsignedLessThanOrEqual => UnsignedGreaterThan, + Overflow => NotOverflow, + NotOverflow => Overflow, } } @@ -83,6 +89,8 @@ impl CondCode for IntCC { UnsignedGreaterThanOrEqual => UnsignedLessThanOrEqual, UnsignedLessThan => UnsignedGreaterThan, UnsignedLessThanOrEqual => UnsignedGreaterThanOrEqual, + Overflow => Overflow, + NotOverflow => NotOverflow, } } } @@ -101,6 +109,8 @@ impl Display for IntCC { UnsignedGreaterThanOrEqual => "uge", UnsignedLessThan => "ult", UnsignedLessThanOrEqual => "ule", + Overflow => "of", + NotOverflow => "nof", }) } } @@ -121,6 +131,8 @@ impl FromStr for IntCC { "ugt" => Ok(UnsignedGreaterThan), "ule" => Ok(UnsignedLessThanOrEqual), "ult" => Ok(UnsignedLessThan), + "of" => Ok(Overflow), + "nof" => Ok(NotOverflow), _ => Err(()), } } @@ -270,7 +282,7 @@ mod tests { use super::*; use std::string::ToString; - static INT_ALL: [IntCC; 10] = [ + static INT_ALL: [IntCC; 12] = [ IntCC::Equal, IntCC::NotEqual, IntCC::SignedLessThan, @@ -281,6 +293,8 @@ mod tests { IntCC::UnsignedGreaterThanOrEqual, IntCC::UnsignedGreaterThan, IntCC::UnsignedLessThanOrEqual, + IntCC::Overflow, + IntCC::NotOverflow, ]; #[test] diff --git a/cranelift/codegen/src/isa/x86/binemit.rs b/cranelift/codegen/src/isa/x86/binemit.rs index a5924ed030..cda6ae5807 100644 --- a/cranelift/codegen/src/isa/x86/binemit.rs +++ b/cranelift/codegen/src/isa/x86/binemit.rs @@ -272,8 +272,8 @@ fn sib(scale: u8, index: RegUnit, base: RegUnit, sink: &m fn icc2opc(cond: IntCC) -> u16 { use crate::ir::condcodes::IntCC::*; match cond { - // 0x0 = Overflow. - // 0x1 = !Overflow. + Overflow => 0x0, + NotOverflow => 0x1, UnsignedLessThan => 0x2, UnsignedGreaterThanOrEqual => 0x3, Equal => 0x4, diff --git a/cranelift/filetests/filetests/isa/x86/binary32.clif b/cranelift/filetests/filetests/isa/x86/binary32.clif index cc8f638014..5db78ee2e0 100644 --- a/cranelift/filetests/filetests/isa/x86/binary32.clif +++ b/cranelift/filetests/filetests/isa/x86/binary32.clif @@ -664,6 +664,10 @@ ebb11: trapif ugt v11, user0 ; bin: 76 02 user0 0f 0b ; asm: jnbe .+4; ud2 trapif ule v11, user0 ; bin: 77 02 user0 0f 0b + ; asm: jo .+4; ud2 + trapif of v11, user0 ; bin: 71 02 user0 0f 0b + ; asm: jno .+4; ud2 + trapif nof v11, user0 ; bin: 70 02 user0 0f 0b ; Stack check. ; asm: cmpl %esp, %ecx diff --git a/cranelift/filetests/filetests/isa/x86/binary64.clif b/cranelift/filetests/filetests/isa/x86/binary64.clif index 0430cd78a5..a3fcede60d 100644 --- a/cranelift/filetests/filetests/isa/x86/binary64.clif +++ b/cranelift/filetests/filetests/isa/x86/binary64.clif @@ -862,6 +862,10 @@ ebb11: trapif ugt v11, user0 ; bin: 76 02 user0 0f 0b ; asm: jnbe .+4; ud2 trapif ule v11, user0 ; bin: 77 02 user0 0f 0b + ; asm: jo .+4; ud2 + trapif of v11, user0 ; bin: 71 02 user0 0f 0b + ; asm: jno .+4; ud2 + trapif nof v11, user0 ; bin: 70 02 user0 0f 0b ; Debug trap. debugtrap ; bin: cc