rtx objects
The compiled RTL is represented internally by an object called "rtx". This object is used for lots of things, insns, operands, constants, etc. There are several macros defined to get information about an rtx object.
Testing whether an rtx is something is done using macros that have _P appended. So to test if an rtx is an insn, you can call INSN_P(rtx); to test if it is a reg you can call REG_P(rtx); to test for numbers use CONST_INT_P(rtx), and so on. For the general case, GET_CODE(rtx) will return an enum with the type of an rtx. GET_RTX_NAME(code) will return a printable string containing the code name.
NOTE: I've found the code name to reliably match the enum so when debugging it is much easier to find an insn with a name of "plus" than it is to wade through the enum definition file trying to figure out which one is number 573. [1]
If it is a reg or memory location, it will have a mode. In C code, the modes are defined by an enum as QImode, HImode, SImode, etc. To get the mode of an rtx, the macro GET_MODE(rtx) can be used. To get a printable name, the macro GET_MODE_NAME(mode) can be used.
Registers
Registers have defines for convenience such as HARD_R0_REGNUM or FRAME_POINTER_REGNUM (aka HARD_R9_REGNUM). The stack pointer is also available through a global rtx called stack_pointer_rtx.
NOTE: be sure to wrap register values with gen_rtx_REG() before passing to any functions that expect an rtx parameter. I'm sure there will be a warning, but it will get lost in the big sea of warnings and then gcc will just crash.
Emitting opcodes
C code can emit opcodes. This is done in functions tms9900_expand_prologue() for example. The emit_insn() function will emit an insn rtx into the output list. Each named insn in the md file will have a corresponding function with a "gen_" prefix so you can call gen_movhi() and so on to emit these insns. The functions take an array of rtx objects as parameters for operands.
Operands
Operands are passed to insns as an array of rtx objects. So operand[0] is the first rtx and so on. I did once have a concern that we shouldn't modify rtx objects passed to insns but that seems to be a valid thing to and many other backends do it all the time. This is useful if we want to replace an operand with something else or swap them around, etc.
NOTE: be careful not to access operands with a higher array index than your insn defines. As with any C code there is no bounds checking on the array. If an insn takes 3 operands and you try to access operand[3] the compiler will probably (make that hopefully) seg fault.
[1] I just made that up, I've no idea what the code is for PLUS.
No comments:
Post a Comment