Merge pull request #1687 from fitzgen/sign-extend-immediates

cranelift: Sign extend `Imm64` immediates
This commit is contained in:
Nick Fitzgerald
2020-05-14 10:09:53 -07:00
committed by GitHub
4 changed files with 103 additions and 1 deletions

View File

@@ -62,6 +62,21 @@ impl Imm64 {
pub fn bits(&self) -> i64 {
self.0
}
/// Sign extend this immediate as if it were a signed integer of the given
/// power-of-two width.
pub fn sign_extend_from_width(&mut self, bit_width: u16) {
debug_assert!(bit_width.is_power_of_two());
if bit_width >= 64 {
return;
}
let bit_width = bit_width as i64;
let delta = 64 - bit_width;
let sign_extended = (self.0 << delta) >> delta;
*self = Imm64(sign_extended);
}
}
impl Into<i64> for Imm64 {

View File

@@ -296,6 +296,39 @@ impl InstructionData {
}
}
}
#[inline]
pub(crate) fn sign_extend_immediates(&mut self, ctrl_typevar: Type) {
if ctrl_typevar.is_invalid() {
return;
}
let bit_width = ctrl_typevar.bits();
match self {
Self::BinaryImm {
opcode,
arg: _,
imm,
} => {
if matches!(opcode, Opcode::SdivImm | Opcode::SremImm) {
imm.sign_extend_from_width(bit_width);
}
}
Self::IntCompareImm {
opcode,
arg: _,
cond,
imm,
} => {
debug_assert_eq!(*opcode, Opcode::IcmpImm);
if cond.unsigned() != *cond {
imm.sign_extend_from_width(bit_width);
}
}
_ => {}
}
}
}
/// Information about branch and jump instructions.