32#define DEBUG_TYPE "mccodeemitter"
34STATISTIC(MCNumEmitted,
"Number of MC instructions emitted.");
35STATISTIC(MCNumFixups,
"Number of MC fixups created.");
50 void encodeP2AlignAndMemOrder(
const MCInst &
MI,
unsigned P2AlignIdx,
60 : MCII(MCII), Ctx{Ctx} {}
66 return new WebAssemblyMCCodeEmitter(MCII, Ctx);
70 unsigned Opcode)
const {
73 if (Name.contains(
"RMW") || Name.contains(
"CMPXCHG"))
79void WebAssemblyMCCodeEmitter::encodeP2AlignAndMemOrder(
80 const MCInst &
MI,
unsigned P2AlignIdx,
const MCInstrDesc &
Desc,
81 const MCSubtargetInfo &STI, raw_ostream &OS,
82 SmallVectorImpl<MCFixup> &Fixups, uint64_t Start)
const {
83 uint64_t P2Align =
MI.getOperand(P2AlignIdx).getImm();
89 if (P2AlignIdx > 0 &&
Desc.operands()[P2AlignIdx - 1].OperandType ==
91 Order =
MI.getOperand(P2AlignIdx - 1).getImm();
94 "Non-default atomic ordering but feature not enabled");
105 getEncodedMemOrder(Order,
MI.getOpcode()),
110void WebAssemblyMCCodeEmitter::encodeInstruction(
111 const MCInst &
MI, SmallVectorImpl<char> &CB,
112 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
113 raw_svector_ostream OS(CB);
116 uint64_t
Binary = getBinaryCodeForInstr(
MI, Fixups, STI);
117 if (Binary < (1 << 8)) {
118 OS << uint8_t(Binary);
119 }
else if (Binary < (1 << 16)) {
120 OS << uint8_t(Binary >> 8);
122 }
else if (Binary < (1 << 24)) {
123 OS << uint8_t(Binary >> 16);
132 unsigned Opcode =
MI.getOpcode();
133 if (Opcode == WebAssembly::BR_TABLE_I32_S ||
134 Opcode == WebAssembly::BR_TABLE_I64_S)
136 if (Opcode == WebAssembly::BR_TABLE_I32 ||
137 Opcode == WebAssembly::BR_TABLE_I64)
140 const MCInstrDesc &
Desc = MCII.
get(Opcode);
141 for (
unsigned I = 0,
E =
MI.getNumOperands();
I <
E; ++
I) {
142 const MCOperand &MO =
MI.getOperand(
I);
146 }
else if (MO.
isImm()) {
147 if (
I <
Desc.getNumOperands()) {
148 const MCOperandInfo &
Info =
Desc.operands()[
I];
150 <<
int(
Info.OperandType) <<
"\n");
151 switch (
Info.OperandType) {
156 encodeP2AlignAndMemOrder(
MI,
I,
Desc, STI, OS, Fixups, Start);
172 if (
I + 1 <
Desc.getNumOperands() &&
173 Desc.operands()[
I + 1].OperandType ==
176 uint8_t Val = getEncodedMemOrder(MO.
getImm(), Opcode);
180 assert(Opcode == WebAssembly::ATOMIC_FENCE_S);
200 Twine(
"Wasm globals should only be accessed symbolically!"));
210 Opcode == WebAssembly::TRY_TABLE_S);
222 size_t PaddedSize = 5;
223 if (
I <
Desc.getNumOperands()) {
224 const MCOperandInfo &
Info =
Desc.operands()[
I];
225 switch (
Info.OperandType) {
251 assert(Opcode == WebAssembly::TRY_TABLE_S);
266#include "WebAssemblyGenMCCodeEmitter.inc"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file provides WebAssembly-specific target descriptions.
MCCodeEmitter - Generic instruction encoding interface.
Context object for machine code objects.
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
const MCExpr * getExpr() const
uint32_t getSFPImm() const
uint64_t getDFPImm() const
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
This class implements an extremely fast bulk output stream that can only output to a stream.
uint64_t tell() const
tell - Return the current offset with the file.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isBrTable(unsigned Opc)
@ OPERAND_GLOBAL
Global index.
@ OPERAND_OFFSET64
64-bit unsigned memory offsets.
@ OPERAND_MEMORDER
Memory ordering immediate for atomic instructions.
@ OPERAND_I32IMM
32-bit integer immediates.
@ OPERAND_P2ALIGN
p2align immediate for load and store address alignment.
@ OPERAND_TABLE
32-bit unsigned table number.
@ OPERAND_VEC_I64IMM
64-bit vector lane immediate
@ OPERAND_VEC_I16IMM
16-bit vector lane immediate
@ OPERAND_TYPEINDEX
type signature immediate for call_indirect.
@ OPERAND_FUNCTION32
32-bit unsigned function indices.
@ OPERAND_VEC_I32IMM
32-bit vector lane immediate
@ OPERAND_VEC_I8IMM
8-bit vector lane immediate
@ OPERAND_SIGNATURE
signature immediate for block/loop.
@ OPERAND_I64IMM
64-bit integer immediates.
@ OPERAND_OFFSET32
32-bit unsigned memory offsets.
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
@ WASM_MEM_ORDER_RMW_ACQ_REL
const unsigned WASM_MEMARG_HAS_MEM_ORDER
This is an optimization pass for GlobalISel generic memory operations.
MCCodeEmitter * createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static Lanai::Fixups FixupKind(const MCExpr *Expr)
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.