[WebAssembly] Fixed disassembler not knowing about new brlist operand
Summary: The previously introduced new operand type for br_table didn't have a disassembler implementation, causing an assert. Reviewers: dschuff, aheejin Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D56227 llvm-svn: 350366
This commit is contained in:
parent
9843295608
commit
820c6263d9
|
@ -151,7 +151,8 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction(
|
|||
MI.setOpcode(WasmInst->Opcode);
|
||||
// Parse any operands.
|
||||
for (uint8_t OPI = 0; OPI < WasmInst->NumOperands; OPI++) {
|
||||
switch (OperandTable[WasmInst->OperandStart + OPI]) {
|
||||
auto OT = OperandTable[WasmInst->OperandStart + OPI];
|
||||
switch (OT) {
|
||||
// ULEB operands:
|
||||
case WebAssembly::OPERAND_BASIC_BLOCK:
|
||||
case WebAssembly::OPERAND_LOCAL:
|
||||
|
@ -210,6 +211,19 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction(
|
|||
return MCDisassembler::Fail;
|
||||
break;
|
||||
}
|
||||
case WebAssembly::OPERAND_BRLIST: {
|
||||
int64_t TargetTableLen;
|
||||
if (!nextLEB(TargetTableLen, Bytes, Size, false))
|
||||
return MCDisassembler::Fail;
|
||||
for (int64_t I = 0; I < TargetTableLen; I++) {
|
||||
if (!parseLEBImmediate(MI, Size, Bytes, false))
|
||||
return MCDisassembler::Fail;
|
||||
}
|
||||
// Default case.
|
||||
if (!parseLEBImmediate(MI, Size, Bytes, false))
|
||||
return MCDisassembler::Fail;
|
||||
break;
|
||||
}
|
||||
case MCOI::OPERAND_REGISTER:
|
||||
// The tablegen header currently does not have any register operands since
|
||||
// we use only the stack (_S) instructions.
|
||||
|
|
|
@ -79,6 +79,8 @@ enum OperandType {
|
|||
OPERAND_TYPEINDEX,
|
||||
/// Event index.
|
||||
OPERAND_EVENT,
|
||||
/// A list of branch targets for br_list.
|
||||
OPERAND_BRLIST,
|
||||
};
|
||||
} // end namespace WebAssembly
|
||||
|
||||
|
|
|
@ -36,10 +36,14 @@ def : Pat<(brcond (i32 (seteq I32:$cond, 0)), bb:$dst),
|
|||
// A list of branch targets enclosed in {} and separated by comma.
|
||||
// Used by br_table only.
|
||||
def BrListAsmOperand : AsmOperandClass { let Name = "BrList"; }
|
||||
let OperandNamespace = "WebAssembly" in {
|
||||
let OperandType = "OPERAND_BRLIST" in {
|
||||
def brlist : Operand<i32> {
|
||||
let ParserMatchClass = BrListAsmOperand;
|
||||
let PrintMethod = "printBrList";
|
||||
}
|
||||
} // OPERAND_BRLIST
|
||||
} // OperandNamespace = "WebAssembly"
|
||||
|
||||
// TODO: SelectionDAG's lowering insists on using a pointer as the index for
|
||||
// jump tables, so in practice we don't ever use BR_TABLE_I64 in wasm32 mode
|
||||
|
|
|
@ -44,3 +44,7 @@
|
|||
# CHECK: i64x2.any_true
|
||||
# CHECK-NOT: i64.div_u
|
||||
0xFD 0x85 0x81 0x80 0x80 0x80 0x80 0x00
|
||||
|
||||
# Check br_table, which has its own operand type.
|
||||
# CHECK: br_table {0, 1, 2}
|
||||
0x0E 0x02 0x00 0x01 0x02
|
||||
|
|
|
@ -92,6 +92,7 @@ void emitWebAssemblyDisassemblerTables(
|
|||
// Collect operand types for storage in a shared list.
|
||||
CurOperandList.clear();
|
||||
for (auto &Op : CGI.Operands.OperandList) {
|
||||
assert(Op.OperandType != "MCOI::OPERAND_UNKNOWN");
|
||||
CurOperandList.push_back(Op.OperandType);
|
||||
}
|
||||
// See if we already have stored this sequence before. This is not
|
||||
|
|
Loading…
Reference in New Issue