Difference between revisions of "NaplesPURegisterInfo.td"

From NaplesPU Documentation
Jump to: navigation, search
 
(4 intermediate revisions by 3 users not shown)
Line 1: Line 1:
The NuPlusRegisterInfo.td is used to define the nu+ hw registers and the nu+ register classes.  
+
[[Category:Tablegen Files]]
 +
The NaplesPURegisterInfo.td is used to define the NaplesPU hw registers and the NaplesPU register classes.  
  
The '''registers''' contain informations about the hardware encoding, the asm name used to index a specific register and the [https://en.wikipedia.org/wiki/DWARF DWARF number]. The '''register classes''' contain the bindings between the data-types, the registers to use and their width expressed in bit
+
<syntaxhighlight lang="c" line='line'>
 +
//===-- NaplesPURegisterInfo.td - NaplesPU Register defs ---------*- tablegen -*-===//
 +
//
 +
//                    The LLVM Compiler Infrastructure
 +
//
 +
// This file is distributed under the University of Illinois Open Source
 +
// License. See LICENSE.TXT for details.
 +
//
 +
//===----------------------------------------------------------------------===//
 +
 
 +
//===----------------------------------------------------------------------===//
 +
//  Declarations that describe the NaplesPU register file
 +
//===----------------------------------------------------------------------===//
  
The registers definition is done creating two support classes '''NuPlusGPRReg''' and '''NuPlus64GPRReg'''. The first one is used to define 32-bit wide registers while the second is used to define 64-bit wide registers. We made this distinction because the hardware uses the same register for both 32 and 64 bits wide variables. Thus a 64-bit wide register is composed by a couple of 32-bit wide register, using the even sub-register to contain the 32 less significant bits, while the odd sub-register holds the 32 most significant bits.
+
let Namespace = "NaplesPU" in {
 +
def sub_even : SubRegIndex<32>;
 +
def sub_odd  : SubRegIndex<32, 32>;
 +
}
  
<syntaxhighlight lang="c" line='line'>
+
class NaplesPUReg<bits<16> Enc, string n> : Register<n> {
// NuPlus 32-bit registers
+
  let HWEncoding = Enc;
class NuPlusGPRReg<bits<16> Enc, string n> : NuPlusReg<Enc, n>;
+
  let Namespace = "NaplesPU";
 +
}
  
// NuPlus pairs of 32-bit registers
+
class NaplesPURegWithSubRegs<bits<16> Enc, string n, list<Register> subregs>
class NuPlus64GPRReg<bits<16> Enc, string n, list<Register> subregs>
+
   : RegisterWithSubRegs<n, subregs> {
   : NuPlusRegWithSubRegs<Enc, n, subregs> {
+
   let HWEncoding = Enc;
   let SubRegIndices = [sub_even, sub_odd];
+
   let Namespace = "NaplesPU";
   let CoveredBySubRegs = 1;
 
 
}
 
}
</syntaxhighlight>
 
  
Note that the '''NuPlus64GPRReg''' uses '''SubRegIndices''' to index a specific 32-bit wide sub-register. In particular, '''sub_even''' indexes the even sub-register, while '''sub_odd''' indexes the odd sub-register.
+
// NaplesPU 32-bit registers
 +
class NaplesPUGPRReg<bits<16> Enc, string n> : NaplesPUReg<Enc, n>;
 +
 
 +
//===----------------------------------------------------------------------===//
 +
//  Registers
 +
//===----------------------------------------------------------------------===//
  
Two loops are used to define the architecture general purpose registers. 
 
  
<syntaxhighlight lang="c" line='line'>
 
 
   // General Purpose scalar registers
 
   // General Purpose scalar registers
 
   foreach i = 0-57 in {
 
   foreach i = 0-57 in {
     def S#i : NuPlusGPRReg<i, "s"#i>, DwarfRegNum<[i]>;
+
     def S#i : NaplesPUGPRReg<i, "s"#i>, DwarfRegNum<[i]>;
 
   }
 
   }
  
 
   //trap register
 
   //trap register
   def TR_REG : NuPlusGPRReg<58, "tr">, DwarfRegNum<[58]>;
+
   def TR_REG : NaplesPUGPRReg<58, "tr">, DwarfRegNum<[58]>;
 
   //mask register
 
   //mask register
   def MR_REG : NuPlusGPRReg<59, "rm">, DwarfRegNum<[59]>;
+
   def MR_REG : NaplesPUGPRReg<59, "rm">, DwarfRegNum<[59]>;
 
   //frame pointer
 
   //frame pointer
   def FP_REG : NuPlusGPRReg<60, "fp">, DwarfRegNum<[60]>;
+
   def FP_REG : NaplesPUGPRReg<60, "fp">, DwarfRegNum<[60]>;
 
   //stack pointer
 
   //stack pointer
   def SP_REG : NuPlusGPRReg<61, "sp">, DwarfRegNum<[61]>;
+
   def SP_REG : NaplesPUGPRReg<61, "sp">, DwarfRegNum<[61]>;
 
   //return address
 
   //return address
   def RA_REG : NuPlusGPRReg<62, "ra">, DwarfRegNum<[62]>;
+
   def RA_REG : NaplesPUGPRReg<62, "ra">, DwarfRegNum<[62]>;
 
   //PC
 
   //PC
   def PC_REG : NuPlusGPRReg<63, "pc">, DwarfRegNum<[63]>;
+
   def PC_REG : NaplesPUGPRReg<63, "pc">, DwarfRegNum<[63]>;
  
 
   // General Purpose vectorial registers
 
   // General Purpose vectorial registers
 
   foreach i = 0-63 in {
 
   foreach i = 0-63 in {
     def V#i : NuPlusGPRReg<i, "v"#i>, DwarfRegNum<[!add(i, 64)]>;
+
     def V#i : NaplesPUGPRReg<i, "v"#i>, DwarfRegNum<[!add(i, 64)]>;
 
   }
 
   }
</syntaxhighlight>
 
  
Note also the definition of the special registers.
+
//===----------------------------------------------------------------------===//
 
+
// Register Classes
The definition of the 64-bit registers is done using the following loop.
+
//===----------------------------------------------------------------------===//
 
 
<syntaxhighlight lang="c" line='line'>
 
  foreach i = 0-28 in {
 
    def S#!shl(i, 1)#_S#!add(!shl(i, 1), 1) : NuPlus64GPRReg<!shl(i, 1), "s"#!shl(i, 1)#_64,
 
                [!cast<NuPlusGPRReg>("S"#!shl(i, 1)),
 
                  !cast<NuPlusGPRReg>("S"#!add(!shl(i, 1), 1))]>;
 
  }
 
</syntaxhighlight>
 
 
 
The code uses Tablgen commands to define the registers in the form '''Sx_Sy''', where '''x''' is an even number and '''y''' an odd one.
 
 
 
The register classes defined are '''GPR32''', '''GPR64''', '''VR512W''' and '''VR512L'''. These are for 32-bit scalar variables, 64-bit scalar variables, 32-bit vector variables and 64-bit vector variables respectively.
 
 
 
<syntaxhighlight lang="c" line='line'>
 
def GPR32 : RegisterClass<"NuPlus", [i32, f32, i64, f64], 32, (add (sequence "S%u", 0, 57),
 
  TR_REG, MR_REG, FP_REG, SP_REG, RA_REG, PC_REG)>;
 
  
def GPR64 : RegisterClass<"NuPlus", [i64, f64], 64,
+
// This register class should not be used to hold i64/f64 values, use the GPR64
    (add S0_S1, S2_S3, S4_S5, S6_S7,
+
// register class for that. The i64/f64 type is included here to allow i64/f64
        S8_S9, S10_S11, S12_S13, S14_S15,
+
// patterns using the instructions.
        S16_S17, S18_S19, S20_S21, S22_S23,
+
def GPR32 : RegisterClass<"NaplesPU", [i32, f32], 32, (add (sequence "S%u", 0, 57),
        S24_S25, S26_S27, S28_S29, S30_S31,
+
  TR_REG, MR_REG, FP_REG, SP_REG, RA_REG, PC_REG)>
        S32_S33, S34_S35, S36_S37, S38_S39,
 
        S40_S41, S42_S43, S44_S45, S46_S47,
 
        S48_S49, S50_S51, S52_S53, S54_S55,
 
        S56_S57)>;
 
  
def VR512W : RegisterClass<"NuPlus", [v16i8, v16i16, v16i32, v8f32, v16f32], 512, (sequence "V%u", 0, 63)>;
+
def VR512W : RegisterClass<"NaplesPU", [v16i32, v16f32, v16i8, v16i16], 512, (sequence "V%u", 0, 63)>;
def VR512L : RegisterClass<"NuPlus", [v8i8, v8i16, v8i32, v8i64, v8f64], 512, (sequence "V%u", 0, 63)>;
 
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 15:56, 21 June 2019

The NaplesPURegisterInfo.td is used to define the NaplesPU hw registers and the NaplesPU register classes.

//===-- NaplesPURegisterInfo.td - NaplesPU Register defs ---------*- tablegen -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
//  Declarations that describe the NaplesPU register file
//===----------------------------------------------------------------------===//

let Namespace = "NaplesPU" in {
def sub_even : SubRegIndex<32>;
def sub_odd  : SubRegIndex<32, 32>;
}

class NaplesPUReg<bits<16> Enc, string n> : Register<n> {
  let HWEncoding = Enc;
  let Namespace = "NaplesPU";
}

class NaplesPURegWithSubRegs<bits<16> Enc, string n, list<Register> subregs>
  : RegisterWithSubRegs<n, subregs> {
  let HWEncoding = Enc;
  let Namespace = "NaplesPU";
}

// NaplesPU 32-bit registers
class NaplesPUGPRReg<bits<16> Enc, string n> : NaplesPUReg<Enc, n>;

//===----------------------------------------------------------------------===//
//  Registers
//===----------------------------------------------------------------------===//


  // General Purpose scalar registers
  foreach i = 0-57 in {
    def S#i : NaplesPUGPRReg<i, "s"#i>, DwarfRegNum<[i]>;
  }

  //trap register
  def TR_REG : NaplesPUGPRReg<58, "tr">, DwarfRegNum<[58]>;
  //mask register
  def MR_REG : NaplesPUGPRReg<59, "rm">, DwarfRegNum<[59]>;
  //frame pointer
  def FP_REG : NaplesPUGPRReg<60, "fp">, DwarfRegNum<[60]>;
  //stack pointer
  def SP_REG : NaplesPUGPRReg<61, "sp">, DwarfRegNum<[61]>;
  //return address
  def RA_REG : NaplesPUGPRReg<62, "ra">, DwarfRegNum<[62]>;
  //PC
  def PC_REG : NaplesPUGPRReg<63, "pc">, DwarfRegNum<[63]>;

  // General Purpose vectorial registers
  foreach i = 0-63 in {
    def V#i : NaplesPUGPRReg<i, "v"#i>, DwarfRegNum<[!add(i, 64)]>;
  }

//===----------------------------------------------------------------------===//
// Register Classes
//===----------------------------------------------------------------------===//

// This register class should not be used to hold i64/f64 values, use the GPR64
// register class for that. The i64/f64 type is included here to allow i64/f64
// patterns using the instructions.
def GPR32 : RegisterClass<"NaplesPU", [i32, f32], 32, (add (sequence "S%u", 0, 57),
  TR_REG, MR_REG, FP_REG, SP_REG, RA_REG, PC_REG)>

def VR512W : RegisterClass<"NaplesPU", [v16i32, v16f32, v16i8, v16i16], 512, (sequence "V%u", 0, 63)>;