1f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===-- WebAssemblyAsmBackend.cpp - WebAssembly Assembler Backend ---------===// 2f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 3f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// The LLVM Compiler Infrastructure 4f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 5f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 6f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// License. See LICENSE.TXT for details. 7f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 8f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 9f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// 10f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// \file 11f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// \brief This file implements the WebAssemblyAsmBackend class. 12f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// 13f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 14f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 15f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 16f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/MC/MCAsmBackend.h" 17f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/MC/MCAssembler.h" 18f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/MC/MCDirectives.h" 19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/MC/MCELFObjectWriter.h" 20f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/MC/MCExpr.h" 21f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/MC/MCFixupKindInfo.h" 22f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/MC/MCObjectWriter.h" 23f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/MC/MCSubtargetInfo.h" 24f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/MC/MCSymbol.h" 25f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/ErrorHandling.h" 26f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 27f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarusing namespace llvm; 28f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 29f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace { 30f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarclass WebAssemblyAsmBackend final : public MCAsmBackend { 31f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool Is64Bit; 32f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 33f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarpublic: 34f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar explicit WebAssemblyAsmBackend(bool Is64Bit) 35f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : MCAsmBackend(), Is64Bit(Is64Bit) {} 36f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ~WebAssemblyAsmBackend() override {} 37f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 38f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 39f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uint64_t Value, bool IsPCRel) const override; 40f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; 42f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 43f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // No instruction requires relaxation 44f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, 45f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCRelaxableFragment *DF, 46f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCAsmLayout &Layout) const override { 47f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 48f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 49f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 50f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned getNumFixupKinds() const override { 51f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // We currently just use the generic fixups in MCFixup.h and don't have any 52f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // target-specific fixups. 53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return 0; 54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool mayNeedRelaxation(const MCInst &Inst) const override { return false; } 57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, 59de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MCInst &Res) const override {} 60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; 62f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}; 63f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 64f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool WebAssemblyAsmBackend::writeNopData(uint64_t Count, 65f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCObjectWriter *OW) const { 66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Count == 0) 67f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 69f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // FIXME: Do something. 70f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 71f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid WebAssemblyAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, 74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned DataSize, uint64_t Value, 75f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool IsPCRel) const { 76f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCFixupKindInfo &Info = getFixupKindInfo(Fixup.getKind()); 77de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(Info.Flags == 0 && "WebAssembly does not use MCFixupKindInfo flags"); 78de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 79de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned NumBytes = (Info.TargetSize + 7) / 8; 80de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Value == 0) 81f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return; // Doesn't change encoding. 82f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 83f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Shift the value into position. 84f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Value <<= Info.TargetOffset; 85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Offset = Fixup.getOffset(); 87f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!"); 88f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // For each byte of the fragment that the fixup touches, mask in the 90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // bits from the fixup value. 91f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (unsigned i = 0; i != NumBytes; ++i) 92f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff); 93f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 94f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 95f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarMCObjectWriter * 96f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarWebAssemblyAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { 97f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return createWebAssemblyELFObjectWriter(OS, Is64Bit, 0); 98f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 99f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} // end anonymous namespace 100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 101de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarMCAsmBackend *llvm::createWebAssemblyAsmBackend(const Triple &TT) { 102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return new WebAssemblyAsmBackend(TT.isArch64Bit()); 103f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 104