[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:
committed by
Dan Gohman
parent
1431ab5201
commit
6e131e5347
@@ -1586,6 +1586,7 @@ pub(crate) fn define(
|
|||||||
let x = &operand("x", Int);
|
let x = &operand("x", Int);
|
||||||
let y = &operand("y", Int);
|
let y = &operand("y", Int);
|
||||||
|
|
||||||
|
// TODO(ryzokuken): Add documentation for unsigned overflow.
|
||||||
ig.push(
|
ig.push(
|
||||||
Inst::new(
|
Inst::new(
|
||||||
"icmp",
|
"icmp",
|
||||||
|
|||||||
@@ -126,6 +126,14 @@ impl TargetIsa for Isa {
|
|||||||
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
|
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
|
||||||
emit_function(func, binemit::emit_inst, sink, self)
|
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 {
|
impl fmt::Display for Isa {
|
||||||
|
|||||||
@@ -114,6 +114,14 @@ impl TargetIsa for Isa {
|
|||||||
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
|
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
|
||||||
emit_function(func, binemit::emit_inst, sink, self)
|
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 {
|
impl fmt::Display for Isa {
|
||||||
|
|||||||
@@ -371,4 +371,10 @@ pub trait TargetIsa: fmt::Display + Sync {
|
|||||||
|
|
||||||
/// Emit a whole function into memory.
|
/// Emit a whole function into memory.
|
||||||
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut binemit::MemoryCodeSink);
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,14 @@ impl TargetIsa for Isa {
|
|||||||
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
|
fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
|
||||||
emit_function(func, binemit::emit_inst, sink, self)
|
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)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -142,6 +142,14 @@ impl TargetIsa for Isa {
|
|||||||
let _tt = timing::prologue_epilogue();
|
let _tt = timing::prologue_epilogue();
|
||||||
abi::prologue_epilogue(func, self)
|
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 {
|
impl fmt::Display for Isa {
|
||||||
|
|||||||
@@ -83,7 +83,11 @@ fn dynamic_addr(
|
|||||||
// We need an overflow check for the adjusted offset.
|
// We need an overflow check for the adjusted offset.
|
||||||
let access_size_val = pos.ins().iconst(offset_ty, access_size as i64);
|
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);
|
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
|
oob = pos
|
||||||
.ins()
|
.ins()
|
||||||
.icmp(IntCC::UnsignedGreaterThan, adj_offset, bound);
|
.icmp(IntCC::UnsignedGreaterThan, adj_offset, bound);
|
||||||
|
|||||||
Reference in New Issue
Block a user