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