39 #define DEBUG_TYPE "asm-printer"
43 class WebAssemblyAsmPrinter final :
public AsmPrinter {
48 WebAssemblyAsmPrinter(
TargetMachine &
TM, std::unique_ptr<MCStreamer> Streamer)
49 :
AsmPrinter(TM, std::move(Streamer)),
MRI(
nullptr), MFI(
nullptr) {}
53 return "WebAssembly Assembly Printer";
70 void EmitEndOfAsmFile(
Module &M)
override;
71 void EmitJumpTableInfo()
override;
72 void EmitConstantPool()
override;
73 void EmitFunctionBodyStart()
override;
74 void EmitFunctionBodyEnd()
override;
77 bool PrintAsmOperand(
const MachineInstr *MI,
unsigned OpNo,
78 unsigned AsmVariant,
const char *ExtraCode,
80 bool PrintAsmMemoryOperand(
const MachineInstr *MI,
unsigned OpNo,
81 unsigned AsmVariant,
const char *ExtraCode,
84 MVT getRegType(
unsigned RegNo)
const;
95 MVT WebAssemblyAsmPrinter::getRegType(
unsigned RegNo)
const {
101 DEBUG(
errs() <<
"Unknown type for register number: " << RegNo);
106 std::string WebAssemblyAsmPrinter::regToString(
const MachineOperand &MO) {
107 unsigned RegNo = MO.
getReg();
109 "Unlowered physical register encountered during assembly printing");
110 assert(!MFI->isVRegStackified(RegNo));
111 unsigned WAReg = MFI->getWAReg(RegNo);
113 return '$' +
utostr(WAReg);
125 void WebAssemblyAsmPrinter::EmitEndOfAsmFile(
Module &M) {
126 for (
const auto &
F : M) {
128 if (
F.isDeclarationForLinker() && !
F.isIntrinsic()) {
132 getTargetStreamer()->emitIndirectFunctionType(
F.getName(), Params,
136 for (
const auto &
G : M.globals()) {
137 if (!
G.hasInitializer() &&
G.hasExternalLinkage()) {
138 getTargetStreamer()->emitGlobalImport(
G.getGlobalIdentifier());
143 void WebAssemblyAsmPrinter::EmitConstantPool() {
144 assert(MF->getConstantPool()->getConstants().empty() &&
145 "WebAssembly disables constant pools");
148 void WebAssemblyAsmPrinter::EmitJumpTableInfo() {
152 void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
153 if (!MFI->getParams().empty())
154 getTargetStreamer()->emitParam(MFI->getParams());
160 if (
MDNode *Idx =
F.getMetadata(
"wasm.index")) {
161 assert(Idx->getNumOperands() == 1);
164 cast<ConstantAsMetadata>(Idx->getOperand(0))->getValue()));
171 if (ResultVTs.
size() == 1)
172 getTargetStreamer()->emitResult(ResultVTs);
176 for (
unsigned Idx = 0, IdxE =
MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
178 unsigned WAReg = MFI->getWAReg(VReg);
183 if (WAReg < MFI->getParams().size())
188 MFI->addLocal(getRegType(VReg));
191 getTargetStreamer()->emitLocal(MFI->getLocals());
196 void WebAssemblyAsmPrinter::EmitFunctionBodyEnd() {
197 getTargetStreamer()->emitEndFunc();
200 void WebAssemblyAsmPrinter::EmitInstruction(
const MachineInstr *
MI) {
201 DEBUG(
dbgs() <<
"EmitInstruction: " << *MI <<
'\n');
204 case WebAssembly::ARGUMENT_I32:
205 case WebAssembly::ARGUMENT_I64:
206 case WebAssembly::ARGUMENT_F32:
207 case WebAssembly::ARGUMENT_F64:
208 case WebAssembly::ARGUMENT_v16i8:
209 case WebAssembly::ARGUMENT_v8i16:
210 case WebAssembly::ARGUMENT_v4i32:
211 case WebAssembly::ARGUMENT_v4f32:
215 case WebAssembly::FALLTHROUGH_RETURN_I32:
216 case WebAssembly::FALLTHROUGH_RETURN_I64:
217 case WebAssembly::FALLTHROUGH_RETURN_F32:
218 case WebAssembly::FALLTHROUGH_RETURN_F64:
219 case WebAssembly::FALLTHROUGH_RETURN_v16i8:
220 case WebAssembly::FALLTHROUGH_RETURN_v8i16:
221 case WebAssembly::FALLTHROUGH_RETURN_v4i32:
222 case WebAssembly::FALLTHROUGH_RETURN_v4f32: {
228 OutStreamer->AddComment(
"fallthrough-return: $pop" +
229 utostr(MFI->getWARegStackId(
231 OutStreamer->AddBlankLine();
235 case WebAssembly::FALLTHROUGH_RETURN_VOID:
239 OutStreamer->AddComment(
"fallthrough-return");
240 OutStreamer->AddBlankLine();
246 MCInstLowering.Lower(MI, TmpInst);
247 EmitToStreamer(*OutStreamer, TmpInst);
253 const MCExpr *WebAssemblyAsmPrinter::lowerConstant(
const Constant *CV) {
254 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
255 if (GV->getValueType()->isFunctionTy())
261 bool WebAssemblyAsmPrinter::PrintAsmOperand(
const MachineInstr *MI,
262 unsigned OpNo,
unsigned AsmVariant,
263 const char *ExtraCode,
279 OS << regToString(MO);
300 bool WebAssemblyAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *MI,
303 const char *ExtraCode,
311 OS <<
"0(" + regToString(MI->
getOperand(OpNo)) +
')';
bool hasType(MVT vt) const
Return true if this TargetRegisterClass has the ValueType vt.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const GlobalValue * getGlobal() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
This class is used to lower an MachineInstr into an MCInst.
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
MachineBasicBlock * getMBB() const
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
A Module instance is used to store all the information related to an LLVM module. ...
This class prints an WebAssembly MCInst to wasm file syntax.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Target specific streamer interface.
This file declares the class to lower WebAssembly MachineInstrs to their corresponding MCInst records...
Function Alias Analysis Results
MachineBasicBlock reference.
const char * getSymbolName() const
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end...
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, SmallVectorImpl< MVT > &ValueVTs)
Base class for the full range of assembler expressions which are needed for parsing.
Name of external global symbol.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
static std::string utostr(uint64_t X, bool isNeg=false)
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
Instances of this class represent a single low-level machine instruction.
WebAssembly-specific streamer interface, to implement support WebAssembly-specific assembly directive...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Address of a global value.
unsigned const MachineRegisterInfo * MRI
MVT - Machine Value Type.
void ComputeSignatureVTs(const Function &F, const TargetMachine &TM, SmallVectorImpl< MVT > &Params, SmallVectorImpl< MVT > &Results)
This is an important base class in LLVM.
const MachineOperand & getOperand(unsigned i) const
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant...
This file provides WebAssembly-specific target descriptions.
This class is intended to be used as a driving class for all asm writers.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
int64_t getOffset() const
Return the offset from the symbol in this operand.
static const unsigned UnusedReg
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This file declares WebAssembly-specific target streamer classes.
This file contains the WebAssembly implementation of the WebAssemblyRegisterInfo class.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
void LLVMInitializeWebAssemblyAsmPrinter()
virtual const MCExpr * lowerConstant(const Constant *CV)
Lower the specified LLVM Constant to an MCExpr.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
virtual void EmitFunctionBodyStart()
Targets can override this to emit stuff before the first basic block in the function.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
This file declares WebAssembly-specific per-machine-function information.
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
RegisterAsmPrinter - Helper template for registering a target specific assembly printer, for use in the target machine initialization function.
This class implements an extremely fast bulk output stream that can only output to a stream...
Primary interface to the complete machine description for the target machine.
StringRef - Represent a constant reference to a string, i.e.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Target & getTheWebAssemblyTarget32()
Target & getTheWebAssemblyTarget64()