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.
To include instruction encoding while defining instructions, proceed with the following steps:
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
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; … … }
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; }
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()); }
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; }
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.
3.144.17.137