[codegen] add intcc conditions for reading carry flag

Add conditions to IntCC for checking the carry flag (Carry, NotCarry).

Fixes: https://github.com/CraneStation/cranelift/issues/980
This commit is contained in:
Ujjwal Sharma
2019-09-07 00:10:54 +05:30
committed by Dan Gohman
parent 1431ab5201
commit 6e131e5347
7 changed files with 44 additions and 1 deletions

View File

@@ -1586,6 +1586,7 @@ pub(crate) fn define(
let x = &operand("x", Int);
let y = &operand("y", Int);
// TODO(ryzokuken): Add documentation for unsigned overflow.
ig.push(
Inst::new(
"icmp",

View File

@@ -126,6 +126,14 @@ impl TargetIsa for Isa {
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
emit_function(func, binemit::emit_inst, sink, self)
}
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC {
ir::condcodes::IntCC::UnsignedLessThan
}
fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC {
ir::condcodes::IntCC::UnsignedGreaterThanOrEqual
}
}
impl fmt::Display for Isa {

View File

@@ -114,6 +114,14 @@ impl TargetIsa for Isa {
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
emit_function(func, binemit::emit_inst, sink, self)
}
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC {
ir::condcodes::IntCC::UnsignedLessThan
}
fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC {
ir::condcodes::IntCC::UnsignedGreaterThanOrEqual
}
}
impl fmt::Display for Isa {

View File

@@ -371,4 +371,10 @@ pub trait TargetIsa: fmt::Display + Sync {
/// Emit a whole function into memory.
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut binemit::MemoryCodeSink);
/// IntCC condition for Unsigned Addition Overflow (Carry).
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC;
/// IntCC condition for Unsigned Subtraction Overflow (Borrow/Carry).
fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC;
}

View File

@@ -121,6 +121,14 @@ impl TargetIsa for Isa {
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
emit_function(func, binemit::emit_inst, sink, self)
}
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC {
unimplemented!()
}
fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC {
unimplemented!()
}
}
#[cfg(test)]

View File

@@ -142,6 +142,14 @@ impl TargetIsa for Isa {
let _tt = timing::prologue_epilogue();
abi::prologue_epilogue(func, self)
}
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC {
ir::condcodes::IntCC::UnsignedLessThan
}
fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC {
ir::condcodes::IntCC::UnsignedLessThan
}
}
impl fmt::Display for Isa {

View File

@@ -83,7 +83,11 @@ fn dynamic_addr(
// We need an overflow check for the adjusted offset.
let access_size_val = pos.ins().iconst(offset_ty, access_size as i64);
let (adj_offset, overflow) = pos.ins().iadd_ifcout(offset, access_size_val);
pos.ins().trapnz(overflow, ir::TrapCode::HeapOutOfBounds);
pos.ins().trapif(
isa.unsigned_add_overflow_condition(),
overflow,
ir::TrapCode::HeapOutOfBounds,
);
oob = pos
.ins()
.icmp(IntCC::UnsignedGreaterThan, adj_offset, bound);