Printing an assembly instruction is an important step in generating target code. Various classes are defined that work as a gateway to the streamers. The instruction string is provided by the .td
file defined earlier.
The first and foremost step for printing instructions is to define the instruction string in the .td
file, which was done in the Defining the instruction set recipe.
Perform the following steps:
InstPrinter
inside the TOY
folder:$ cd lib/Target/TOY $ mkdir InstPrinter
TOYInstrFormats.td
, define the AsmString
variable:class InstTOY<dag outs, dag ins, string asmstr, list<dag> pattern> : Instruction { field bits<32> Inst; let Namespace = "TOY"; dag OutOperandList = outs; dag InOperandList = ins; let AsmString = asmstr; let Pattern = pattern; let Size = 4; }
TOYInstPrinter.cpp
, and define the printOperand
function, as follows:void TOYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); if (Op.isReg()) { printRegName(O, Op.getReg()); return; } if (Op.isImm()) { O << "#" << Op.getImm(); return; } assert(Op.isExpr() && "unknown operand kind in printOperand"); printExpr(Op.getExpr(), O); }
void TOYInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { OS << StringRef(getRegisterName(RegNo)).lower(); }
void TOYInstPrinter::printInst(const MCInst *MI, raw_ostream &O,StringRef Annot) { printInstruction(MI, O); printAnnotation(O, Annot); }
MCASMinfo
to be specified to print the instruction. This can be done by defining the TOYMCAsmInfo.h
and TOYMCAsmInfo.cpp
files.The TOYMCAsmInfo.h
file can be defined as follows:
#ifndef TOYTARGETASMINFO_H #define TOYTARGETASMINFO_H #include "llvm/MC/MCAsmInfoELF.h" namespace llvm { class StringRef; class Target; class TOYMCAsmInfo : public MCAsmInfoELF { virtual void anchor(); public: explicit TOYMCAsmInfo(StringRef TT); }; } // namespace llvm #endif
The TOYMCAsmInfo.cpp
file can be defined like this:
#include "TOYMCAsmInfo.h" #include "llvm/ADT/StringRef.h" using namespace llvm; void TOYMCAsmInfo::anchor() {} TOYMCAsmInfo::TOYMCAsmInfo(StringRef TT) { SupportsDebugInformation = true; Data16bitsDirective = " .short "; Data32bitsDirective = " .long "; Data64bitsDirective = 0; ZeroDirective = " .space "; CommentString = "#"; AscizDirective = ".asciiz"; HiddenVisibilityAttr = MCSA_Invalid; HiddenDeclarationVisibilityAttr = MCSA_Invalid; ProtectedVisibilityAttr = MCSA_Invalid; }
LLVMBuild.txt
file for the instruction printer:[component_0] type = Library name = TOYAsmPrinter parent = TOY required_libraries = MC Support add_to_library_groups = TOY
CMakeLists.txt
:add_llvm_library(LLVMTOYAsmPrinter TOYInstPrinter.cpp )
When the final compilation takes place, the llc tool—a static compiler—will generate the assembly of the TOY architecture.
For example, the following IR, when given to the llc tool, will generate an assembly as shown:
target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32- i16:16:32-i64:32-f64:32-a:0:32-n32" target triple = "toy" define i32 @foo(i32 %a, i32 %b) { %c = add nsw i32 %a, %b ret i32 %c } $ llc foo.ll .text .file "foo.ll" .globl foo .type foo,@function foo: # @foo # BB#0: # %entry add r0, r0, r1 b lr .Ltmp0: .size foo, .Ltmp0-foo
3.140.188.244