llvm.org GIT mirror llvm / 5731435
[WebAssembly] Experimental ELF writer support This creates the initial infrastructure for writing ELF output files. It doesn't yet have any implementation for encoding instructions. Differential Revision: http://reviews.llvm.org/D15555 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255869 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 3 years ago
9 changed file(s) with 293 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
549549 case Triple::sparc:
550550 case Triple::sparcv9:
551551 case Triple::systemz:
552 case Triple::wasm32:
553 case Triple::wasm64:
552554 case Triple::xcore:
553555 case Triple::ppc64le:
554556 return Triple::ELF;
558560 if (T.isOSDarwin())
559561 return Triple::MachO;
560562 return Triple::ELF;
561
562 case Triple::wasm32:
563 case Triple::wasm64:
564 // Unknown for now, until an object format is specified.
565 return Triple::UnknownObjectFormat;
566563 }
567564
568565 if (T.isOSDarwin())
0 add_llvm_library(LLVMWebAssemblyDesc
1 WebAssemblyAsmBackend.cpp
2 WebAssemblyELFObjectWriter.cpp
13 WebAssemblyMCAsmInfo.cpp
4 WebAssemblyMCCodeEmitter.cpp
25 WebAssemblyMCTargetDesc.cpp
36 )
0 //===-- WebAssemblyAsmBackend.cpp - WebAssembly Assembler Backend ---------===//
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 /// \brief This file implements the WebAssemblyAsmBackend class.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
15 #include "llvm/MC/MCAsmBackend.h"
16 #include "llvm/MC/MCAssembler.h"
17 #include "llvm/MC/MCDirectives.h"
18 #include "llvm/MC/MCELFObjectWriter.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCFixupKindInfo.h"
21 #include "llvm/MC/MCObjectWriter.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/raw_ostream.h"
26 using namespace llvm;
27
28 namespace {
29 class WebAssemblyAsmBackend final : public MCAsmBackend {
30 bool Is64Bit;
31
32 public:
33 explicit WebAssemblyAsmBackend(bool Is64Bit)
34 : MCAsmBackend(), Is64Bit(Is64Bit) {}
35 ~WebAssemblyAsmBackend() override {}
36
37 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
38 uint64_t Value, bool IsPCRel) const override;
39
40 MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
41
42 // No instruction requires relaxation
43 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
44 const MCRelaxableFragment *DF,
45 const MCAsmLayout &Layout) const override {
46 return false;
47 }
48
49 unsigned getNumFixupKinds() const override {
50 // We currently just use the generic fixups in MCFixup.h and don't have any
51 // target-specific fixups.
52 return 0;
53 }
54
55 bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
56
57 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {}
58
59 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
60 };
61
62 bool WebAssemblyAsmBackend::writeNopData(uint64_t Count,
63 MCObjectWriter *OW) const {
64 if (Count == 0)
65 return true;
66
67 // FIXME: Do something.
68 return false;
69 }
70
71 void WebAssemblyAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
72 unsigned DataSize, uint64_t Value,
73 bool IsPCRel) const {
74 const MCFixupKindInfo &Info = getFixupKindInfo(Fixup.getKind());
75 unsigned NumBytes = RoundUpToAlignment(Info.TargetSize, 8);
76 if (!Value)
77 return; // Doesn't change encoding.
78
79 // Shift the value into position.
80 Value <<= Info.TargetOffset;
81
82 unsigned Offset = Fixup.getOffset();
83 assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!");
84
85 // For each byte of the fragment that the fixup touches, mask in the
86 // bits from the fixup value.
87 for (unsigned i = 0; i != NumBytes; ++i)
88 Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
89 }
90
91 MCObjectWriter *
92 WebAssemblyAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
93 return createWebAssemblyELFObjectWriter(OS, Is64Bit, 0);
94 }
95 } // end anonymous namespace
96
97 MCAsmBackend *llvm::createWebAssemblyAsmBackend(const Target &T,
98 const MCRegisterInfo &MRI,
99 const Triple &TT,
100 StringRef CPU) {
101 return new WebAssemblyAsmBackend(TT.isArch64Bit());
102 }
0 //===-- 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 /// \brief 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/Support/ErrorHandling.h"
19 using namespace llvm;
20
21 namespace {
22 class WebAssemblyELFObjectWriter final : public MCELFObjectTargetWriter {
23 public:
24 WebAssemblyELFObjectWriter(bool Is64Bit, uint8_t OSABI);
25
26 ~WebAssemblyELFObjectWriter() override;
27
28 protected:
29 unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
30 bool IsPCRel) const override;
31 };
32 } // end anonymous namespace
33
34 // FIXME: Use EM_NONE as a temporary hack. Should we decide to pursue ELF
35 // writing seriously, we should email generic-abi@googlegroups.com and ask
36 // for our own ELF code.
37 WebAssemblyELFObjectWriter::WebAssemblyELFObjectWriter(bool Is64Bit,
38 uint8_t OSABI)
39 : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_NONE,
40 /*HasRelocationAddend=*/true) {}
41
42 WebAssemblyELFObjectWriter::~WebAssemblyELFObjectWriter() {}
43
44 unsigned WebAssemblyELFObjectWriter::GetRelocType(const MCValue &Target,
45 const MCFixup &Fixup,
46 bool IsPCRel) const {
47 // FIXME: Do we need our own relocs?
48 return Fixup.getKind();
49 }
50
51 MCObjectWriter *llvm::createWebAssemblyELFObjectWriter(raw_pwrite_stream &OS,
52 bool Is64Bit,
53 uint8_t OSABI) {
54 MCELFObjectTargetWriter *MOTW =
55 new WebAssemblyELFObjectWriter(Is64Bit, OSABI);
56 return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true);
57 }
0 //=- WebAssemblyMCCodeEmitter.cpp - Convert WebAssembly code to machine code -//
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 /// \brief This file implements the WebAssemblyMCCodeEmitter class.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
15 #include "llvm/ADT/Statistic.h"
16 #include "llvm/MC/MCCodeEmitter.h"
17 #include "llvm/MC/MCFixup.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/MC/MCSymbol.h"
23 #include "llvm/Support/raw_ostream.h"
24 using namespace llvm;
25
26 #define DEBUG_TYPE "mccodeemitter"
27
28 namespace {
29 class WebAssemblyMCCodeEmitter final : public MCCodeEmitter {
30 const MCInstrInfo &MCII;
31 const MCRegisterInfo &MRI;
32 const MCContext &Ctx;
33
34 public:
35 WebAssemblyMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri,
36 MCContext &ctx)
37 : MCII(mcii), MRI(mri), Ctx(ctx) {}
38
39 ~WebAssemblyMCCodeEmitter() override {}
40
41 /// TableGen'erated function for getting the binary encoding for an
42 /// instruction.
43 uint64_t getBinaryCodeForInstr(const MCInst &MI,
44 SmallVectorImpl &Fixups,
45 const MCSubtargetInfo &STI) const;
46
47 /// Return binary encoding of operand. If the machine operand requires
48 /// relocation, record the relocation and return zero.
49 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
50 SmallVectorImpl &Fixups,
51 const MCSubtargetInfo &STI) const;
52
53 uint64_t getMemoryOpValue(const MCInst &MI, unsigned Op,
54 SmallVectorImpl &Fixups,
55 const MCSubtargetInfo &STI) const;
56
57 void encodeInstruction(const MCInst &MI, raw_ostream &OS,
58 SmallVectorImpl &Fixups,
59 const MCSubtargetInfo &STI) const override;
60 };
61 } // end anonymous namespace
62
63 MCCodeEmitter *llvm::createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII,
64 const MCRegisterInfo &MRI,
65 MCContext &Ctx) {
66 return new WebAssemblyMCCodeEmitter(MCII, MRI, Ctx);
67 }
68
69 unsigned WebAssemblyMCCodeEmitter::getMachineOpValue(
70 const MCInst &MI, const MCOperand &MO, SmallVectorImpl &Fixups,
71 const MCSubtargetInfo &STI) const {
72 if (MO.isReg())
73 return MRI.getEncodingValue(MO.getReg());
74 if (MO.isImm())
75 return static_cast(MO.getImm());
76
77 assert(MO.isExpr());
78
79 const MCExpr *Expr = MO.getExpr();
80
81 assert(Expr->getKind() == MCExpr::SymbolRef);
82
83 assert(false && "FIXME: not implemented yet");
84
85 return 0;
86 }
87
88 void WebAssemblyMCCodeEmitter::encodeInstruction(
89 const MCInst &MI, raw_ostream &OS, SmallVectorImpl &Fixups,
90 const MCSubtargetInfo &STI) const {
91 assert(false && "FIXME: not implemented yet");
92 }
93
94 // Encode WebAssembly Memory Operand
95 uint64_t
96 WebAssemblyMCCodeEmitter::getMemoryOpValue(const MCInst &MI, unsigned Op,
97 SmallVectorImpl &Fixups,
98 const MCSubtargetInfo &STI) const {
99 assert(false && "FIXME: not implemented yet");
100 return 0;
101 }
102
103 #include "WebAssemblyGenMCCodeEmitter.inc"
4545 return X;
4646 }
4747
48 static MCStreamer *createWebAssemblyMCStreamer(const Triple &T, MCContext &Ctx,
49 MCAsmBackend &MAB,
50 raw_pwrite_stream &OS,
51 MCCodeEmitter *Emitter,
52 bool RelaxAll) {
53 return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll);
54 }
55
4856 static MCInstPrinter *
4957 createWebAssemblyMCInstPrinter(const Triple & /*T*/, unsigned SyntaxVariant,
5058 const MCAsmInfo &MAI, const MCInstrInfo &MII,
6270 // Register the MC instruction info.
6371 TargetRegistry::RegisterMCInstrInfo(*T, createWebAssemblyMCInstrInfo);
6472
73 // Register the object streamer
74 TargetRegistry::RegisterELFStreamer(*T, createWebAssemblyMCStreamer);
75
6576 // Register the MCInstPrinter.
6677 TargetRegistry::RegisterMCInstPrinter(*T, createWebAssemblyMCInstPrinter);
78
79 // Register the MC code emitter
80 TargetRegistry::RegisterMCCodeEmitter(*T, createWebAssemblyMCCodeEmitter);
81
82 // Register the ASM Backend
83 TargetRegistry::RegisterMCAsmBackend(*T, createWebAssemblyAsmBackend);
6784 }
6885 }
4545 const MCRegisterInfo &MRI,
4646 const Triple &TT, StringRef CPU);
4747
48 MCObjectWriter *createWebAssemblyELFObjectWriter(raw_pwrite_stream &OS,
49 bool Is64Bit, uint8_t OSABI);
50
4851 } // end namespace llvm
4952
5053 // Defines symbolic names for WebAssembly registers. This defines a mapping from
1616 #include "WebAssemblyMachineFunctionInfo.h"
1717 #include "WebAssemblySubtarget.h"
1818 #include "WebAssemblyTargetMachine.h"
19 #include "WebAssemblyTargetObjectFile.h"
2019 #include "llvm/CodeGen/Analysis.h"
2120 #include "llvm/CodeGen/CallingConvLower.h"
2221 #include "llvm/CodeGen/MachineJumpTableInfo.h"
649648 //===----------------------------------------------------------------------===//
650649 // WebAssembly Optimization Hooks
651650 //===----------------------------------------------------------------------===//
652
653 MCSection *WebAssemblyTargetObjectFile::SelectSectionForGlobal(
654 const GlobalValue *GV, SectionKind /*Kind*/, Mangler & /*Mang*/,
655 const TargetMachine & /*TM*/) const {
656 // TODO: Be more sophisticated than this.
657 return isa(GV) ? getTextSection() : getDataSection();
658 }
1414 #include "WebAssembly.h"
1515 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
1616 #include "WebAssemblyTargetMachine.h"
17 #include "WebAssemblyTargetObjectFile.h"
1817 #include "WebAssemblyTargetTransformInfo.h"
1918 #include "llvm/CodeGen/MachineFunctionPass.h"
2019 #include "llvm/CodeGen/Passes.h"
4847 : LLVMTargetMachine(T, TT.isArch64Bit() ? "e-p:64:64-i64:64-n32:64-S128"
4948 : "e-p:32:32-i64:64-n32:64-S128",
5049 TT, CPU, FS, Options, RM, CM, OL),
51 TLOF(make_unique<WebAssemblyTargetObjectFile>()) {
50 TLOF(make_unique<TargetLoweringObjectFileELF>()) {
5251 // WebAssembly type-checks expressions, but a noreturn function with a return
5352 // type that doesn't match the context will cause a check failure. So we lower
5453 // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
170169 addPass(createWebAssemblyRegStackify());
171170 // The register coalescing pass has a bad interaction with COPY MIs which have
172171 // EXPR_STACK as an extra operand
173 //disablePass(&RegisterCoalescerID);
172 // disablePass(&RegisterCoalescerID);
174173 }
175174
176175 void WebAssemblyPassConfig::addPostRegAlloc() {
197196
198197 void WebAssemblyPassConfig::addPreEmitPass() {
199198 TargetPassConfig::addPreEmitPass();
200
199
201200 // Put the CFG in structured form; insert BLOCK and LOOP markers.
202201 addPass(createWebAssemblyCFGStackify());
203202