Parse the BranchTable instruction format.
Resolve the jump table reference immediately since all jump tables are declared in the preamble.
This commit is contained in:
@@ -110,6 +110,14 @@ impl Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolve a reference to a jump table.
|
||||||
|
fn get_jt(&self, number: u32, loc: &Location) -> Result<JumpTable> {
|
||||||
|
match self.jump_tables.get(&number) {
|
||||||
|
Some(&jt) => Ok(jt),
|
||||||
|
None => err!(loc, "undefined jump table jt{}", number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate a new EBB and add a mapping src_ebb -> Ebb.
|
// Allocate a new EBB and add a mapping src_ebb -> Ebb.
|
||||||
fn add_ebb(&mut self, src_ebb: Ebb, loc: &Location) -> Result<Ebb> {
|
fn add_ebb(&mut self, src_ebb: Ebb, loc: &Location) -> Result<Ebb> {
|
||||||
let ebb = self.function.dfg.make_ebb();
|
let ebb = self.function.dfg.make_ebb();
|
||||||
@@ -332,12 +340,12 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Match and consume a jump table reference.
|
// Match and consume a jump table reference.
|
||||||
fn match_jt(&mut self, err_msg: &str) -> Result<u32> {
|
fn match_jt(&mut self) -> Result<u32> {
|
||||||
if let Some(Token::JumpTable(jt)) = self.token() {
|
if let Some(Token::JumpTable(jt)) = self.token() {
|
||||||
self.consume();
|
self.consume();
|
||||||
Ok(jt)
|
Ok(jt)
|
||||||
} else {
|
} else {
|
||||||
err!(self.loc, err_msg)
|
err!(self.loc, "expected jump table number: jt«n»")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +610,7 @@ impl<'a> Parser<'a> {
|
|||||||
//
|
//
|
||||||
// jump-table-decl ::= * JumpTable(jt) "=" "jump_table" jt-entry {"," jt-entry}
|
// jump-table-decl ::= * JumpTable(jt) "=" "jump_table" jt-entry {"," jt-entry}
|
||||||
fn parse_jump_table_decl(&mut self) -> Result<(u32, JumpTableData)> {
|
fn parse_jump_table_decl(&mut self) -> Result<(u32, JumpTableData)> {
|
||||||
let number = try!(self.match_jt("expected jump table number: jt«n»"));
|
let number = try!(self.match_jt());
|
||||||
try!(self.match_token(Token::Equal, "expected '=' in jump_table decl"));
|
try!(self.match_token(Token::Equal, "expected '=' in jump_table decl"));
|
||||||
try!(self.match_identifier("jump_table", "expected 'jump_table'"));
|
try!(self.match_identifier("jump_table", "expected 'jump_table'"));
|
||||||
|
|
||||||
@@ -763,7 +771,7 @@ impl<'a> Parser<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// instruction ::= [inst-results "="] Opcode(opc) ["." Type] * ...
|
// instruction ::= [inst-results "="] Opcode(opc) ["." Type] * ...
|
||||||
let inst_data = try!(self.parse_inst_operands(opcode));
|
let inst_data = try!(self.parse_inst_operands(ctx, opcode));
|
||||||
|
|
||||||
// We're done parsing the instruction now.
|
// We're done parsing the instruction now.
|
||||||
//
|
//
|
||||||
@@ -914,7 +922,7 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
// Parse the operands following the instruction opcode.
|
// Parse the operands following the instruction opcode.
|
||||||
// This depends on the format of the opcode.
|
// This depends on the format of the opcode.
|
||||||
fn parse_inst_operands(&mut self, opcode: Opcode) -> Result<InstructionData> {
|
fn parse_inst_operands(&mut self, ctx: &Context, opcode: Opcode) -> Result<InstructionData> {
|
||||||
Ok(match opcode.format().unwrap() {
|
Ok(match opcode.format().unwrap() {
|
||||||
InstructionFormat::Nullary => {
|
InstructionFormat::Nullary => {
|
||||||
InstructionData::Nullary {
|
InstructionData::Nullary {
|
||||||
@@ -1096,7 +1104,17 @@ impl<'a> Parser<'a> {
|
|||||||
data: Box::new(ReturnData { args: args }),
|
data: Box::new(ReturnData { args: args }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InstructionFormat::BranchTable |
|
InstructionFormat::BranchTable => {
|
||||||
|
let arg = try!(self.match_value("expected SSA value operand"));
|
||||||
|
try!(self.match_token(Token::Comma, "expected ',' between operands"));
|
||||||
|
let table = try!(self.match_jt().and_then(|num| ctx.get_jt(num, &self.loc)));
|
||||||
|
InstructionData::BranchTable {
|
||||||
|
opcode: opcode,
|
||||||
|
ty: VOID,
|
||||||
|
arg: arg,
|
||||||
|
table: table,
|
||||||
|
}
|
||||||
|
}
|
||||||
InstructionFormat::Call => {
|
InstructionFormat::Call => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,11 +44,12 @@ ebb1(vx2: i32, vx3: f32):
|
|||||||
brnz vx0, ebb0(vx2, vx3)
|
brnz vx0, ebb0(vx2, vx3)
|
||||||
}
|
}
|
||||||
|
|
||||||
function jumptable() {
|
function jumptable(i32) {
|
||||||
jt200 = jump_table 0, 0
|
jt200 = jump_table 0, 0
|
||||||
jt2 = jump_table 0, 0, ebb10, ebb40, ebb20, ebb30
|
jt2 = jump_table 0, 0, ebb10, ebb40, ebb20, ebb30
|
||||||
|
|
||||||
ebb10:
|
ebb10(v3: i32):
|
||||||
|
br_table v3, jt2
|
||||||
trap
|
trap
|
||||||
ebb20:
|
ebb20:
|
||||||
trap
|
trap
|
||||||
|
|||||||
@@ -38,11 +38,12 @@ ebb1(vx2: i32, vx3: f32):
|
|||||||
brnz vx0, ebb0(vx2, vx3)
|
brnz vx0, ebb0(vx2, vx3)
|
||||||
}
|
}
|
||||||
|
|
||||||
function jumptable() {
|
function jumptable(i32) {
|
||||||
jt0 = jump_table 0
|
jt0 = jump_table 0
|
||||||
jt1 = jump_table 0, 0, ebb0, ebb3, ebb1, ebb2
|
jt1 = jump_table 0, 0, ebb0, ebb3, ebb1, ebb2
|
||||||
|
|
||||||
ebb0:
|
ebb0(vx0: i32):
|
||||||
|
br_table vx0, jt1
|
||||||
trap
|
trap
|
||||||
|
|
||||||
ebb1:
|
ebb1:
|
||||||
|
|||||||
Reference in New Issue
Block a user