[codegen] add intcc conditions for reading overflow flag
Add conditions to IntCC for checking the overflow flag (Overflow, NotOverflow).
This commit is contained in:
committed by
Benjamin Bouvier
parent
dfdd504edc
commit
43a891dfa2
@@ -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);
|
||||
"#,
|
||||
),
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -272,8 +272,8 @@ fn sib<CS: CodeSink + ?Sized>(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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user