diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp')
| -rw-r--r-- | llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp | 72 |
1 files changed, 41 insertions, 31 deletions
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp index aaca213c4afe..807fd42b8cf6 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp @@ -13,14 +13,12 @@ #include "MCTargetDesc/WebAssemblyFixupKinds.h" #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrInfo.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/Debug.h" @@ -82,14 +80,15 @@ void WebAssemblyMCCodeEmitter::encodeInstruction( // For br_table instructions, encode the size of the table. In the MCInst, // there's an index operand (if not a stack instruction), one operand for // each table entry, and the default operand. - if (MI.getOpcode() == WebAssembly::BR_TABLE_I32_S || - MI.getOpcode() == WebAssembly::BR_TABLE_I64_S) + unsigned Opcode = MI.getOpcode(); + if (Opcode == WebAssembly::BR_TABLE_I32_S || + Opcode == WebAssembly::BR_TABLE_I64_S) encodeULEB128(MI.getNumOperands() - 1, OS); - if (MI.getOpcode() == WebAssembly::BR_TABLE_I32 || - MI.getOpcode() == WebAssembly::BR_TABLE_I64) + if (Opcode == WebAssembly::BR_TABLE_I32 || + Opcode == WebAssembly::BR_TABLE_I64) encodeULEB128(MI.getNumOperands() - 2, OS); - const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); + const MCInstrDesc &Desc = MCII.get(Opcode); for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) { const MCOperand &MO = MI.getOperand(I); if (MO.isReg()) { @@ -136,7 +135,12 @@ void WebAssemblyMCCodeEmitter::encodeInstruction( encodeULEB128(uint64_t(MO.getImm()), OS); } } else { - encodeULEB128(uint64_t(MO.getImm()), OS); + // Variadic immediate operands are br_table's destination operands or + // try_table's operands (# of catch clauses, catch sub-opcodes, or catch + // clause destinations) + assert(WebAssembly::isBrTable(Opcode) || + Opcode == WebAssembly::TRY_TABLE_S); + encodeULEB128(uint32_t(MO.getImm()), OS); } } else if (MO.isSFPImm()) { @@ -146,32 +150,38 @@ void WebAssemblyMCCodeEmitter::encodeInstruction( uint64_t D = MO.getDFPImm(); support::endian::write<uint64_t>(OS, D, llvm::endianness::little); } else if (MO.isExpr()) { - const MCOperandInfo &Info = Desc.operands()[I]; llvm::MCFixupKind FixupKind; size_t PaddedSize = 5; - switch (Info.OperandType) { - case WebAssembly::OPERAND_I32IMM: - FixupKind = MCFixupKind(WebAssembly::fixup_sleb128_i32); - break; - case WebAssembly::OPERAND_I64IMM: - FixupKind = MCFixupKind(WebAssembly::fixup_sleb128_i64); - PaddedSize = 10; - break; - case WebAssembly::OPERAND_FUNCTION32: - case WebAssembly::OPERAND_TABLE: - case WebAssembly::OPERAND_OFFSET32: - case WebAssembly::OPERAND_SIGNATURE: - case WebAssembly::OPERAND_TYPEINDEX: - case WebAssembly::OPERAND_GLOBAL: - case WebAssembly::OPERAND_TAG: + if (I < Desc.getNumOperands()) { + const MCOperandInfo &Info = Desc.operands()[I]; + switch (Info.OperandType) { + case WebAssembly::OPERAND_I32IMM: + FixupKind = MCFixupKind(WebAssembly::fixup_sleb128_i32); + break; + case WebAssembly::OPERAND_I64IMM: + FixupKind = MCFixupKind(WebAssembly::fixup_sleb128_i64); + PaddedSize = 10; + break; + case WebAssembly::OPERAND_FUNCTION32: + case WebAssembly::OPERAND_TABLE: + case WebAssembly::OPERAND_OFFSET32: + case WebAssembly::OPERAND_SIGNATURE: + case WebAssembly::OPERAND_TYPEINDEX: + case WebAssembly::OPERAND_GLOBAL: + case WebAssembly::OPERAND_TAG: + FixupKind = MCFixupKind(WebAssembly::fixup_uleb128_i32); + break; + case WebAssembly::OPERAND_OFFSET64: + FixupKind = MCFixupKind(WebAssembly::fixup_uleb128_i64); + PaddedSize = 10; + break; + default: + llvm_unreachable("unexpected symbolic operand kind"); + } + } else { + // Variadic expr operands are try_table's catch/catch_ref clauses' tags. + assert(Opcode == WebAssembly::TRY_TABLE_S); FixupKind = MCFixupKind(WebAssembly::fixup_uleb128_i32); - break; - case WebAssembly::OPERAND_OFFSET64: - FixupKind = MCFixupKind(WebAssembly::fixup_uleb128_i64); - PaddedSize = 10; - break; - default: - llvm_unreachable("unexpected symbolic operand kind"); } Fixups.push_back(MCFixup::create(OS.tell() - Start, MO.getExpr(), FixupKind, MI.getLoc())); |
