Difference between revisions of "NaplesPUInstrInfo.td"

From NaplesPU Documentation
Jump to: navigation, search
(Pattern matching)
Line 36: Line 36:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The following example shows other uses of the Pat class, easier to understand than the previous one.
+
The following example shows other uses of the Pat class, easier to understand than the previous one. The '''zextloadi1''' nodes are defined in [[NuPlusInstrFormats.td]] and match loads followed by a zero extension.  
 
<syntaxhighlight lang="c" line='line'>
 
<syntaxhighlight lang="c" line='line'>
 
def : Pat<(i32 (zextloadi1_mem ADDRri:$addr)), (L32BU_Mainmem ADDRri:$addr)>;
 
def : Pat<(i32 (zextloadi1_mem ADDRri:$addr)), (L32BU_Mainmem ADDRri:$addr)>;

Revision as of 16:55, 2 October 2017

NuPlusInstrInfo.td and NuPlusInstrFormats.td describe the nu+ instructions and the patterns to transform LLVM IR into machine code. The NuPlusInstrInfo.td contains the instructions definition and the patterns necessary for the translation from the LLVM IR to the nu+ machine code.

The files "compiler/include/llvm/Target/Target.td" and "compiler/include/llvm/Target/TargetSelectionDAG.td" contain the Tablegen classes used for the description.

Instructions definition

The instructions are the definition of the classes contained in the NuPlusInstrFormats.td file. The definition is done by selecting the appropriate class or multiclass and specifying the required arguments such as the opcode, the asm radix and the pattern to match. Usually the classes define require only to specify a particular node, since the pattern is already defined.

Lets consider the definition of the integer ADD instructions. According to the nu+ ISA, the ADD instruction has some variations depending on the operands' nature; e.g. they can be both stored in two 32-bit scalar registers or one of them is a 9-bit immediate. However, all these variations are encapsulated in the FArithInt_TwoOp multiclass. Thus, the ADD instruction is instantiated specifying the asm radix add, the operand add and the opcode 4.

defm ADD    : FArithInt_TwoOp<"add", add, 4>;


Pattern matching

During the instruction selection phase, there are some cases in which the instructions do not match with any specified pattern in the instruction definition, or the resulting legalized DAG does not contain the desired machine nodes. There are several ways to overcome this situation, some of which requires the modification of the NuPlusTargetLowering class. However the easiest way is to define a tablegen anonymous pattern, by instantiating the class Pat.

class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;

Keep in mind that this solution affects how the input DAG is transformed into a legalized DAG, so the only type of dependency is the data dependecy among the operations expressed as nodes.

In the NuPlusInstrInfo.td file there is an entire section dedicated to these patterns. They are to detect intrinsics, match different operations to the same machine-dependent operation. Lets consider some examples.

This first example shows how the Pat class can be used to achieve complex pattern transformation. The purpose of the pattern is to emit the necessary nodes to load a 64-bit immediate in nu+. The goal is to break the immediate value in two 32-bit parts and load them in the sub-registers of a 64-bit register in a little-endian fashion. The pattern to match is (i64 imm:$val); i64 is the operation of 64-bit load, while imm:$val defines that the operand val is an immediate imm. This pattern is translated in the DAG reported in the second part of the definition. The order is from the inner node the the outer.

def : Pat<(i64 imm:$val),
       (INSERT_SUBREG (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
                      (LoadI32 (i32 (HI32I $val))),
                      sub_odd),
      (LoadI32 (i32 (LO32I $val))),
      sub_even)>;

The following example shows other uses of the Pat class, easier to understand than the previous one. The zextloadi1 nodes are defined in NuPlusInstrFormats.td and match loads followed by a zero extension.

def : Pat<(i32 (zextloadi1_mem ADDRri:$addr)), (L32BU_Mainmem ADDRri:$addr)>;
def : Pat<(i64 (zextloadi1_mem ADDRri:$addr)), (L64BU_Mainmem ADDRri:$addr)>;
def : Pat<(i32 (zextloadi1_scratch ADDRri:$addr)), (L32BU_Scratchpad ADDRri:$addr)>;
def : Pat<(i64 (zextloadi1_scratch ADDRri:$addr)), (L64BU_Scratchpad ADDRri:$addr)>;

Pseudo-instructions