Printing an instruction

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.

Getting ready

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.

How to do it…

Perform the following steps:

  1. Create a new folder called InstPrinter inside the TOY folder:
    $ cd lib/Target/TOY
    $ mkdir InstPrinter
    
  2. In a new file, called 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;
    }
  3. Create a new file called 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);
    }
  4. Also, define a function to print the register names:
    void TOYInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
      OS << StringRef(getRegisterName(RegNo)).lower();
    }
  5. Define a function to print the instruction:
    void TOYInstPrinter::printInst(const MCInst *MI, raw_ostream &O,StringRef Annot) {
      printInstruction(MI, O);
      printAnnotation(O, Annot);
    }
  6. It also requires 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;
    }
  7. Define the LLVMBuild.txt file for the instruction printer:
    [component_0]
    type = Library
    name = TOYAsmPrinter
    parent = TOY
    required_libraries = MC Support
    add_to_library_groups = TOY
  8. Define CMakeLists.txt:
    add_llvm_library(LLVMTOYAsmPrinter
      TOYInstPrinter.cpp
      )

How it works…

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
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.188.244