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
16use strict;
17use warnings;
18
19my $SGPR_COUNT = 104;
20my $VGPR_COUNT = 256;
21
22my $SGPR_MAX_IDX = $SGPR_COUNT - 1;
23my $VGPR_MAX_IDX = $VGPR_COUNT - 1;
24
25my $INDEX_FILE = defined($ARGV[0]) ? $ARGV[0] : '';
26
27print <<STRING;
28
29let 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
43class SIReg <string n> : Register<n> {
44  let Namespace = "AMDGPU";
45}
46
47class SI_64 <string n, list<Register> subregs> : RegisterWithSubRegs<n, subregs> {
48  let Namespace = "AMDGPU";
49  let SubRegIndices = [low, high];
50}
51
52class 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
57class 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
62class SGPR_32 <bits<8> num, string name> : SIReg<name> {
63  field bits<8> Num;
64
65  let Num = num;
66}
67
68
69class VGPR_32 <bits<9> num, string name> : SIReg<name> {
70  field bits<9> Num;
71
72  let Num = num;
73}
74
75class SGPR_64 <bits<8> num, string name, list<Register> subregs> :
76    SI_64 <name, subregs>;
77
78class VGPR_64 <bits<9> num, string name, list<Register> subregs> :
79    SI_64 <name, subregs>;
80
81class SGPR_128 <bits<8> num, string name, list<Register> subregs> :
82    SI_128 <name, subregs>;
83
84class VGPR_128 <bits<9> num, string name, list<Register> subregs> :
85    SI_128 <name, subregs>;
86
87class SGPR_256 <bits<8> num, string name, list<Register> subregs> :
88    SI_256 <name, subregs>;
89
90def VCC : SIReg<"VCC">;
91def EXEC : SIReg<"EXEC">;
92def SCC : SIReg<"SCC">;
93def SREG_LIT_0 : SIReg <"S LIT 0">;
94
95def M0 : SIReg <"M0">;
96
97//Interpolation registers
98
99def PERSP_SAMPLE_I : SIReg <"PERSP_SAMPLE_I">;
100def PERSP_SAMPLE_J : SIReg <"PERSP_SAMPLE_J">;
101def PERSP_CENTER_I : SIReg <"PERSP_CENTER_I">;
102def PERSP_CENTER_J : SIReg <"PERSP_CENTER_J">;
103def PERSP_CENTROID_I : SIReg <"PERSP_CENTROID_I">;
104def PERSP_CENTROID_J : SIReg <"PERP_CENTROID_J">;
105def PERSP_I_W : SIReg <"PERSP_I_W">;
106def PERSP_J_W : SIReg <"PERSP_J_W">;
107def PERSP_1_W : SIReg <"PERSP_1_W">;
108def LINEAR_SAMPLE_I : SIReg <"LINEAR_SAMPLE_I">;
109def LINEAR_SAMPLE_J : SIReg <"LINEAR_SAMPLE_J">;
110def LINEAR_CENTER_I : SIReg <"LINEAR_CENTER_I">;
111def LINEAR_CENTER_J : SIReg <"LINEAR_CENTER_J">;
112def LINEAR_CENTROID_I : SIReg <"LINEAR_CENTROID_I">;
113def LINEAR_CENTROID_J : SIReg <"LINEAR_CENTROID_J">;
114def LINE_STIPPLE_TEX_COORD : SIReg <"LINE_STIPPLE_TEX_COORD">;
115def POS_X_FLOAT : SIReg <"POS_X_FLOAT">;
116def POS_Y_FLOAT : SIReg <"POS_Y_FLOAT">;
117def POS_Z_FLOAT : SIReg <"POS_Z_FLOAT">;
118def POS_W_FLOAT : SIReg <"POS_W_FLOAT">;
119def FRONT_FACE : SIReg <"FRONT_FACE">;
120def ANCILLARY : SIReg <"ANCILLARY">;
121def SAMPLE_COVERAGE : SIReg <"SAMPLE_COVERAGE">;
122def POS_FIXED_PT : SIReg <"POS_FIXED_PT">;
123
124STRING
125
126#32 bit register
127
128my @SGPR;
129for (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
134my @VGPR;
135for (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
140print <<STRING;
141
142def SReg_32 : RegisterClass<"AMDGPU", [f32, i32], 32,
143    (add (sequence "SGPR%u", 0, $SGPR_MAX_IDX),  SREG_LIT_0, M0)
144>;
145
146def 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
167def AllReg_32 : RegisterClass<"AMDGPU", [f32, i32], 32,
168    (add VReg_32, SReg_32)
169>;
170
171def SCCReg : RegisterClass<"AMDGPU", [i1], 1, (add SCC)>;
172def VCCReg : RegisterClass<"AMDGPU", [i1], 1, (add VCC)>;
173def EXECReg : RegisterClass<"AMDGPU", [i1], 1, (add EXEC)>;
174def M0Reg : RegisterClass<"AMDGPU", [i32], 32, (add M0)>;
175
176
177STRING
178
179my @subregs_64 = ('low', 'high');
180my @subregs_128 = ('sel_x', 'sel_y', 'sel_z', 'sel_w');
181my @subregs_256 = ('sub0', 'sub1', 'sub2', 'sub3', 'sub4', 'sub5', 'sub6', 'sub7');
182
183my @SGPR64 = print_sgpr_class(64, \@subregs_64, ('i64'));
184my @SGPR128 = print_sgpr_class(128, \@subregs_128, ('v4f32', 'v4i32'));
185my @SGPR256 = print_sgpr_class(256, \@subregs_256, ('v8i32'));
186
187my @VGPR64 = print_vgpr_class(64, \@subregs_64, ('i64'));
188my @VGPR128 = print_vgpr_class(128, \@subregs_128, ('v4f32'));
189
190
191my $sgpr64_list = join(',', @SGPR64);
192my $vgpr64_list = join(',', @VGPR64);
193print <<STRING;
194
195def AllReg_64 : RegisterClass<"AMDGPU", [f64, i64], 64,
196    (add $sgpr64_list, $vgpr64_list)
197>;
198
199STRING
200
201if ($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
247sub 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
252sub 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
257sub 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