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();
90 if (P2AlignIdx > 0 &&
Desc.operands()[P2AlignIdx - 1].OperandType ==
91 WebAssembly::OPERAND_MEMORDER) {
92 Order =
MI.getOperand(P2AlignIdx - 1).getImm();
95 "Non-default atomic ordering but feature not enabled");
106 getEncodedMemOrder(Order,
MI.getOpcode()),
111void WebAssemblyMCCodeEmitter::encodeInstruction(
112 const MCInst &
MI, SmallVectorImpl<char> &CB,
113 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
114 raw_svector_ostream OS(CB);
120 }
else if (
Binary < (1 << 16)) {
121 OS << uint8_t(
Binary >> 8);
123 }
else if (
Binary < (1 << 24)) {
124 OS << uint8_t(
Binary >> 16);
133 unsigned Opcode =
MI.getOpcode();
134 if (Opcode == WebAssembly::BR_TABLE_I32_S ||
135 Opcode == WebAssembly::BR_TABLE_I64_S)
137 if (Opcode == WebAssembly::BR_TABLE_I32 ||
138 Opcode == WebAssembly::BR_TABLE_I64)
141 const MCInstrDesc &
Desc = MCII.
get(Opcode);
142 for (
unsigned I = 0,
E =
MI.getNumOperands();
I <
E; ++
I) {
143 const MCOperand &MO =
MI.getOperand(
I);
147 }
else if (MO.
isImm()) {
148 if (
I <
Desc.getNumOperands()) {
149 const MCOperandInfo &
Info =
Desc.operands()[
I];
151 <<
int(
Info.OperandType) <<
"\n");
152 switch (
Info.OperandType) {
153 case WebAssembly::OPERAND_I32IMM:
156 case WebAssembly::OPERAND_P2ALIGN:
157 encodeP2AlignAndMemOrder(
MI,
I,
Desc, STI, OS, Fixups, Start);
159 case WebAssembly::OPERAND_OFFSET32:
162 case WebAssembly::OPERAND_I64IMM:
165 case WebAssembly::OPERAND_SIGNATURE:
166 case WebAssembly::OPERAND_VEC_I8IMM:
170 case WebAssembly::OPERAND_VALTYPE_LIST: {
177 "select t* operand count exceeds MCInst operand count");
181 int64_t Val =
MI.getOperand(
I).getImm();
187 case WebAssembly::OPERAND_MEMORDER: {
190 if (
I + 1 <
Desc.getNumOperands() &&
191 Desc.operands()[
I + 1].OperandType ==
192 WebAssembly::OPERAND_P2ALIGN)
194 uint8_t Val = getEncodedMemOrder(MO.
getImm(), Opcode);
195 if (STI.
getFeatureBits()[WebAssembly::FeatureAcquireReleaseAtomics]) {
198 assert(Opcode == WebAssembly::ATOMIC_FENCE_S);
203 case WebAssembly::OPERAND_VEC_I16IMM:
207 case WebAssembly::OPERAND_VEC_I32IMM:
211 case WebAssembly::OPERAND_VEC_I64IMM:
215 case WebAssembly::OPERAND_GLOBAL:
218 Twine(
"Wasm globals should only be accessed symbolically!"));
227 assert(WebAssembly::isBrTable(Opcode) ||
228 Opcode == WebAssembly::TRY_TABLE_S);
240 size_t PaddedSize = 5;
241 if (
I <
Desc.getNumOperands()) {
242 const MCOperandInfo &
Info =
Desc.operands()[
I];
243 switch (
Info.OperandType) {
244 case WebAssembly::OPERAND_I32IMM:
245 FixupKind = WebAssembly::fixup_sleb128_i32;
247 case WebAssembly::OPERAND_I64IMM:
248 FixupKind = WebAssembly::fixup_sleb128_i64;
251 case WebAssembly::OPERAND_FUNCTION32:
252 case WebAssembly::OPERAND_TABLE:
253 case WebAssembly::OPERAND_OFFSET32:
254 case WebAssembly::OPERAND_SIGNATURE:
255 case WebAssembly::OPERAND_TYPEINDEX:
256 case WebAssembly::OPERAND_GLOBAL:
257 case WebAssembly::OPERAND_TAG:
258 FixupKind = WebAssembly::fixup_uleb128_i32;
260 case WebAssembly::OPERAND_OFFSET64:
261 FixupKind = WebAssembly::fixup_uleb128_i64;
269 assert(Opcode == WebAssembly::TRY_TABLE_S);
270 FixupKind = WebAssembly::fixup_uleb128_i32;
284#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...
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.
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)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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.