Path: blob/main/contrib/llvm-project/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp
35293 views
//===-- WebAssemblyAsmBackend.cpp - WebAssembly Assembler Backend ---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file implements the WebAssemblyAsmBackend class.10///11//===----------------------------------------------------------------------===//1213#include "MCTargetDesc/WebAssemblyFixupKinds.h"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/MCExpr.h"19#include "llvm/MC/MCFixupKindInfo.h"20#include "llvm/MC/MCObjectWriter.h"21#include "llvm/MC/MCSubtargetInfo.h"22#include "llvm/MC/MCSymbol.h"23#include "llvm/MC/MCWasmObjectWriter.h"24#include "llvm/Support/ErrorHandling.h"25#include "llvm/Support/raw_ostream.h"2627using namespace llvm;2829namespace {3031class WebAssemblyAsmBackend final : public MCAsmBackend {32bool Is64Bit;33bool IsEmscripten;3435public:36explicit WebAssemblyAsmBackend(bool Is64Bit, bool IsEmscripten)37: MCAsmBackend(llvm::endianness::little), Is64Bit(Is64Bit),38IsEmscripten(IsEmscripten) {}3940unsigned getNumFixupKinds() const override {41return WebAssembly::NumTargetFixupKinds;42}4344const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;4546void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,47const MCValue &Target, MutableArrayRef<char> Data,48uint64_t Value, bool IsPCRel,49const MCSubtargetInfo *STI) const override;5051std::unique_ptr<MCObjectTargetWriter>52createObjectTargetWriter() const override;5354bool writeNopData(raw_ostream &OS, uint64_t Count,55const MCSubtargetInfo *STI) const override;56};5758const MCFixupKindInfo &59WebAssemblyAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {60const static MCFixupKindInfo Infos[WebAssembly::NumTargetFixupKinds] = {61// This table *must* be in the order that the fixup_* kinds are defined in62// WebAssemblyFixupKinds.h.63//64// Name Offset (bits) Size (bits) Flags65{"fixup_sleb128_i32", 0, 5 * 8, 0},66{"fixup_sleb128_i64", 0, 10 * 8, 0},67{"fixup_uleb128_i32", 0, 5 * 8, 0},68{"fixup_uleb128_i64", 0, 10 * 8, 0},69};7071if (Kind < FirstTargetFixupKind)72return MCAsmBackend::getFixupKindInfo(Kind);7374assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&75"Invalid kind!");76return Infos[Kind - FirstTargetFixupKind];77}7879bool WebAssemblyAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,80const MCSubtargetInfo *STI) const {81for (uint64_t I = 0; I < Count; ++I)82OS << char(WebAssembly::Nop);8384return true;85}8687void WebAssemblyAsmBackend::applyFixup(const MCAssembler &Asm,88const MCFixup &Fixup,89const MCValue &Target,90MutableArrayRef<char> Data,91uint64_t Value, bool IsPCRel,92const MCSubtargetInfo *STI) const {93const MCFixupKindInfo &Info = getFixupKindInfo(Fixup.getKind());94assert(Info.Flags == 0 && "WebAssembly does not use MCFixupKindInfo flags");9596unsigned NumBytes = alignTo(Info.TargetSize, 8) / 8;97if (Value == 0)98return; // Doesn't change encoding.99100// Shift the value into position.101Value <<= Info.TargetOffset;102103unsigned Offset = Fixup.getOffset();104assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");105106// For each byte of the fragment that the fixup touches, mask in the107// bits from the fixup value.108for (unsigned I = 0; I != NumBytes; ++I)109Data[Offset + I] |= uint8_t((Value >> (I * 8)) & 0xff);110}111112std::unique_ptr<MCObjectTargetWriter>113WebAssemblyAsmBackend::createObjectTargetWriter() const {114return createWebAssemblyWasmObjectWriter(Is64Bit, IsEmscripten);115}116117} // end anonymous namespace118119MCAsmBackend *llvm::createWebAssemblyAsmBackend(const Triple &TT) {120return new WebAssemblyAsmBackend(TT.isArch64Bit(), TT.isOSEmscripten());121}122123124