Home | History | Annotate | Download | only in radeon
      1 #===-- SIGenRegisterInfo.pl - Script for generating register info files ----===#
      2 #
      3 #                     The LLVM Compiler Infrastructure
      4 #
      5 # This file is distributed under the University of Illinois Open Source
      6 # License. See LICENSE.TXT for details.
      7 #
      8 #===------------------------------------------------------------------------===#
      9 #
     10 # This perl script prints to stdout .td code to be used as SIRegisterInfo.td
     11 # it also generates a file called SIHwRegInfo.include, which contains helper
     12 # functions for determining the hw encoding of registers.
     13 #
     14 #===------------------------------------------------------------------------===#
     15 
     16 use strict;
     17 use warnings;
     18 
     19 my $SGPR_COUNT = 104;
     20 my $VGPR_COUNT = 256;
     21 
     22 my $SGPR_MAX_IDX = $SGPR_COUNT - 1;
     23 my $VGPR_MAX_IDX = $VGPR_COUNT - 1;
     24 
     25 my $INDEX_FILE = defined($ARGV[0]) ? $ARGV[0] : '';
     26 
     27 print <<STRING;
     28 
     29 let Namespace = "AMDGPU" in {
     30   def low : SubRegIndex;
     31   def high : SubRegIndex;
     32 
     33   def sub0 : SubRegIndex;
     34   def sub1 : SubRegIndex;
     35   def sub2 : SubRegIndex;
     36   def sub3 : SubRegIndex;
     37   def sub4 : SubRegIndex;
     38   def sub5 : SubRegIndex;
     39   def sub6 : SubRegIndex;
     40   def sub7 : SubRegIndex;
     41 }
     42 
     43 class SIReg <string n> : Register<n> {
     44   let Namespace = "AMDGPU";
     45 }
     46 
     47 class SI_64 <string n, list<Register> subregs> : RegisterWithSubRegs<n, subregs> {
     48   let Namespace = "AMDGPU";
     49   let SubRegIndices = [low, high];
     50 }
     51 
     52 class SI_128 <string n, list<Register> subregs> : RegisterWithSubRegs<n, subregs> {
     53   let Namespace = "AMDGPU";
     54   let SubRegIndices = [sel_x, sel_y, sel_z, sel_w];
     55 }
     56 
     57 class SI_256 <string n, list<Register> subregs> : RegisterWithSubRegs<n, subregs> {
     58   let Namespace = "AMDGPU";
     59   let SubRegIndices = [sub0, sub1, sub2, sub3, sub4, sub5, sub6, sub7];
     60 }
     61 
     62 class SGPR_32 <bits<8> num, string name> : SIReg<name> {
     63   field bits<8> Num;
     64 
     65   let Num = num;
     66 }
     67 
     68 
     69 class VGPR_32 <bits<9> num, string name> : SIReg<name> {
     70   field bits<9> Num;
     71 
     72   let Num = num;
     73 }
     74 
     75 class SGPR_64 <bits<8> num, string name, list<Register> subregs> :
     76     SI_64 <name, subregs>;
     77 
     78 class VGPR_64 <bits<9> num, string name, list<Register> subregs> :
     79     SI_64 <name, subregs>;
     80 
     81 class SGPR_128 <bits<8> num, string name, list<Register> subregs> :
     82     SI_128 <name, subregs>;
     83 
     84 class VGPR_128 <bits<9> num, string name, list<Register> subregs> :
     85     SI_128 <name, subregs>;
     86 
     87 class SGPR_256 <bits<8> num, string name, list<Register> subregs> :
     88     SI_256 <name, subregs>;
     89 
     90 def VCC : SIReg<"VCC">;
     91 def EXEC : SIReg<"EXEC">;
     92 def SCC : SIReg<"SCC">;
     93 def SREG_LIT_0 : SIReg <"S LIT 0">;
     94 
     95 def M0 : SIReg <"M0">;
     96 
     97 //Interpolation registers
     98 
     99 def PERSP_SAMPLE_I : SIReg <"PERSP_SAMPLE_I">;
    100 def PERSP_SAMPLE_J : SIReg <"PERSP_SAMPLE_J">;
    101 def PERSP_CENTER_I : SIReg <"PERSP_CENTER_I">;
    102 def PERSP_CENTER_J : SIReg <"PERSP_CENTER_J">;
    103 def PERSP_CENTROID_I : SIReg <"PERSP_CENTROID_I">;
    104 def PERSP_CENTROID_J : SIReg <"PERP_CENTROID_J">;
    105 def PERSP_I_W : SIReg <"PERSP_I_W">;
    106 def PERSP_J_W : SIReg <"PERSP_J_W">;
    107 def PERSP_1_W : SIReg <"PERSP_1_W">;
    108 def LINEAR_SAMPLE_I : SIReg <"LINEAR_SAMPLE_I">;
    109 def LINEAR_SAMPLE_J : SIReg <"LINEAR_SAMPLE_J">;
    110 def LINEAR_CENTER_I : SIReg <"LINEAR_CENTER_I">;
    111 def LINEAR_CENTER_J : SIReg <"LINEAR_CENTER_J">;
    112 def LINEAR_CENTROID_I : SIReg <"LINEAR_CENTROID_I">;
    113 def LINEAR_CENTROID_J : SIReg <"LINEAR_CENTROID_J">;
    114 def LINE_STIPPLE_TEX_COORD : SIReg <"LINE_STIPPLE_TEX_COORD">;
    115 def POS_X_FLOAT : SIReg <"POS_X_FLOAT">;
    116 def POS_Y_FLOAT : SIReg <"POS_Y_FLOAT">;
    117 def POS_Z_FLOAT : SIReg <"POS_Z_FLOAT">;
    118 def POS_W_FLOAT : SIReg <"POS_W_FLOAT">;
    119 def FRONT_FACE : SIReg <"FRONT_FACE">;
    120 def ANCILLARY : SIReg <"ANCILLARY">;
    121 def SAMPLE_COVERAGE : SIReg <"SAMPLE_COVERAGE">;
    122 def POS_FIXED_PT : SIReg <"POS_FIXED_PT">;
    123 
    124 STRING
    125 
    126 #32 bit register
    127 
    128 my @SGPR;
    129 for (my $i = 0; $i < $SGPR_COUNT; $i++) {
    130   print "def SGPR$i : SGPR_32 <$i, \"SGPR$i\">;\n";
    131   $SGPR[$i] = "SGPR$i";
    132 }
    133 
    134 my @VGPR;
    135 for (my $i = 0; $i < $VGPR_COUNT; $i++) {
    136   print "def VGPR$i : VGPR_32 <$i, \"VGPR$i\">;\n";
    137   $VGPR[$i] = "VGPR$i";
    138 }
    139 
    140 print <<STRING;
    141 
    142 def SReg_32 : RegisterClass<"AMDGPU", [f32, i32], 32,
    143     (add (sequence "SGPR%u", 0, $SGPR_MAX_IDX),  SREG_LIT_0, M0)
    144 >;
    145 
    146 def VReg_32 : RegisterClass<"AMDGPU", [f32, i32], 32,
    147     (add (sequence "VGPR%u", 0, $VGPR_MAX_IDX),
    148     PERSP_SAMPLE_I, PERSP_SAMPLE_J,
    149     PERSP_CENTER_I, PERSP_CENTER_J,
    150     PERSP_CENTROID_I, PERSP_CENTROID_J,
    151     PERSP_I_W, PERSP_J_W, PERSP_1_W,
    152     LINEAR_SAMPLE_I, LINEAR_SAMPLE_J,
    153     LINEAR_CENTER_I, LINEAR_CENTER_J,
    154     LINEAR_CENTROID_I, LINEAR_CENTROID_J,
    155     LINE_STIPPLE_TEX_COORD,
    156     POS_X_FLOAT,
    157     POS_Y_FLOAT,
    158     POS_Z_FLOAT,
    159     POS_W_FLOAT,
    160     FRONT_FACE,
    161     ANCILLARY,
    162     SAMPLE_COVERAGE,
    163     POS_FIXED_PT
    164     )
    165 >;
    166 
    167 def AllReg_32 : RegisterClass<"AMDGPU", [f32, i32], 32,
    168     (add VReg_32, SReg_32)
    169 >;
    170 
    171 def SCCReg : RegisterClass<"AMDGPU", [i1], 1, (add SCC)>;
    172 def VCCReg : RegisterClass<"AMDGPU", [i1], 1, (add VCC)>;
    173 def EXECReg : RegisterClass<"AMDGPU", [i1], 1, (add EXEC)>;
    174 def M0Reg : RegisterClass<"AMDGPU", [i32], 32, (add M0)>;
    175 
    176 
    177 STRING
    178 
    179 my @subregs_64 = ('low', 'high');
    180 my @subregs_128 = ('sel_x', 'sel_y', 'sel_z', 'sel_w');
    181 my @subregs_256 = ('sub0', 'sub1', 'sub2', 'sub3', 'sub4', 'sub5', 'sub6', 'sub7');
    182 
    183 my @SGPR64 = print_sgpr_class(64, \@subregs_64, ('i64'));
    184 my @SGPR128 = print_sgpr_class(128, \@subregs_128, ('v4f32', 'v4i32'));
    185 my @SGPR256 = print_sgpr_class(256, \@subregs_256, ('v8i32'));
    186 
    187 my @VGPR64 = print_vgpr_class(64, \@subregs_64, ('i64'));
    188 my @VGPR128 = print_vgpr_class(128, \@subregs_128, ('v4f32'));
    189 
    190 
    191 my $sgpr64_list = join(',', @SGPR64);
    192 my $vgpr64_list = join(',', @VGPR64);
    193 print <<STRING;
    194 
    195 def AllReg_64 : RegisterClass<"AMDGPU", [f64, i64], 64,
    196     (add $sgpr64_list, $vgpr64_list)
    197 >;
    198 
    199 STRING
    200 
    201 if ($INDEX_FILE ne '') {
    202   open(my $fh, ">", $INDEX_FILE);
    203   my %hw_values;
    204 
    205   for (my $i = 0; $i <= $#SGPR; $i++) {
    206     push (@{$hw_values{$i}}, $SGPR[$i]);
    207   }
    208 
    209   for (my $i = 0; $i <= $#SGPR64; $i++) {
    210     push (@{$hw_values{$i * 2}}, $SGPR64[$i])
    211   }
    212 
    213   for (my $i = 0; $i <= $#SGPR128; $i++) {
    214     push (@{$hw_values{$i * 4}}, $SGPR128[$i]);
    215   }
    216 
    217   for (my $i = 0; $i <= $#SGPR256; $i++) {
    218     push (@{$hw_values{$i * 8}}, $SGPR256[$i]);
    219   }
    220 
    221   for (my $i = 0; $i <= $#VGPR; $i++) {
    222     push (@{$hw_values{$i}}, $VGPR[$i]);
    223   }
    224   for (my $i = 0; $i <= $#VGPR64; $i++) {
    225     push (@{$hw_values{$i * 2}}, $VGPR64[$i]);
    226   }
    227 
    228   for (my $i = 0; $i <= $#VGPR128; $i++) {
    229     push (@{$hw_values{$i * 4}}, $VGPR128[$i]);
    230   }
    231 
    232 
    233   print $fh "unsigned SIRegisterInfo::getHWRegNum(unsigned reg) const\n{\n  switch(reg) {\n";
    234   for my $key (keys(%hw_values)) {
    235     my @names = @{$hw_values{$key}};
    236     for my $regname (@names) {
    237       print $fh "  case AMDGPU::$regname:\n"
    238     }
    239     print $fh "    return $key;\n";
    240   }
    241   print $fh "  default: return 0;\n  }\n}\n"
    242 }
    243 
    244 
    245 
    246 
    247 sub print_sgpr_class {
    248   my ($reg_width, $sub_reg_ref, @types) = @_;
    249   return print_reg_class('SReg', 'SGPR', $reg_width, $SGPR_COUNT, $sub_reg_ref, @types);
    250 }
    251 
    252 sub print_vgpr_class {
    253   my ($reg_width, $sub_reg_ref, @types) = @_;
    254   return print_reg_class('VReg', 'VGPR', $reg_width, $VGPR_COUNT, $sub_reg_ref, @types);
    255 }
    256 
    257 sub print_reg_class {
    258   my ($class_prefix, $reg_prefix, $reg_width, $reg_count, $sub_reg_ref, @types) = @_;
    259   my @registers;
    260   my $component_count = $reg_width / 32;
    261 
    262   for (my $i = 0; $i < $reg_count; $i += $component_count) {
    263     my $reg_name = $reg_prefix . $i . '_' . $reg_width;
    264     my @sub_regs;
    265     for (my $idx = 0; $idx < $component_count; $idx++) {
    266       my $sub_idx = $i + $idx;
    267       push(@sub_regs, $reg_prefix . $sub_idx);
    268     }
    269     print "def $reg_name : $reg_prefix\_$reg_width <$i, \"$reg_name\", [ ", join(',', @sub_regs) , "]>;\n";
    270     push (@registers, $reg_name);
    271   }
    272 
    273   #Add VCC to SReg_64
    274   if ($class_prefix eq 'SReg' and $reg_width == 64) {
    275     push (@registers, 'VCC')
    276   }
    277 
    278   #Add EXEC to SReg_64
    279   if ($class_prefix eq 'SReg' and $reg_width == 64) {
    280     push (@registers, 'EXEC')
    281   }
    282 
    283   my $reg_list = join(', ', @registers);
    284 
    285   print "def $class_prefix\_$reg_width : RegisterClass<\"AMDGPU\", [" . join (', ', @types) . "], $reg_width,\n  (add $reg_list)\n>{\n";
    286   print "  let SubRegClasses = [($class_prefix\_", ($reg_width / $component_count) , ' ', join(', ', @{$sub_reg_ref}), ")];\n}\n";
    287   return @registers;
    288 }
    289