diff --git a/cranelift/codegen/src/ir/immediates.rs b/cranelift/codegen/src/ir/immediates.rs index 408fe17cf3..eb6dfad34b 100644 --- a/cranelift/codegen/src/ir/immediates.rs +++ b/cranelift/codegen/src/ir/immediates.rs @@ -22,6 +22,12 @@ impl IntoBytes for u8 { } } +impl IntoBytes for i16 { + fn into_bytes(self) -> Vec { + self.to_le_bytes().to_vec() + } +} + impl IntoBytes for i32 { fn into_bytes(self) -> Vec { self.to_le_bytes().to_vec() @@ -429,6 +435,7 @@ impl FromIterator for V128Imm { } construct_uimm128_from_iterator_of!(u8, 16); +construct_uimm128_from_iterator_of!(i16, 8); construct_uimm128_from_iterator_of!(i32, 4); construct_uimm128_from_iterator_of!(Ieee32, 4); construct_uimm128_from_iterator_of!(Imm64, 2); diff --git a/cranelift/reader/src/parser.rs b/cranelift/reader/src/parser.rs index 711b4d3cc1..82437d7c6c 100644 --- a/cranelift/reader/src/parser.rs +++ b/cranelift/reader/src/parser.rs @@ -665,6 +665,19 @@ impl<'a> Parser<'a> { } } + // Match and consume a signed 16-bit immediate. + fn match_imm16(&mut self, err_msg: &str) -> ParseResult { + if let Some(Token::Integer(text)) = self.token() { + self.consume(); + // Lexer just gives us raw text that looks like an integer. + // Parse it as a i16 to check for overflow and other issues. + text.parse() + .map_err(|_| self.error("expected i16 decimal immediate")) + } else { + err!(self.loc, err_msg) + } + } + // Match and consume an i32 immediate. // This is used for stack argument byte offsets. fn match_imm32(&mut self, err_msg: &str) -> ParseResult { @@ -855,7 +868,7 @@ impl<'a> Parser<'a> { } else { let uimm128 = match ty.lane_type() { I8 => consume!(ty, self.match_uimm8("Expected an 8-bit unsigned integer")), - I16 => unimplemented!(), // TODO no 16-bit match yet + I16 => consume!(ty, self.match_imm16("Expected a 16-bit integer")), I32 => consume!(ty, self.match_imm32("Expected a 32-bit integer")), I64 => consume!(ty, self.match_imm64("Expected a 64-bit integer")), F32 => consume!(ty, self.match_ieee32("Expected a 32-bit float...")),