Commit afd6ae80 authored by qinsoon's avatar qinsoon

identify cases where 64b ints are small enough to fit in an i32 immediate

number
parent ff42dd1e
...@@ -5632,14 +5632,23 @@ impl<'a> InstructionSelection { ...@@ -5632,14 +5632,23 @@ impl<'a> InstructionSelection {
None => panic!("expected an int") None => panic!("expected an int")
}; };
match op.v { let val = match op.v {
Value_::Constant(Constant::Int(val)) => { Value_::Constant(Constant::Int(val)) => {
debug_assert!(x86_64::is_valid_x86_imm(op)); debug_assert!(x86_64::is_valid_x86_imm(op));
(val as i32, op_length) match op_length {
128 => panic!("cannot emit int128 as immediate"),
64 => val as i64 as i32,
32 => val as i32,
16 => val as i16 as i32,
1 | 8 => val as i8 as i32,
_ => panic!("unsupported int types")
}
} }
_ => panic!("expected iimm") _ => panic!("expect iimm")
} };
(val, op_length)
} }
/// emits a TreeNode as address /// emits a TreeNode as address
......
...@@ -616,11 +616,19 @@ pub fn is_callee_saved(reg_id: MuID) -> bool { ...@@ -616,11 +616,19 @@ pub fn is_callee_saved(reg_id: MuID) -> bool {
pub fn is_valid_x86_imm(op: &P<Value>) -> bool { pub fn is_valid_x86_imm(op: &P<Value>) -> bool {
use std::i32; use std::i32;
if op.ty.get_int_length().is_some() && op.ty.get_int_length().unwrap() <= 32 { if let Some(int_width) = op.ty.get_int_length() {
match op.v { match int_width {
Value_::Constant(Constant::Int(val)) 1...32 => op.is_int_const(),
if val as i32 >= i32::MIN && val as i32 <= i32::MAX => true, 64 => {
_ => false match op.v {
Value_::Constant(Constant::Int(val)) => {
val as i64 >= i32::MIN as i64 && val as i64 <= i32::MAX as i64
}
_ => false
}
}
128 => false,
_ => unimplemented!()
} }
} else { } else {
false false
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment