Adding instruction encoding

If the instructions need to be specific for how they are encoded with respect to bit fields, this can be done by specifying the bit field in the .td file when defining an instruction.

How to do it…

To include instruction encoding while defining instructions, proceed with the following steps:

  1. A register operand that will be used to register the add instruction will have some defined encoding for its instruction. The size of the instruction is 32 bits, and the encoding for it is as follows:
    bits 0 to 3 -> src2, second register operand
    bits 4 to 11 -> all zeros
    bits 12 to 15 -> dst, for destination register
    bits 16 to 19 -> src1, first register operand
    bit 20 -> zero
    bit 21 to 24 -> for opcode
    bit 25 to 27 -> all zeros
    bit 28 to 31 -> 1110

    This can be achieved by specifying the preceding bit pattern in the .td files

  2. In the TOYInstrFormats.td file, define a new variable, called Inst:
    class InstTOY<dag outs, dag ins, string asmstr, list<dag> pattern>
          : Instruction {
      field bits<32> Inst;
    
      let Namespace = "TOY";
        …
       …
        let AsmString   = asmstr;
       …
     …
     }
  3. In the TOYInstrInfo.td file, define an instruction encoding:
    def ADDrr : InstTOY<(outs GRRegs:$dst),(ins GRRegs:$src1, GRRegs:$src2) ... > {
    bits<4> src1;
    bits<4> src2;
    bits<4> dst;
    let Inst{31-25} = 0b1100000;
    let Inst{24-21} = 0b1100; // Opcode
    let Inst{20} = 0b0;
    let Inst{19-16} = src1; // Operand 1
    let Inst{15-12} = dst; // Destination
    let Inst{11-4} = 0b00000000;
    let Inst{3-0} = src2;
    }
  4. In the TOY/MCTargetDesc folder, in the TOYMCCodeEmitter.cpp file, the encoding function will be called if the machine instruction operand is a register:
    unsigned TOYMCCodeEmitter::getMachineOpValue(const MCInst &MI,
                                                 const MCOperand &MO,
                                                 SmallVectorImpl<MCFixup> &Fixups,
                                                 const MCSubtargetInfo &STI) const {
        if (MO.isReg()) {
          return CTX.getRegisterInfo()- >getEncodingValue(MO.getReg());
      }
  5. Also, in the same file, a function used to encode the instruction is specified:
    void TOYMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
          const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
          if (Desc.getSize() != 4) {
            llvm_unreachable("Unexpected instruction size!");
      }
    
          const uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
    
      EmitConstant(Binary, Desc.getSize(), OS);
     ++MCNumEmitted;
    }

How it works…

In the .td files, the encoding of an instruction has been specified—the bits for the operands, the destination, flag conditions, and opcode of the instruction. The machine code emitter gets these encodings from the .inc file generated by tablegen from the .td files through function calls. It encodes these instructions and emits the same for instruction printing.

See also

  • For complex architecture such as ARM, see the ARMInstrInfo.td and ARMInstrInfo.td files in the lib/Target/ARM directory of the LLVM trunk
..................Content has been hidden....................

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