diff --git a/cranelift/src/libcretonne/ir/immediates.rs b/cranelift/src/libcretonne/ir/immediates.rs index 077ea4205f..99276bfd66 100644 --- a/cranelift/src/libcretonne/ir/immediates.rs +++ b/cranelift/src/libcretonne/ir/immediates.rs @@ -11,16 +11,20 @@ use std::str::FromStr; /// 64-bit immediate integer operand. /// +/// An `Imm64` operand can also be used to represent immediate values of smaller integer types by +/// sign-extending to `i64`. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct Imm64(i64); impl Imm64 { - pub fn from_bits(x: u64) -> Imm64 { - Imm64(x as i64) + pub fn new(x: i64) -> Imm64 { + Imm64(x) } +} - pub fn to_bits(&self) -> u64 { - self.0 as u64 +impl Into for Imm64 { + fn into(self) -> i64 { + self.0 } } @@ -115,7 +119,7 @@ impl FromStr for Imm64 { return Err("Negative number too small for Imm64"); } } - Ok(Imm64::from_bits(value)) + Ok(Imm64::new(value as i64)) } } diff --git a/cranelift/src/libreader/parser.rs b/cranelift/src/libreader/parser.rs index 87c336906a..fa6a445158 100644 --- a/cranelift/src/libreader/parser.rs +++ b/cranelift/src/libreader/parser.rs @@ -596,8 +596,11 @@ impl<'a> Parser<'a> { try!(self.match_identifier("stack_slot", "expected 'stack_slot'")); // stack-slot-decl ::= StackSlot(ss) "=" "stack_slot" * Bytes {"," stack-slot-flag} - let bytes = try!(self.match_imm64("expected byte-size in stack_slot decl")).to_bits(); - if bytes > u32::MAX as u64 { + let bytes: i64 = try!(self.match_imm64("expected byte-size in stack_slot decl")).into(); + if bytes < 0 { + return err!(self.loc, "negative stack slot size"); + } + if bytes > u32::MAX as i64 { return err!(self.loc, "stack slot too large"); } let data = StackSlotData::new(bytes as u32);