diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly/MCTargetDesc')
9 files changed, 190 insertions, 89 deletions
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp index 8ecd7c53621d..d88311197c1a 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp @@ -59,11 +59,6 @@ public: return false; } - bool mayNeedRelaxation(const MCInst &Inst, - const MCSubtargetInfo &STI) const override { - return false; - } - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; }; diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp index f60b5fcd14ec..fb8b0c364f30 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp @@ -94,19 +94,18 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address, case WebAssembly::LOOP_S: printAnnotation(OS, "label" + utostr(ControlFlowCounter) + ':'); ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, true)); - break; + return; case WebAssembly::BLOCK: case WebAssembly::BLOCK_S: ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false)); - break; + return; case WebAssembly::TRY: case WebAssembly::TRY_S: - ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false)); - EHPadStack.push_back(EHPadStackCounter++); - LastSeenEHInst = TRY; - break; + ControlFlowStack.push_back(std::make_pair(ControlFlowCounter, false)); + EHPadStack.push_back(ControlFlowCounter++); + return; case WebAssembly::END_LOOP: case WebAssembly::END_LOOP_S: @@ -115,7 +114,7 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address, } else { ControlFlowStack.pop_back(); } - break; + return; case WebAssembly::END_BLOCK: case WebAssembly::END_BLOCK_S: @@ -125,7 +124,7 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address, printAnnotation( OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':'); } - break; + return; case WebAssembly::END_TRY: case WebAssembly::END_TRY_S: @@ -134,60 +133,60 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address, } else { printAnnotation( OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':'); - LastSeenEHInst = END_TRY; } - break; + return; case WebAssembly::CATCH: case WebAssembly::CATCH_S: + case WebAssembly::CATCH_ALL: + case WebAssembly::CATCH_ALL_S: if (EHPadStack.empty()) { printAnnotation(OS, "try-catch mismatch!"); } else { printAnnotation(OS, "catch" + utostr(EHPadStack.pop_back_val()) + ':'); } - break; - } - - // Annotate any control flow label references. + return; - // rethrow instruction does not take any depth argument and rethrows to the - // nearest enclosing catch scope, if any. If there's no enclosing catch - // scope, it throws up to the caller. - if (Opc == WebAssembly::RETHROW || Opc == WebAssembly::RETHROW_S) { + case WebAssembly::RETHROW: + case WebAssembly::RETHROW_S: + // 'rethrow' rethrows to the nearest enclosing catch scope, if any. If + // there's no enclosing catch scope, it throws up to the caller. if (EHPadStack.empty()) { printAnnotation(OS, "to caller"); } else { printAnnotation(OS, "down to catch" + utostr(EHPadStack.back())); } + return; + } - } else { - unsigned NumFixedOperands = Desc.NumOperands; - SmallSet<uint64_t, 8> Printed; - for (unsigned I = 0, E = MI->getNumOperands(); I < E; ++I) { - // See if this operand denotes a basic block target. - if (I < NumFixedOperands) { - // A non-variable_ops operand, check its type. - if (Desc.OpInfo[I].OperandType != WebAssembly::OPERAND_BASIC_BLOCK) - continue; - } else { - // A variable_ops operand, which currently can be immediates (used in - // br_table) which are basic block targets, or for call instructions - // when using -wasm-keep-registers (in which case they are registers, - // and should not be processed). - if (!MI->getOperand(I).isImm()) - continue; - } - uint64_t Depth = MI->getOperand(I).getImm(); - if (!Printed.insert(Depth).second) + // Annotate any control flow label references. + + unsigned NumFixedOperands = Desc.NumOperands; + SmallSet<uint64_t, 8> Printed; + for (unsigned I = 0, E = MI->getNumOperands(); I < E; ++I) { + // See if this operand denotes a basic block target. + if (I < NumFixedOperands) { + // A non-variable_ops operand, check its type. + if (Desc.OpInfo[I].OperandType != WebAssembly::OPERAND_BASIC_BLOCK) continue; - if (Depth >= ControlFlowStack.size()) { - printAnnotation(OS, "Invalid depth argument!"); - } else { - const auto &Pair = ControlFlowStack.rbegin()[Depth]; - printAnnotation(OS, utostr(Depth) + ": " + - (Pair.second ? "up" : "down") + " to label" + - utostr(Pair.first)); - } + } else { + // A variable_ops operand, which currently can be immediates (used in + // br_table) which are basic block targets, or for call instructions + // when using -wasm-keep-registers (in which case they are registers, + // and should not be processed). + if (!MI->getOperand(I).isImm()) + continue; + } + uint64_t Depth = MI->getOperand(I).getImm(); + if (!Printed.insert(Depth).second) + continue; + if (Depth >= ControlFlowStack.size()) { + printAnnotation(OS, "Invalid depth argument!"); + } else { + const auto &Pair = ControlFlowStack.rbegin()[Depth]; + printAnnotation(OS, utostr(Depth) + ": " + + (Pair.second ? "up" : "down") + " to label" + + utostr(Pair.first)); } } } @@ -302,6 +301,29 @@ void WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI, } } +void WebAssemblyInstPrinter::printWebAssemblyHeapTypeOperand(const MCInst *MI, + unsigned OpNo, + raw_ostream &O) { + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isImm()) { + switch (Op.getImm()) { + case long(wasm::ValType::EXTERNREF): + O << "extern"; + break; + case long(wasm::ValType::FUNCREF): + O << "func"; + break; + default: + O << "unsupported_heap_type_value"; + break; + } + } else { + // Typed function references and other subtypes of funcref and externref + // currently unimplemented. + O << "unsupported_heap_type_operand"; + } +} + // We have various enums representing a subset of these types, use this // function to convert any of them to text. const char *WebAssembly::anyTypeToString(unsigned Ty) { @@ -318,10 +340,10 @@ const char *WebAssembly::anyTypeToString(unsigned Ty) { return "v128"; case wasm::WASM_TYPE_FUNCREF: return "funcref"; + case wasm::WASM_TYPE_EXTERNREF: + return "externref"; case wasm::WASM_TYPE_FUNC: return "func"; - case wasm::WASM_TYPE_EXNREF: - return "exnref"; case wasm::WASM_TYPE_NORESULT: return "void"; default: diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h index 1387a1928b3f..2ed6d562acff 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h @@ -25,13 +25,9 @@ class MCSubtargetInfo; class WebAssemblyInstPrinter final : public MCInstPrinter { uint64_t ControlFlowCounter = 0; - uint64_t EHPadStackCounter = 0; SmallVector<std::pair<uint64_t, bool>, 4> ControlFlowStack; SmallVector<uint64_t, 4> EHPadStack; - enum EHInstKind { TRY, CATCH, END_TRY }; - EHInstKind LastSeenEHInst = END_TRY; - public: WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI); @@ -48,8 +44,11 @@ public: raw_ostream &O); void printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printWebAssemblyHeapTypeOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O); // Autogenerated by tblgen. + std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); }; diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp index dfed3451e45b..55bf5d14fdac 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp @@ -62,12 +62,16 @@ void WebAssemblyMCCodeEmitter::encodeInstruction( uint64_t Start = OS.tell(); uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); - if (Binary <= UINT8_MAX) { + if (Binary < (1 << 8)) { OS << uint8_t(Binary); - } else { - assert(Binary <= UINT16_MAX && "Several-byte opcodes not supported yet"); + } else if (Binary < (1 << 16)) { OS << uint8_t(Binary >> 8); encodeULEB128(uint8_t(Binary), OS); + } else if (Binary < (1 << 24)) { + OS << uint8_t(Binary >> 16); + encodeULEB128(uint16_t(Binary), OS); + } else { + llvm_unreachable("Very large (prefix + 3 byte) opcodes not supported"); } // For br_table instructions, encode the size of the table. In the MCInst, @@ -102,6 +106,7 @@ void WebAssemblyMCCodeEmitter::encodeInstruction( encodeSLEB128(int64_t(MO.getImm()), OS); break; case WebAssembly::OPERAND_SIGNATURE: + case WebAssembly::OPERAND_HEAPTYPE: OS << uint8_t(MO.getImm()); break; case WebAssembly::OPERAND_VEC_I8IMM: @@ -151,6 +156,7 @@ void WebAssemblyMCCodeEmitter::encodeInstruction( PaddedSize = 10; break; case WebAssembly::OPERAND_FUNCTION32: + case WebAssembly::OPERAND_TABLE: case WebAssembly::OPERAND_OFFSET32: case WebAssembly::OPERAND_SIGNATURE: case WebAssembly::OPERAND_TYPEINDEX: diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp index 027e5408c633..064e613cfc8e 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp @@ -76,7 +76,7 @@ static MCAsmBackend *createAsmBackend(const Target & /*T*/, static MCSubtargetInfo *createMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { - return createWebAssemblyMCSubtargetInfoImpl(TT, CPU, FS); + return createWebAssemblyMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS); } static MCTargetStreamer * @@ -147,8 +147,10 @@ wasm::ValType WebAssembly::toValType(const MVT &Ty) { case MVT::v4f32: case MVT::v2f64: return wasm::ValType::V128; - case MVT::exnref: - return wasm::ValType::EXNREF; + case MVT::funcref: + return wasm::ValType::FUNCREF; + case MVT::externref: + return wasm::ValType::EXTERNREF; default: llvm_unreachable("unexpected type"); } diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h index 02b310628ee1..5b77b8495adf 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -76,6 +76,10 @@ enum OperandType { OPERAND_EVENT, /// A list of branch targets for br_list. OPERAND_BRLIST, + /// 32-bit unsigned table number. + OPERAND_TABLE, + /// heap type immediate for ref.null. + OPERAND_HEAPTYPE, }; } // end namespace WebAssembly @@ -97,6 +101,11 @@ enum TOF { MO_MEMORY_BASE_REL, // On a symbol operand this indicates that the immediate is the symbol + // address relative the __tls_base wasm global. + // Only applicable to data symbols. + MO_TLS_BASE_REL, + + // On a symbol operand this indicates that the immediate is the symbol // address relative the __table_base wasm global. // Only applicable to function symbols. MO_TABLE_BASE_REL, @@ -129,7 +138,8 @@ enum class BlockType : unsigned { F32 = unsigned(wasm::ValType::F32), F64 = unsigned(wasm::ValType::F64), V128 = unsigned(wasm::ValType::V128), - Exnref = unsigned(wasm::ValType::EXNREF), + Externref = unsigned(wasm::ValType::EXTERNREF), + Funcref = unsigned(wasm::ValType::FUNCREF), // Multivalue blocks (and other non-void blocks) are only emitted when the // blocks will never be exited and are at the ends of functions (see // WebAssemblyCFGStackify::fixEndsAtEndOfFunction). They also are never made @@ -138,6 +148,13 @@ enum class BlockType : unsigned { Multivalue = 0xffff, }; +/// Used as immediate MachineOperands for heap types, e.g. for ref.null. +enum class HeapType : unsigned { + Invalid = 0x00, + Externref = unsigned(wasm::ValType::EXTERNREF), + Funcref = unsigned(wasm::ValType::FUNCREF), +}; + /// Instruction opcodes emitted via means other than CodeGen. static const unsigned Nop = 0x01; static const unsigned End = 0x0b; @@ -176,8 +193,12 @@ inline unsigned GetDefaultP2AlignAny(unsigned Opc) { WASM_LOAD_STORE(ATOMIC_RMW8_U_XCHG_I64) WASM_LOAD_STORE(ATOMIC_RMW8_U_CMPXCHG_I32) WASM_LOAD_STORE(ATOMIC_RMW8_U_CMPXCHG_I64) - WASM_LOAD_STORE(LOAD_SPLAT_v8x16) - return 0; + WASM_LOAD_STORE(LOAD8_SPLAT) + WASM_LOAD_STORE(LOAD_LANE_I8x16) + WASM_LOAD_STORE(STORE_LANE_I8x16) + WASM_LOAD_STORE(PREFETCH_T) + WASM_LOAD_STORE(PREFETCH_NT) + return 0; WASM_LOAD_STORE(LOAD16_S_I32) WASM_LOAD_STORE(LOAD16_U_I32) WASM_LOAD_STORE(LOAD16_S_I64) @@ -202,8 +223,10 @@ inline unsigned GetDefaultP2AlignAny(unsigned Opc) { WASM_LOAD_STORE(ATOMIC_RMW16_U_XCHG_I64) WASM_LOAD_STORE(ATOMIC_RMW16_U_CMPXCHG_I32) WASM_LOAD_STORE(ATOMIC_RMW16_U_CMPXCHG_I64) - WASM_LOAD_STORE(LOAD_SPLAT_v16x8) - return 1; + WASM_LOAD_STORE(LOAD16_SPLAT) + WASM_LOAD_STORE(LOAD_LANE_I16x8) + WASM_LOAD_STORE(STORE_LANE_I16x8) + return 1; WASM_LOAD_STORE(LOAD_I32) WASM_LOAD_STORE(LOAD_F32) WASM_LOAD_STORE(STORE_I32) @@ -229,10 +252,13 @@ inline unsigned GetDefaultP2AlignAny(unsigned Opc) { WASM_LOAD_STORE(ATOMIC_RMW32_U_XCHG_I64) WASM_LOAD_STORE(ATOMIC_RMW_CMPXCHG_I32) WASM_LOAD_STORE(ATOMIC_RMW32_U_CMPXCHG_I64) - WASM_LOAD_STORE(ATOMIC_NOTIFY) - WASM_LOAD_STORE(ATOMIC_WAIT_I32) - WASM_LOAD_STORE(LOAD_SPLAT_v32x4) - return 2; + WASM_LOAD_STORE(MEMORY_ATOMIC_NOTIFY) + WASM_LOAD_STORE(MEMORY_ATOMIC_WAIT32) + WASM_LOAD_STORE(LOAD32_SPLAT) + WASM_LOAD_STORE(LOAD_ZERO_I32x4) + WASM_LOAD_STORE(LOAD_LANE_I32x4) + WASM_LOAD_STORE(STORE_LANE_I32x4) + return 2; WASM_LOAD_STORE(LOAD_I64) WASM_LOAD_STORE(LOAD_F64) WASM_LOAD_STORE(STORE_I64) @@ -246,15 +272,18 @@ inline unsigned GetDefaultP2AlignAny(unsigned Opc) { WASM_LOAD_STORE(ATOMIC_RMW_XOR_I64) WASM_LOAD_STORE(ATOMIC_RMW_XCHG_I64) WASM_LOAD_STORE(ATOMIC_RMW_CMPXCHG_I64) - WASM_LOAD_STORE(ATOMIC_WAIT_I64) - WASM_LOAD_STORE(LOAD_SPLAT_v64x2) - WASM_LOAD_STORE(LOAD_EXTEND_S_v8i16) - WASM_LOAD_STORE(LOAD_EXTEND_U_v8i16) - WASM_LOAD_STORE(LOAD_EXTEND_S_v4i32) - WASM_LOAD_STORE(LOAD_EXTEND_U_v4i32) - WASM_LOAD_STORE(LOAD_EXTEND_S_v2i64) - WASM_LOAD_STORE(LOAD_EXTEND_U_v2i64) - return 3; + WASM_LOAD_STORE(MEMORY_ATOMIC_WAIT64) + WASM_LOAD_STORE(LOAD64_SPLAT) + WASM_LOAD_STORE(LOAD_EXTEND_S_I16x8) + WASM_LOAD_STORE(LOAD_EXTEND_U_I16x8) + WASM_LOAD_STORE(LOAD_EXTEND_S_I32x4) + WASM_LOAD_STORE(LOAD_EXTEND_U_I32x4) + WASM_LOAD_STORE(LOAD_EXTEND_S_I64x2) + WASM_LOAD_STORE(LOAD_EXTEND_U_I64x2) + WASM_LOAD_STORE(LOAD_ZERO_I64x2) + WASM_LOAD_STORE(LOAD_LANE_I64x2) + WASM_LOAD_STORE(STORE_LANE_I64x2) + return 3; WASM_LOAD_STORE(LOAD_V128) WASM_LOAD_STORE(STORE_V128) return 4; @@ -294,8 +323,10 @@ inline bool isArgument(unsigned Opc) { case WebAssembly::ARGUMENT_v4f32_S: case WebAssembly::ARGUMENT_v2f64: case WebAssembly::ARGUMENT_v2f64_S: - case WebAssembly::ARGUMENT_exnref: - case WebAssembly::ARGUMENT_exnref_S: + case WebAssembly::ARGUMENT_funcref: + case WebAssembly::ARGUMENT_funcref_S: + case WebAssembly::ARGUMENT_externref: + case WebAssembly::ARGUMENT_externref_S: return true; default: return false; @@ -314,8 +345,10 @@ inline bool isCopy(unsigned Opc) { case WebAssembly::COPY_F64_S: case WebAssembly::COPY_V128: case WebAssembly::COPY_V128_S: - case WebAssembly::COPY_EXNREF: - case WebAssembly::COPY_EXNREF_S: + case WebAssembly::COPY_FUNCREF: + case WebAssembly::COPY_FUNCREF_S: + case WebAssembly::COPY_EXTERNREF: + case WebAssembly::COPY_EXTERNREF_S: return true; default: return false; @@ -334,8 +367,10 @@ inline bool isTee(unsigned Opc) { case WebAssembly::TEE_F64_S: case WebAssembly::TEE_V128: case WebAssembly::TEE_V128_S: - case WebAssembly::TEE_EXNREF: - case WebAssembly::TEE_EXNREF_S: + case WebAssembly::TEE_FUNCREF: + case WebAssembly::TEE_FUNCREF_S: + case WebAssembly::TEE_EXTERNREF: + case WebAssembly::TEE_EXTERNREF_S: return true; default: return false; @@ -398,6 +433,18 @@ inline bool isMarker(unsigned Opc) { } } +inline bool isCatch(unsigned Opc) { + switch (Opc) { + case WebAssembly::CATCH: + case WebAssembly::CATCH_S: + case WebAssembly::CATCH_ALL: + case WebAssembly::CATCH_ALL_S: + return true; + default: + return false; + } +} + } // end namespace WebAssembly } // end namespace llvm diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp index e954eeaebb14..652d7a00a63c 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -71,8 +71,17 @@ void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) { assert(Sym->isGlobal()); OS << "\t.globaltype\t" << Sym->getName() << ", " << WebAssembly::typeToString( - static_cast<wasm::ValType>(Sym->getGlobalType().Type)) - << '\n'; + static_cast<wasm::ValType>(Sym->getGlobalType().Type)); + if (!Sym->getGlobalType().Mutable) + OS << ", immutable"; + OS << '\n'; +} + +void WebAssemblyTargetAsmStreamer::emitTableType(const MCSymbolWasm *Sym) { + assert(Sym->isTable()); + OS << "\t.tabletype\t" << Sym->getName() << ", " + << WebAssembly::typeToString(Sym->getTableType()); + OS << '\n'; } void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) { diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h index d6fba05c9986..75c9fb4e289d 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h @@ -39,6 +39,8 @@ public: virtual void emitIndIdx(const MCExpr *Value) = 0; /// .globaltype virtual void emitGlobalType(const MCSymbolWasm *Sym) = 0; + /// .tabletype + virtual void emitTableType(const MCSymbolWasm *Sym) = 0; /// .eventtype virtual void emitEventType(const MCSymbolWasm *Sym) = 0; /// .import_module @@ -67,6 +69,7 @@ public: void emitFunctionType(const MCSymbolWasm *Sym) override; void emitIndIdx(const MCExpr *Value) override; void emitGlobalType(const MCSymbolWasm *Sym) override; + void emitTableType(const MCSymbolWasm *Sym) override; void emitEventType(const MCSymbolWasm *Sym) override; void emitImportModule(const MCSymbolWasm *Sym, StringRef ImportModule) override; void emitImportName(const MCSymbolWasm *Sym, StringRef ImportName) override; @@ -83,6 +86,7 @@ public: void emitFunctionType(const MCSymbolWasm *Sym) override {} void emitIndIdx(const MCExpr *Value) override; void emitGlobalType(const MCSymbolWasm *Sym) override {} + void emitTableType(const MCSymbolWasm *Sym) override {} void emitEventType(const MCSymbolWasm *Sym) override {} void emitImportModule(const MCSymbolWasm *Sym, StringRef ImportModule) override {} @@ -103,6 +107,7 @@ public: void emitFunctionType(const MCSymbolWasm *) override {} void emitIndIdx(const MCExpr *) override {} void emitGlobalType(const MCSymbolWasm *) override {} + void emitTableType(const MCSymbolWasm *) override {} void emitEventType(const MCSymbolWasm *) override {} void emitImportModule(const MCSymbolWasm *, StringRef) override {} void emitImportName(const MCSymbolWasm *, StringRef) override {} diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp index 779e921c1d94..aa7e2311d240 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp @@ -76,6 +76,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, case MCSymbolRefExpr::VK_WASM_TBREL: assert(SymA.isFunction()); return wasm::R_WASM_TABLE_INDEX_REL_SLEB; + case MCSymbolRefExpr::VK_WASM_TLSREL: + return wasm::R_WASM_MEMORY_ADDR_TLS_SLEB; case MCSymbolRefExpr::VK_WASM_MBREL: assert(SymA.isData()); return is64Bit() ? wasm::R_WASM_MEMORY_ADDR_REL_SLEB64 @@ -92,7 +94,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, return wasm::R_WASM_TABLE_INDEX_SLEB; return wasm::R_WASM_MEMORY_ADDR_SLEB; case WebAssembly::fixup_sleb128_i64: - assert(SymA.isData()); + if (SymA.isFunction()) + return wasm::R_WASM_TABLE_INDEX_SLEB64; return wasm::R_WASM_MEMORY_ADDR_SLEB64; case WebAssembly::fixup_uleb128_i32: if (SymA.isGlobal()) @@ -101,6 +104,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, return wasm::R_WASM_FUNCTION_INDEX_LEB; if (SymA.isEvent()) return wasm::R_WASM_EVENT_INDEX_LEB; + if (SymA.isTable()) + return wasm::R_WASM_TABLE_NUMBER_LEB; return wasm::R_WASM_MEMORY_ADDR_LEB; case WebAssembly::fixup_uleb128_i64: assert(SymA.isData()); @@ -119,6 +124,17 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, } return wasm::R_WASM_MEMORY_ADDR_I32; case FK_Data_8: + if (SymA.isFunction()) + return wasm::R_WASM_TABLE_INDEX_I64; + if (SymA.isGlobal()) + llvm_unreachable("unimplemented R_WASM_GLOBAL_INDEX_I64"); + if (auto Section = static_cast<const MCSectionWasm *>( + getFixupSection(Fixup.getValue()))) { + if (Section->getKind().isText()) + return wasm::R_WASM_FUNCTION_OFFSET_I64; + else if (!Section->isWasmData()) + llvm_unreachable("unimplemented R_WASM_SECTION_OFFSET_I64"); + } assert(SymA.isData()); return wasm::R_WASM_MEMORY_ADDR_I64; default: |