Before the instruction matcher can be created the
arch
Operand structure must be defined. This
represents a parsed machine instruction, storing information about
the types and contents of its operands.
Note | |
---|---|
This class inherits from |
Within this structure is an enum and union which store the operand along with its type.
In the case for OpenRISC 1000 , these operand types are tokens, registers and
immediate. Similarly, SMLoc
s (source code
locations) are stored for the start and stop locations of the operand.
enum KindTy { Token, Register, Immediate } Kind; SMLoc StartLoc, EndLoc; union { struct { const char *Data; unsigned Length; } Tok; struct { unsigned RegNum; } Reg; struct { const MCExpr *Val; } Imm; };
The majority of functions within this struct are simply getters and setters for the different operands stored in the object. For the getters, asserts are added to check that the operand is of the correct type before returning its value. An example is shown below.
StringRef getToken() const { assert (Kind == Token && "Invalid type access!"); return StringRef(Tok.Data, Tok.Length); }
Generator functions called CreateToken
,
CreateReg
etc. are defined which take the data
type for the operand as well as the start and end locations of the
operand (with the exception of tokens which only take a start
location). These functions then create a new object for the provided
operand details, set its contents and then returns it.
The final functions in this structure add operands to a particular
instruction. These use the addOperand
function
of a MCInst
to add the relevant operand. For
registers, the getReg()
is simply used.
Immediates however use a more complex method where if it is possible
to add the instruction as an immediate it is done so, otherwise it
is added as an expression, as demonstrated below.
void addExpr(MCInst &Inst, const MCExpr *Expr) const { // Add as immediates where possible. Null MCExpr = 0 if (Expr == 0) Inst.addOperand(MCOperand::CreateImm(0)); else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) Inst.addOperand(MCOperand::CreateImm(CE->getValue())); else Inst.addOperand(MCOperand::CreateExpr(Expr)); }