diff --git a/cranelift/src/libreader/parser.rs b/cranelift/src/libreader/parser.rs index 82e17aea5f..ca8f56232b 100644 --- a/cranelift/src/libreader/parser.rs +++ b/cranelift/src/libreader/parser.rs @@ -247,6 +247,19 @@ impl<'a> Parser<'a> { } } + // Match and consume a u8 immediate. + // This is used for lane numbers in SIMD vectors. + fn match_u8(&mut self, err_msg: &str) -> Result { + 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 u8 to check for overflow and other issues. + text.parse().map_err(|_| self.error("expected u8 decimal immediate")) + } else { + err!(self.loc, err_msg) + } + } + // Match and consume an Ieee32 immediate. fn match_ieee32(&mut self, err_msg: &str) -> Result { if let Some(Token::Float(text)) = self.token() { @@ -831,8 +844,30 @@ impl<'a> Parser<'a> { }), } } - InstructionFormat::InsertLane | - InstructionFormat::ExtractLane | + InstructionFormat::InsertLane => { + let lhs = try!(self.match_value("expected SSA value first operand")); + try!(self.match_token(Token::Comma, "expected ',' between operands")); + let lane = try!(self.match_u8("expected lane number")); + try!(self.match_token(Token::Comma, "expected ',' between operands")); + let rhs = try!(self.match_value("expected SSA value last operand")); + InstructionData::InsertLane { + opcode: opcode, + ty: VOID, + lane: lane, + args: [lhs, rhs], + } + } + InstructionFormat::ExtractLane => { + let arg = try!(self.match_value("expected SSA value last operand")); + try!(self.match_token(Token::Comma, "expected ',' between operands")); + let lane = try!(self.match_u8("expected lane number")); + InstructionData::ExtractLane { + opcode: opcode, + ty: VOID, + lane: lane, + arg: arg, + } + } InstructionFormat::BranchTable | InstructionFormat::Call => { unimplemented!(); diff --git a/cranelift/tests/parser/tiny.cton b/cranelift/tests/parser/tiny.cton index 5e38d5efbb..6be261e273 100644 --- a/cranelift/tests/parser/tiny.cton +++ b/cranelift/tests/parser/tiny.cton @@ -15,6 +15,14 @@ ebb0: ; Polymorphic istruction controlled by second operand. function select() { -ebb0(vx0: i32, vx1:i32, vx2: b1): +ebb0(vx0: i32, vx1: i32, vx2: b1): v0 = select vx2, vx0, vx1 } + +; Lane indexes. +function lanes() { +ebb0: + v0 = iconst.i32x4 2 + v1 = extractlane v0, 3 + v2 = insertlane v0, 1, v1 +} diff --git a/cranelift/tests/parser/tiny.cton.ref b/cranelift/tests/parser/tiny.cton.ref index 29b604f29d..1fc1745a34 100644 --- a/cranelift/tests/parser/tiny.cton.ref +++ b/cranelift/tests/parser/tiny.cton.ref @@ -14,3 +14,10 @@ function select() { ebb0(vx0: i32, vx1: i32, vx2: b1): v0 = select vx2, vx0, vx1 } + +function lanes() { +ebb0: + v0 = iconst.i32x4 2 + v1 = extractlane v0, 3 + v2 = insertlane v0, 1, v1 +}