llvm.org GIT mirror llvm / 2a147a1
[WebAssembly] Remove ELF file support. This support was partial and temporary. Now that we have wasm object file support its no longer needed. Differential Revision: https://reviews.llvm.org/D48744 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337222 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 1 year, 4 months ago
30 changed file(s) with 58 addition(s) and 393 deletion(s). Raw diff Collapse all Expand all
311311 EM_RISCV = 243, // RISC-V
312312 EM_LANAI = 244, // Lanai 32-bit processor
313313 EM_BPF = 247, // Linux kernel bpf virtual machine
314
315 // A request has been made to the maintainer of the official registry for
316 // such numbers for an official value for WebAssembly. As soon as one is
317 // allocated, this enum will be updated to use it.
318 EM_WEBASSEMBLY = 0x4157, // WebAssembly architecture
319314 };
320315
321316 // Object file classes.
641636 // ELF Relocation type for Sparc.
642637 enum {
643638 #include "ELFRelocs/Sparc.def"
644 };
645
646 // ELF Relocation types for WebAssembly
647 enum {
648 #include "ELFRelocs/WebAssembly.def"
649639 };
650640
651641 // AMDGPU specific e_flags.
11741164 PT_MIPS_RTPROC = 0x70000001, // Runtime procedure table.
11751165 PT_MIPS_OPTIONS = 0x70000002, // Options segment.
11761166 PT_MIPS_ABIFLAGS = 0x70000003, // Abiflags segment.
1177
1178 // WebAssembly program header types.
1179 PT_WEBASSEMBLY_FUNCTIONS = PT_LOPROC + 0, // Function definitions.
11801167 };
11811168
11821169 // Segment flag bits.
+0
-8
include/llvm/BinaryFormat/ELFRelocs/WebAssembly.def less more
None
1 #ifndef ELF_RELOC
2 #error "ELF_RELOC must be defined"
3 #endif
4
5 ELF_RELOC(R_WEBASSEMBLY_NONE, 0)
6 ELF_RELOC(R_WEBASSEMBLY_DATA, 1)
7 ELF_RELOC(R_WEBASSEMBLY_FUNCTION, 2)
10251025 case ELF::EM_SPARC:
10261026 case ELF::EM_SPARC32PLUS:
10271027 return "ELF32-sparc";
1028 case ELF::EM_WEBASSEMBLY:
1029 return "ELF32-wasm";
10301028 case ELF::EM_AMDGPU:
10311029 return "ELF32-amdgpu";
10321030 default:
10501048 return "ELF64-sparc";
10511049 case ELF::EM_MIPS:
10521050 return "ELF64-mips";
1053 case ELF::EM_WEBASSEMBLY:
1054 return "ELF64-wasm";
10551051 case ELF::EM_AMDGPU:
10561052 return "ELF64-amdgpu";
10571053 case ELF::EM_BPF:
11131109 return IsLittleEndian ? Triple::sparcel : Triple::sparc;
11141110 case ELF::EM_SPARCV9:
11151111 return Triple::sparcv9;
1116 case ELF::EM_WEBASSEMBLY:
1117 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1118 case ELF::ELFCLASS32: return Triple::wasm32;
1119 case ELF::ELFCLASS64: return Triple::wasm64;
1120 default: return Triple::UnknownArch;
1121 }
11221112
11231113 case ELF::EM_AMDGPU: {
11241114 if (!IsLittleEndian)
5858 textual header "BinaryFormat/ELFRelocs/Sparc.def"
5959 textual header "BinaryFormat/ELFRelocs/SystemZ.def"
6060 textual header "BinaryFormat/ELFRelocs/x86_64.def"
61 textual header "BinaryFormat/ELFRelocs/WebAssembly.def"
6261 textual header "BinaryFormat/WasmRelocs.def"
6362 }
6463
695695 case MCObjectFileInfo::IsWasm:
696696 // TODO: WASM will need its own MCAsmParserExtension implementation, but
697697 // for now we can re-use the ELF one, since the directives can be the
698 // same for now, and this makes the -triple=wasm32-unknown-unknown-wasm
699 // path work.
698 // same for now.
700699 PlatformParser.reset(createELFAsmParser());
701700 break;
702701 }
120120 case ELF::EM_SPARCV9:
121121 switch (Type) {
122122 #include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
123 default:
124 break;
125 }
126 break;
127 case ELF::EM_WEBASSEMBLY:
128 switch (Type) {
129 #include "llvm/BinaryFormat/ELFRelocs/WebAssembly.def"
130123 default:
131124 break;
132125 }
187180 case ELF::EM_SPARC32PLUS:
188181 case ELF::EM_SPARCV9:
189182 return ELF::R_SPARC_RELATIVE;
190 case ELF::EM_WEBASSEMBLY:
191 break;
192183 case ELF::EM_AMDGPU:
193184 break;
194185 case ELF::EM_BPF:
0 add_llvm_library(LLVMWebAssemblyDesc
11 WebAssemblyAsmBackend.cpp
2 WebAssemblyELFObjectWriter.cpp
32 WebAssemblyMCAsmInfo.cpp
43 WebAssemblyMCCodeEmitter.cpp
54 WebAssemblyMCTargetDesc.cpp
1616 #include "llvm/MC/MCAsmBackend.h"
1717 #include "llvm/MC/MCAssembler.h"
1818 #include "llvm/MC/MCDirectives.h"
19 #include "llvm/MC/MCELFObjectWriter.h"
2019 #include "llvm/MC/MCExpr.h"
2120 #include "llvm/MC/MCFixupKindInfo.h"
2221 #include "llvm/MC/MCObjectWriter.h"
2524 #include "llvm/MC/MCWasmObjectWriter.h"
2625 #include "llvm/Support/ErrorHandling.h"
2726 #include "llvm/Support/raw_ostream.h"
27
2828 using namespace llvm;
2929
3030 namespace {
3131
3232 class WebAssemblyAsmBackend final : public MCAsmBackend {
3333 bool Is64Bit;
34 bool IsELF;
3534
36 public:
37 explicit WebAssemblyAsmBackend(bool Is64Bit, bool IsELF)
38 : MCAsmBackend(support::little), Is64Bit(Is64Bit), IsELF(IsELF) {}
35 public:
36 explicit WebAssemblyAsmBackend(bool Is64Bit)
37 : MCAsmBackend(support::little), Is64Bit(Is64Bit) {}
3938 ~WebAssemblyAsmBackend() override {}
4039
4140 unsigned getNumFixupKinds() const override {
125124
126125 std::unique_ptr
127126 WebAssemblyAsmBackend::createObjectTargetWriter() const {
128 return IsELF ? createWebAssemblyELFObjectWriter(Is64Bit, 0)
129 : createWebAssemblyWasmObjectWriter(Is64Bit);
127 return createWebAssemblyWasmObjectWriter(Is64Bit);
130128 }
131129
132130 } // end anonymous namespace
133131
134132 MCAsmBackend *llvm::createWebAssemblyAsmBackend(const Triple &TT) {
135 return new WebAssemblyAsmBackend(TT.isArch64Bit(), TT.isOSBinFormatELF());
133 return new WebAssemblyAsmBackend(TT.isArch64Bit());
136134 }
+0
-65
lib/Target/WebAssembly/MCTargetDesc/WebAssemblyELFObjectWriter.cpp less more
None //===-- WebAssemblyELFObjectWriter.cpp - WebAssembly ELF Writer -----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file handles ELF-specific object emission, converting LLVM's
11 /// internal fixups into the appropriate relocations.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
16 #include "llvm/MC/MCELFObjectWriter.h"
17 #include "llvm/MC/MCFixup.h"
18 #include "llvm/MC/MCObjectWriter.h"
19 #include "llvm/Support/ErrorHandling.h"
20 using namespace llvm;
21
22 namespace {
23 class WebAssemblyELFObjectWriter final : public MCELFObjectTargetWriter {
24 public:
25 WebAssemblyELFObjectWriter(bool Is64Bit, uint8_t OSABI);
26
27 protected:
28 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
29 const MCFixup &Fixup, bool IsPCRel) const override;
30 };
31 } // end anonymous namespace
32
33 WebAssemblyELFObjectWriter::WebAssemblyELFObjectWriter(bool Is64Bit,
34 uint8_t OSABI)
35 : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_WEBASSEMBLY,
36 /*HasRelocationAddend=*/false) {}
37
38 unsigned WebAssemblyELFObjectWriter::getRelocType(MCContext &Ctx,
39 const MCValue &Target,
40 const MCFixup &Fixup,
41 bool IsPCRel) const {
42 // WebAssembly functions are not allocated in the address space. To resolve a
43 // pointer to a function, we must use a special relocation type.
44 if (const MCSymbolRefExpr *SyExp =
45 dyn_cast(Fixup.getValue()))
46 if (SyExp->getKind() == MCSymbolRefExpr::VK_WebAssembly_FUNCTION)
47 return ELF::R_WEBASSEMBLY_FUNCTION;
48
49 switch (Fixup.getKind()) {
50 case FK_Data_4:
51 assert(!is64Bit() && "4-byte relocations only supported on wasm32");
52 return ELF::R_WEBASSEMBLY_DATA;
53 case FK_Data_8:
54 assert(is64Bit() && "8-byte relocations only supported on wasm64");
55 return ELF::R_WEBASSEMBLY_DATA;
56 default:
57 llvm_unreachable("unimplemented fixup kind");
58 }
59 }
60
61 std::unique_ptr
62 llvm::createWebAssemblyELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
63 return llvm::make_unique(Is64Bit, OSABI);
64 }
1414
1515 #include "WebAssemblyMCAsmInfo.h"
1616 #include "llvm/ADT/Triple.h"
17
1718 using namespace llvm;
1819
1920 #define DEBUG_TYPE "wasm-mc-asm-info"
20
21 WebAssemblyMCAsmInfoELF::~WebAssemblyMCAsmInfoELF() {}
22
23 WebAssemblyMCAsmInfoELF::WebAssemblyMCAsmInfoELF(const Triple &T) {
24 CodePointerSize = CalleeSaveStackSlotSize = T.isArch64Bit() ? 8 : 4;
25
26 // TODO: What should MaxInstLength be?
27
28 UseDataRegionDirectives = true;
29
30 // Use .skip instead of .zero because .zero is confusing when used with two
31 // arguments (it doesn't actually zero things out).
32 ZeroDirective = "\t.skip\t";
33
34 Data8bitsDirective = "\t.int8\t";
35 Data16bitsDirective = "\t.int16\t";
36 Data32bitsDirective = "\t.int32\t";
37 Data64bitsDirective = "\t.int64\t";
38
39 AlignmentIsInBytes = false;
40 COMMDirectiveAlignmentIsInBytes = false;
41 LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
42
43 SupportsDebugInformation = true;
44
45 // TODO: UseIntegratedAssembler?
46
47 // WebAssembly's stack is never executable.
48 UsesNonexecutableStackSection = false;
49 }
5021
5122 WebAssemblyMCAsmInfo::~WebAssemblyMCAsmInfo() {}
5223
1414 #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCASMINFO_H
1515 #define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCASMINFO_H
1616
17 #include "llvm/MC/MCAsmInfoELF.h"
1817 #include "llvm/MC/MCAsmInfoWasm.h"
1918
2019 namespace llvm {
2120
2221 class Triple;
23
24 class WebAssemblyMCAsmInfoELF final : public MCAsmInfoELF {
25 public:
26 explicit WebAssemblyMCAsmInfoELF(const Triple &T);
27 ~WebAssemblyMCAsmInfoELF() override;
28 };
2922
3023 class WebAssemblyMCAsmInfo final : public MCAsmInfoWasm {
3124 public:
3535
3636 static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo & /*MRI*/,
3737 const Triple &TT) {
38 if (TT.isOSBinFormatELF())
39 return new WebAssemblyMCAsmInfoELF(TT);
4038 return new WebAssemblyMCAsmInfo(TT);
4139 }
4240
8179
8280 static MCTargetStreamer *
8381 createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
84 const Triple &TT = STI.getTargetTriple();
85 if (TT.isOSBinFormatELF())
86 return new WebAssemblyTargetELFStreamer(S);
87
8882 return new WebAssemblyTargetWasmStreamer(S);
8983 }
9084
3838 MCCodeEmitter *createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII);
3939
4040 MCAsmBackend *createWebAssemblyAsmBackend(const Triple &TT);
41
42 std::unique_ptr
43 createWebAssemblyELFObjectWriter(bool Is64Bit, uint8_t OSABI);
4441
4542 std::unique_ptr
4643 createWebAssemblyWasmObjectWriter(bool Is64Bit);
1616 #include "InstPrinter/WebAssemblyInstPrinter.h"
1717 #include "WebAssemblyMCTargetDesc.h"
1818 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCSectionELF.h"
2019 #include "llvm/MC/MCSectionWasm.h"
2120 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/MC/MCSymbolELF.h"
2321 #include "llvm/MC/MCSymbolWasm.h"
2422 #include "llvm/Support/Casting.h"
2523 #include "llvm/Support/ErrorHandling.h"
3634 WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
3735 MCStreamer &S, formatted_raw_ostream &OS)
3836 : WebAssemblyTargetStreamer(S), OS(OS) {}
39
40 WebAssemblyTargetELFStreamer::WebAssemblyTargetELFStreamer(MCStreamer &S)
41 : WebAssemblyTargetStreamer(S) {}
4237
4338 WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
4439 : WebAssemblyTargetStreamer(S) {}
115110 OS << "\t.indidx \t" << *Value << '\n';
116111 }
117112
118 void WebAssemblyTargetELFStreamer::emitParam(MCSymbol *Symbol,
119 ArrayRef Types) {
120 // Nothing to emit; params are declared as part of the function signature.
121 }
122
123 void WebAssemblyTargetELFStreamer::emitResult(MCSymbol *Symbol,
124 ArrayRef Types) {
125 // Nothing to emit; results are declared as part of the function signature.
126 }
127
128 void WebAssemblyTargetELFStreamer::emitLocal(ArrayRef Types) {
129 Streamer.EmitULEB128IntValue(Types.size());
130 for (MVT Type : Types)
131 emitValueType(WebAssembly::toValType(Type));
132 }
133
134 void WebAssemblyTargetELFStreamer::emitEndFunc() {
135 Streamer.EmitIntValue(WebAssembly::End, 1);
136 }
137
138 void WebAssemblyTargetELFStreamer::emitIndIdx(const MCExpr *Value) {
139 llvm_unreachable(".indidx encoding not yet implemented");
140 }
141
142 void WebAssemblyTargetELFStreamer::emitIndirectFunctionType(
143 MCSymbol *Symbol, SmallVectorImpl &Params, SmallVectorImpl &Results) {
144 // Nothing to emit here. TODO: Re-design how linking works and re-evaluate
145 // whether it's necessary for .o files to declare indirect function types.
146 }
147
148 void WebAssemblyTargetELFStreamer::emitGlobalImport(StringRef name) {
149 }
150
151 void WebAssemblyTargetELFStreamer::emitImportModule(MCSymbolWasm *Sym,
152 StringRef ModuleName) {
153 llvm_unreachable(".import_module encoding not yet implemented");
154 }
155
156113 void WebAssemblyTargetWasmStreamer::emitParam(MCSymbol *Symbol,
157114 ArrayRef Types) {
158115 SmallVector Params;
2121
2222 namespace llvm {
2323
24 class MCELFStreamer;
2524 class MCWasmStreamer;
2625 class MCSymbolWasm;
2726
7372 void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) override;
7473 };
7574
76 /// This part is for ELF object output
77 class WebAssemblyTargetELFStreamer final : public WebAssemblyTargetStreamer {
78 public:
79 explicit WebAssemblyTargetELFStreamer(MCStreamer &S);
80
81 void emitParam(MCSymbol *Symbol, ArrayRef Types) override;
82 void emitResult(MCSymbol *Symbol, ArrayRef Types) override;
83 void emitLocal(ArrayRef Types) override;
84 void emitEndFunc() override;
85 void emitIndirectFunctionType(MCSymbol *Symbol,
86 SmallVectorImpl &Params,
87 SmallVectorImpl &Results) override;
88 void emitIndIdx(const MCExpr *Value) override;
89 void emitGlobalImport(StringRef name) override;
90 void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) override;
91 };
92
9375 /// This part is for Wasm object output
9476 class WebAssemblyTargetWasmStreamer final : public WebAssemblyTargetStreamer {
9577 public:
3333 #include "llvm/MC/MCSectionWasm.h"
3434 #include "llvm/MC/MCStreamer.h"
3535 #include "llvm/MC/MCSymbol.h"
36 #include "llvm/MC/MCSymbolELF.h"
3736 #include "llvm/MC/MCSymbolWasm.h"
3837 #include "llvm/Support/Debug.h"
3938 #include "llvm/Support/TargetRegistry.h"
10099 if (!G.hasInitializer() && G.hasExternalLinkage()) {
101100 if (G.getValueType()->isSized()) {
102101 uint16_t Size = M.getDataLayout().getTypeAllocSize(G.getValueType());
103 if (TM.getTargetTriple().isOSBinFormatELF())
104 getTargetStreamer()->emitGlobalImport(G.getGlobalIdentifier());
105102 OutStreamer->emitELFSize(getSymbol(&G),
106103 MCConstantExpr::create(Size, OutContext));
107104 }
161158 else
162159 getTargetStreamer()->emitResult(CurrentFnSym, ArrayRef());
163160
164 if (TM.getTargetTriple().isOSBinFormatELF()) {
165 assert(MFI->getLocals().empty());
166 for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
167 unsigned VReg = TargetRegisterInfo::index2VirtReg(Idx);
168 unsigned WAReg = MFI->getWAReg(VReg);
169 // Don't declare unused registers.
170 if (WAReg == WebAssemblyFunctionInfo::UnusedReg)
171 continue;
172 // Don't redeclare parameters.
173 if (WAReg < MFI->getParams().size())
174 continue;
175 // Don't declare stackified registers.
176 if (int(WAReg) < 0)
177 continue;
178 MFI->addLocal(getRegType(VReg));
179 }
180 }
181
182161 getTargetStreamer()->emitLocal(MFI->getLocals());
183162
184163 AsmPrinter::EmitFunctionBodyStart();
185 }
186
187 void WebAssemblyAsmPrinter::EmitFunctionBodyEnd() {
188 if (TM.getTargetTriple().isOSBinFormatELF())
189 getTargetStreamer()->emitEndFunc();
190164 }
191165
192166 void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
5656 void EmitJumpTableInfo() override;
5757 void EmitConstantPool() override;
5858 void EmitFunctionBodyStart() override;
59 void EmitFunctionBodyEnd() override;
6059 void EmitInstruction(const MachineInstr *MI) override;
6160 const MCExpr *lowerConstant(const Constant *CV) override;
6261 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
357357 FixEndsAtEndOfFunction(MF, MFI, BlockTops, LoopTops);
358358
359359 // Add an end instruction at the end of the function body.
360 if (!MF.getSubtarget()
361 .getTargetTriple().isOSBinFormatELF())
362 AppendEndToFunction(MF, TII);
360 AppendEndToFunction(MF, TII);
363361 }
364362
365363 bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
186186
187187 // Disable this pass if directed to do so.
188188 if (DisableWebAssemblyExplicitLocals)
189 return false;
190
191 // Disable this pass if we aren't doing direct wasm object emission.
192 if (MF.getSubtarget()
193 .getTargetTriple().isOSBinFormatELF())
194189 return false;
195190
196191 bool Changed = false;
105105
106106 const char *ES = "__stack_pointer";
107107 auto *SPSymbol = MF.createExternalSymbolName(ES);
108 if (MF.getSubtarget()
109 .getTargetTriple().isOSBinFormatELF()) {
110 MachineRegisterInfo &MRI = MF.getRegInfo();
111 const TargetRegisterClass *PtrRC =
112 MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
113 unsigned Zero = MRI.createVirtualRegister(PtrRC);
114
115 BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), Zero)
116 .addImm(0);
117 MachineMemOperand *MMO = MF.getMachineMemOperand(
118 MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
119 MachineMemOperand::MOStore, 4, 4);
120 BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32))
121 .addImm(2) // p2align
122 .addExternalSymbol(SPSymbol)
123 .addReg(Zero)
124 .addReg(SrcReg)
125 .addMemOperand(MMO);
126 } else {
127 BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::SET_GLOBAL_I32))
128 .addExternalSymbol(SPSymbol)
129 .addReg(SrcReg);
130 }
108 BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::SET_GLOBAL_I32))
109 .addExternalSymbol(SPSymbol)
110 .addReg(SrcReg);
131111 }
132112
133113 MachineBasicBlock::iterator
171151
172152 const char *ES = "__stack_pointer";
173153 auto *SPSymbol = MF.createExternalSymbolName(ES);
174 if (MF.getSubtarget()
175 .getTargetTriple().isOSBinFormatELF()) {
176 unsigned Zero = MRI.createVirtualRegister(PtrRC);
177
178 BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), Zero)
179 .addImm(0);
180 MachineMemOperand *LoadMMO = MF.getMachineMemOperand(
181 MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
182 MachineMemOperand::MOLoad, 4, 4);
183 // Load the SP value.
184 BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32), SPReg)
185 .addImm(2) // p2align
186 .addExternalSymbol(SPSymbol)
187 .addReg(Zero) // addr
188 .addMemOperand(LoadMMO);
189 } else {
190 BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GET_GLOBAL_I32), SPReg)
191 .addExternalSymbol(SPSymbol);
192 }
154 BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GET_GLOBAL_I32), SPReg)
155 .addExternalSymbol(SPSymbol);
193156
194157 bool HasBP = hasBP(MF);
195158 if (HasBP) {
2424 #include "llvm/MC/MCContext.h"
2525 #include "llvm/MC/MCExpr.h"
2626 #include "llvm/MC/MCInst.h"
27 #include "llvm/MC/MCSymbolELF.h"
2827 #include "llvm/MC/MCSymbolWasm.h"
2928 #include "llvm/Support/ErrorHandling.h"
3029 #include "llvm/Support/raw_ostream.h"
3332 MCSymbol *
3433 WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
3534 const GlobalValue *Global = MO.getGlobal();
36 MCSymbol *Sym = Printer.getSymbol(Global);
37 if (isa(Sym))
38 return Sym;
39
40 MCSymbolWasm *WasmSym = cast(Sym);
35 MCSymbolWasm *WasmSym = cast(Printer.getSymbol(Global));
4136
4237 if (const auto *FuncTy = dyn_cast(Global->getValueType())) {
4338 const MachineFunction &MF = *MO.getParent()->getParent()->getParent();
8277 MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
8378 const MachineOperand &MO) const {
8479 const char *Name = MO.getSymbolName();
85 MCSymbol *Sym = Printer.GetExternalSymbolSymbol(Name);
86 if (isa(Sym))
87 return Sym;
88
89 MCSymbolWasm *WasmSym = cast(Sym);
80 MCSymbolWasm *WasmSym =
81 cast(Printer.GetExternalSymbolSymbol(Name));
9082 const WebAssemblySubtarget &Subtarget = Printer.getSubtarget();
9183
9284 // __stack_pointer is a global variable; all other external symbols used by
176168 const MCOperandInfo &Info = Desc.OpInfo[i];
177169 if (Info.OperandType == WebAssembly::OPERAND_TYPEINDEX) {
178170 MCSymbol *Sym = Printer.createTempSymbol("typeindex");
179 if (!isa(Sym)) {
180 SmallVector Returns;
181 SmallVector Params;
182
183 const MachineRegisterInfo &MRI =
184 MI->getParent()->getParent()->getRegInfo();
185 for (const MachineOperand &MO : MI->defs())
186 Returns.push_back(getType(MRI.getRegClass(MO.getReg())));
187 for (const MachineOperand &MO : MI->explicit_uses())
188 if (MO.isReg())
189 Params.push_back(getType(MRI.getRegClass(MO.getReg())));
190
191 // call_indirect instructions have a callee operand at the end which
192 // doesn't count as a param.
193 if (WebAssembly::isCallIndirect(*MI))
194 Params.pop_back();
195
196 MCSymbolWasm *WasmSym = cast(Sym);
197 WasmSym->setReturns(std::move(Returns));
198 WasmSym->setParams(std::move(Params));
199 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
200
201 const MCExpr *Expr =
202 MCSymbolRefExpr::create(WasmSym,
203 MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX,
204 Ctx);
205 MCOp = MCOperand::createExpr(Expr);
206 break;
207 }
171
172 SmallVector Returns;
173 SmallVector Params;
174
175 const MachineRegisterInfo &MRI =
176 MI->getParent()->getParent()->getRegInfo();
177 for (const MachineOperand &MO : MI->defs())
178 Returns.push_back(getType(MRI.getRegClass(MO.getReg())));
179 for (const MachineOperand &MO : MI->explicit_uses())
180 if (MO.isReg())
181 Params.push_back(getType(MRI.getRegClass(MO.getReg())));
182
183 // call_indirect instructions have a callee operand at the end which
184 // doesn't count as a param.
185 if (WebAssembly::isCallIndirect(*MI))
186 Params.pop_back();
187
188 MCSymbolWasm *WasmSym = cast(Sym);
189 WasmSym->setReturns(std::move(Returns));
190 WasmSym->setParams(std::move(Params));
191 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
192
193 const MCExpr *Expr = MCSymbolRefExpr::create(
194 WasmSym, MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX, Ctx);
195 MCOp = MCOperand::createExpr(Expr);
196 break;
208197 }
209198 }
210199 MCOp = MCOperand::createImm(MO.getImm());
8282 return false;
8383 if (&MBB != &MF.back())
8484 return false;
85 if (MF.getSubtarget()
86 .getTargetTriple().isOSBinFormatELF()) {
87 if (&MI != &MBB.back())
88 return false;
89 } else {
90 MachineBasicBlock::iterator End = MBB.end();
91 --End;
92 assert(End->getOpcode() == WebAssembly::END_FUNCTION);
93 --End;
94 if (&MI != &*End)
95 return false;
96 }
85
86 MachineBasicBlock::iterator End = MBB.end();
87 --End;
88 assert(End->getOpcode() == WebAssembly::END_FUNCTION);
89 --End;
90 if (&MI != &*End)
91 return false;
9792
9893 if (FallthroughOpc != WebAssembly::FALLTHROUGH_RETURN_VOID) {
9994 // If the operand isn't stackified, insert a COPY to read the operand and
748748 MachineDominatorTree &MDT = getAnalysis();
749749 LiveIntervals &LIS = getAnalysis();
750750
751 // Disable the TEE optimization if we aren't doing direct wasm object
752 // emission, because lowering TEE to TEE_LOCAL is done in the ExplicitLocals
753 // pass, which is also disabled.
754 bool UseTee = true;
755 if (MF.getSubtarget()
756 .getTargetTriple().isOSBinFormatELF())
757 UseTee = false;
758
759751 // Walk the instructions from the bottom up. Currently we don't look past
760752 // block boundaries, and the blocks aren't ordered so the block visitation
761753 // order isn't significant, but we may want to change this in the future.
821813 Insert =
822814 RematerializeCheapDef(Reg, Op, *Def, MBB, Insert->getIterator(),
823815 LIS, MFI, MRI, TII, TRI);
824 } else if (UseTee && CanMove &&
816 } else if (CanMove &&
825817 OneUseDominatesOtherUses(Reg, Op, MBB, MRI, MDT, LIS, MFI)) {
826818 Insert = MoveAndTeeForMultiUse(Reg, Op, Def, MBB, Insert, LIS, MFI,
827819 MRI, TII);
9696 : "e-m:e-p:32:32-i64:64-n32:64-S128",
9797 TT, CPU, FS, Options, getEffectiveRelocModel(RM),
9898 CM ? *CM : CodeModel::Large, OL),
99 TLOF(TT.isOSBinFormatELF() ?
100 static_cast(
101 new WebAssemblyTargetObjectFileELF()) :
102 static_cast(
103 new WebAssemblyTargetObjectFile())) {
99 TLOF(new WebAssemblyTargetObjectFile()) {
104100 // WebAssembly type-checks instructions, but a noreturn function with a return
105101 // type that doesn't match the context will cause a check failure. So we lower
106102 // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
109105
110106 // WebAssembly treats each function as an independent unit. Force
111107 // -ffunction-sections, effectively, so that we can emit them independently.
112 if (!TT.isOSBinFormatELF()) {
113 this->Options.FunctionSections = true;
114 this->Options.DataSections = true;
115 this->Options.UniqueSectionNames = true;
116 }
108 this->Options.FunctionSections = true;
109 this->Options.DataSections = true;
110 this->Options.UniqueSectionNames = true;
117111
118112 initAsmInfo();
119113
1414
1515 #include "WebAssemblyTargetObjectFile.h"
1616 #include "WebAssemblyTargetMachine.h"
17
1718 using namespace llvm;
18
19 void WebAssemblyTargetObjectFileELF::Initialize(MCContext &Ctx,
20 const TargetMachine &TM) {
21 TargetLoweringObjectFileELF::Initialize(Ctx, TM);
22 InitializeELF(TM.Options.UseInitArray);
23 }
2419
2520 void WebAssemblyTargetObjectFile::Initialize(MCContext &Ctx,
2621 const TargetMachine &TM) {
1919
2020 namespace llvm {
2121
22 class WebAssemblyTargetObjectFileELF final
23 : public TargetLoweringObjectFileELF {
24 public:
25 void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
26 };
27
2822 class WebAssemblyTargetObjectFile final : public TargetLoweringObjectFileWasm {
2923 public:
3024 void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
None # RUN: llvm-mc -triple=wasm32-unknown-unknown-elf < %s | FileCheck %s
1 # RUN: llvm-mc -triple=wasm32-unknown-unknown < %s | FileCheck %s
21
32 .text
10611061 ENUM_ENT(EM_56800EX, "EM_56800EX"),
10621062 ENUM_ENT(EM_AMDGPU, "EM_AMDGPU"),
10631063 ENUM_ENT(EM_RISCV, "RISC-V"),
1064 ENUM_ENT(EM_WEBASSEMBLY, "EM_WEBASSEMBLY"),
10651064 ENUM_ENT(EM_LANAI, "EM_LANAI"),
10661065 ENUM_ENT(EM_BPF, "EM_BPF"),
10671066 };
10481048 EXPECT_EQ(Triple::Wasm,
10491049 Triple("wasm64-unknown-unknown-wasm").getObjectFormat());
10501050
1051 EXPECT_EQ(Triple::ELF,
1052 Triple("wasm32-unknown-unknown-elf").getObjectFormat());
1053 EXPECT_EQ(Triple::ELF,
1054 Triple("wasm64-unknown-unknown-elf").getObjectFormat());
1055
10561051 Triple MSVCNormalized(Triple::normalize("i686-pc-windows-msvc-elf"));
10571052 EXPECT_EQ(Triple::ELF, MSVCNormalized.getObjectFormat());
10581053
7171 uint8_t *BytesP = Bytes;
7272 const char OutStringSize = 100;
7373 char OutString[OutStringSize];
74 LLVMDisasmContextRef DCR = LLVMCreateDisasm(
75 "wasm32-unknown-unknown-elf", nullptr, 0, nullptr, symbolLookupCallback);
74 LLVMDisasmContextRef DCR = LLVMCreateDisasm("wasm32-unknown-unknown", nullptr,
75 0, nullptr, symbolLookupCallback);
7676 if (!DCR)
7777 return;
7878