diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp | 99 |
1 files changed, 37 insertions, 62 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp index 86d59ef807ab..ec2380a501ab 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -13,11 +13,11 @@ //===----------------------------------------------------------------------===// #include "WebAssemblyMCInstLower.h" -#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "TargetInfo/WebAssemblyTargetInfo.h" +#include "Utils/WebAssemblyTypeUtilities.h" +#include "Utils/WebAssemblyUtilities.h" #include "WebAssemblyAsmPrinter.h" #include "WebAssemblyMachineFunctionInfo.h" -#include "WebAssemblyRuntimeLibcallSignatures.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/IR/Constants.h" @@ -46,8 +46,28 @@ static void removeRegisterOperands(const MachineInstr *MI, MCInst &OutMI); MCSymbol * WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const { const GlobalValue *Global = MO.getGlobal(); - if (!isa<Function>(Global)) - return cast<MCSymbolWasm>(Printer.getSymbol(Global)); + if (!isa<Function>(Global)) { + auto *WasmSym = cast<MCSymbolWasm>(Printer.getSymbol(Global)); + // If the symbol doesn't have an explicit WasmSymbolType yet and the + // GlobalValue is actually a WebAssembly global, then ensure the symbol is a + // WASM_SYMBOL_TYPE_GLOBAL. + if (WebAssembly::isWasmVarAddressSpace(Global->getAddressSpace()) && + !WasmSym->getType()) { + const MachineFunction &MF = *MO.getParent()->getParent()->getParent(); + const TargetMachine &TM = MF.getTarget(); + const Function &CurrentFunc = MF.getFunction(); + SmallVector<MVT, 1> VTs; + computeLegalValueVTs(CurrentFunc, TM, Global->getValueType(), VTs); + if (VTs.size() != 1) + report_fatal_error("Aggregate globals not yet implemented"); + + bool Mutable = true; + wasm::ValType Type = WebAssembly::toValType(VTs[0]); + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL); + WasmSym->setGlobalType(wasm::WasmGlobalType{uint8_t(Type), Mutable}); + } + return WasmSym; + } const auto *FuncTy = cast<FunctionType>(Global->getValueType()); const MachineFunction &MF = *MO.getParent()->getParent()->getParent(); @@ -71,58 +91,7 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const { MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol( const MachineOperand &MO) const { - const char *Name = MO.getSymbolName(); - auto *WasmSym = cast<MCSymbolWasm>(Printer.GetExternalSymbolSymbol(Name)); - const WebAssemblySubtarget &Subtarget = Printer.getSubtarget(); - - // Except for certain known symbols, all symbols used by CodeGen are - // functions. It's OK to hardcode knowledge of specific symbols here; this - // method is precisely there for fetching the signatures of known - // Clang-provided symbols. - if (strcmp(Name, "__stack_pointer") == 0 || strcmp(Name, "__tls_base") == 0 || - strcmp(Name, "__memory_base") == 0 || strcmp(Name, "__table_base") == 0 || - strcmp(Name, "__tls_size") == 0 || strcmp(Name, "__tls_align") == 0) { - bool Mutable = - strcmp(Name, "__stack_pointer") == 0 || strcmp(Name, "__tls_base") == 0; - WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL); - WasmSym->setGlobalType(wasm::WasmGlobalType{ - uint8_t(Subtarget.hasAddr64() && strcmp(Name, "__table_base") != 0 - ? wasm::WASM_TYPE_I64 - : wasm::WASM_TYPE_I32), - Mutable}); - return WasmSym; - } - - SmallVector<wasm::ValType, 4> Returns; - SmallVector<wasm::ValType, 4> Params; - if (strcmp(Name, "__cpp_exception") == 0) { - WasmSym->setType(wasm::WASM_SYMBOL_TYPE_EVENT); - // We can't confirm its signature index for now because there can be - // imported exceptions. Set it to be 0 for now. - WasmSym->setEventType( - {wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION, /* SigIndex */ 0}); - // We may have multiple C++ compilation units to be linked together, each of - // which defines the exception symbol. To resolve them, we declare them as - // weak. - WasmSym->setWeak(true); - WasmSym->setExternal(true); - - // All C++ exceptions are assumed to have a single i32 (for wasm32) or i64 - // (for wasm64) param type and void return type. The reaon is, all C++ - // exception values are pointers, and to share the type section with - // functions, exceptions are assumed to have void return type. - Params.push_back(Subtarget.hasAddr64() ? wasm::ValType::I64 - : wasm::ValType::I32); - } else { // Function symbols - WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); - getLibcallSignature(Subtarget, Name, Returns, Params); - } - auto Signature = - std::make_unique<wasm::WasmSignature>(std::move(Returns), std::move(Params)); - WasmSym->setSignature(Signature.get()); - Printer.addSignature(std::move(Signature)); - - return WasmSym; + return Printer.getOrCreateWasmSymbol(MO.getSymbolName()); } MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO, @@ -159,8 +128,10 @@ MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO, report_fatal_error("Function addresses with offsets not supported"); if (WasmSym->isGlobal()) report_fatal_error("Global indexes with offsets not supported"); - if (WasmSym->isEvent()) - report_fatal_error("Event indexes with offsets not supported"); + if (WasmSym->isTag()) + report_fatal_error("Tag indexes with offsets not supported"); + if (WasmSym->isTable()) + report_fatal_error("Table indexes with offsets not supported"); Expr = MCBinaryExpr::createAdd( Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); @@ -196,6 +167,10 @@ static wasm::ValType getType(const TargetRegisterClass *RC) { return wasm::ValType::F64; if (RC == &WebAssembly::V128RegClass) return wasm::ValType::V128; + if (RC == &WebAssembly::EXTERNREFRegClass) + return wasm::ValType::EXTERNREF; + if (RC == &WebAssembly::FUNCREFRegClass) + return wasm::ValType::FUNCREF; llvm_unreachable("Unexpected register class"); } @@ -285,13 +260,13 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI, break; } case MachineOperand::MO_FPImmediate: { - // TODO: MC converts all floating point immediate operands to double. - // This is fine for numeric values, but may cause NaNs to change bits. const ConstantFP *Imm = MO.getFPImm(); + const uint64_t BitPattern = + Imm->getValueAPF().bitcastToAPInt().getZExtValue(); if (Imm->getType()->isFloatTy()) - MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToFloat()); + MCOp = MCOperand::createSFPImm(static_cast<uint32_t>(BitPattern)); else if (Imm->getType()->isDoubleTy()) - MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToDouble()); + MCOp = MCOperand::createDFPImm(BitPattern); else llvm_unreachable("unknown floating point immediate type"); break; |