LLVM  4.0.0
WebAssemblyMCCodeEmitter.cpp
Go to the documentation of this file.
1 //=- WebAssemblyMCCodeEmitter.cpp - Convert WebAssembly code to machine code -//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file implements the WebAssemblyMCCodeEmitter class.
12 ///
13 //===----------------------------------------------------------------------===//
14 
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/MC/MCCodeEmitter.h"
19 #include "llvm/MC/MCFixup.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/MC/MCRegisterInfo.h"
24 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/Support/LEB128.h"
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "mccodeemitter"
31 
32 STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
33 STATISTIC(MCNumFixups, "Number of MC fixups created.");
34 
35 namespace {
36 class WebAssemblyMCCodeEmitter final : public MCCodeEmitter {
37  const MCInstrInfo &MCII;
38 
39  // Implementation generated by tablegen.
40  uint64_t getBinaryCodeForInstr(const MCInst &MI,
42  const MCSubtargetInfo &STI) const;
43 
44  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
46  const MCSubtargetInfo &STI) const override;
47 
48 public:
49  explicit WebAssemblyMCCodeEmitter(const MCInstrInfo &mcii) : MCII(mcii) {}
50 };
51 } // end anonymous namespace
52 
54  return new WebAssemblyMCCodeEmitter(MCII);
55 }
56 
57 void WebAssemblyMCCodeEmitter::encodeInstruction(
59  const MCSubtargetInfo &STI) const {
60  uint64_t Start = OS.tell();
61 
62  uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
63  assert(Binary < UINT8_MAX && "Multi-byte opcodes not supported yet");
64  OS << uint8_t(Binary);
65 
66  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
67  for (unsigned i = 0, e = MI.getNumOperands(); i < e; ++i) {
68  const MCOperand &MO = MI.getOperand(i);
69  if (MO.isReg()) {
70  /* nothing to encode */
71  } else if (MO.isImm()) {
72  if (i < Desc.getNumOperands()) {
73  assert(Desc.TSFlags == 0 &&
74  "WebAssembly non-variable_ops don't use TSFlags");
75  const MCOperandInfo &Info = Desc.OpInfo[i];
77  encodeSLEB128(int32_t(MO.getImm()), OS);
78  } else if (Info.OperandType == WebAssembly::OPERAND_I64IMM) {
79  encodeSLEB128(int64_t(MO.getImm()), OS);
80  } else {
81  encodeULEB128(uint64_t(MO.getImm()), OS);
82  }
83  } else {
86  encodeULEB128(uint64_t(MO.getImm()), OS);
87  }
88  } else if (MO.isFPImm()) {
89  assert(i < Desc.getNumOperands() &&
90  "Unexpected floating-point immediate as a non-fixed operand");
91  assert(Desc.TSFlags == 0 &&
92  "WebAssembly variable_ops floating point ops don't use TSFlags");
93  const MCOperandInfo &Info = Desc.OpInfo[i];
95  // TODO: MC converts all floating point immediate operands to double.
96  // This is fine for numeric values, but may cause NaNs to change bits.
97  float f = float(MO.getFPImm());
98  support::endian::Writer<support::little>(OS).write<float>(f);
99  } else {
101  double d = MO.getFPImm();
102  support::endian::Writer<support::little>(OS).write<double>(d);
103  }
104  } else if (MO.isExpr()) {
105  Fixups.push_back(MCFixup::create(
106  OS.tell() - Start, MO.getExpr(),
108  MI.getLoc()));
109  ++MCNumFixups;
110  encodeULEB128(STI.getTargetTriple().isArch64Bit() ? UINT64_MAX
111  : uint64_t(UINT32_MAX),
112  OS);
113  } else {
114  llvm_unreachable("unexpected operand kind");
115  }
116  }
117 
118  ++MCNumEmitted; // Keep track of the # of mi's emitted.
119 }
120 
121 #include "WebAssemblyGenMCCodeEmitter.inc"
32-bit floating-point immediates.
double getFPImm() const
Definition: MCInst.h:83
STATISTIC(NumFunctions,"Total number of functions")
size_t i
bool isReg() const
Definition: MCInst.h:56
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:32
A four-byte fixup.
Definition: MCFixup.h:26
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:98
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1202
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:82
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
bool isImm() const
Definition: MCInst.h:57
const MCExpr * getExpr() const
Definition: MCInst.h:93
MCCodeEmitter * createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII)
bool isFPImm() const
Definition: MCInst.h:58
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:23
This file provides WebAssembly-specific target descriptions.
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
bool isExpr() const
Definition: MCInst.h:59
SMLoc getLoc() const
Definition: MCInst.h:162
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:82
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void encodeSLEB128(int64_t Value, raw_ostream &OS)
Utility function to encode a SLEB128 value to an output stream.
Definition: LEB128.h:23
unsigned getOpcode() const
Definition: MCInst.h:159
64-bit floating-point immediates.
int64_t getImm() const
Definition: MCInst.h:74
unsigned getNumOperands() const
Definition: MCInst.h:166
MCSubtargetInfo - Generic base class for all target subtargets.
A eight-byte fixup.
Definition: MCFixup.h:27
const Triple & getTargetTriple() const
getTargetTriple - Return the target triple string.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:210
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:174
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
void encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned Padding=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:38
IRTranslator LLVM IR MI
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:70
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164