radeonsi: initial WIP SI code
[mesa.git] / src / gallium / drivers / radeon / R600GenRegisterInfo.pl
1 #===-- R600GenRegisterInfo.pl - TODO: Add brief description -------===#
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 # TODO: Add full description
11 #
12 #===----------------------------------------------------------------------===#
13
14 use strict;
15 use warnings;
16
17 use AMDGPUConstants;
18
19 my $CREG_MAX = CONST_REG_COUNT - 1;
20 my $TREG_MAX = TEMP_REG_COUNT - 1;
21
22 print <<STRING;
23
24 class R600Reg <string name> : Register<name> {
25 let Namespace = "AMDIL";
26 }
27
28 class R600Reg_128<string n, list<Register> subregs> : RegisterWithSubRegs<n, subregs> {
29 let Namespace = "AMDIL";
30 let SubRegIndices = [sel_x, sel_y, sel_z, sel_w];
31 }
32
33 STRING
34
35 my $i;
36
37 ### REG DEFS ###
38
39 my @creg_list = print_reg_defs(CONST_REG_COUNT * 4, "C");
40 my @treg_list = print_reg_defs(TEMP_REG_COUNT * 4, "T");
41
42 my @t128reg;
43 my @treg_x;
44 for (my $i = 0; $i < TEMP_REG_COUNT; $i++) {
45 my $name = "T$i\_XYZW";
46 print qq{def $name : R600Reg_128 <"T$i.XYZW", [T$i\_X, T$i\_Y, T$i\_Z, T$i\_W] >;\n};
47 $t128reg[$i] = $name;
48 $treg_x[$i] = "T$i\_X";
49 }
50
51 my $treg_string = join(",", @treg_list);
52 my $creg_list = join(",", @creg_list);
53 my $t128_string = join(",", @t128reg);
54 my $treg_x_string = join(",", @treg_x);
55 print <<STRING;
56
57 class RegSet <dag s> {
58 dag set = s;
59 }
60
61 def ZERO : R600Reg<"0.0">;
62 def HALF : R600Reg<"0.5">;
63 def ONE : R600Reg<"1.0">;
64 def ONE_INT : R600Reg<"1">;
65 def NEG_HALF : R600Reg<"-0.5">;
66 def NEG_ONE : R600Reg<"-1.0">;
67 def PV_X : R600Reg<"pv.x">;
68 def ALU_LITERAL_X : R600Reg<"literal.x">;
69
70 def R600_CReg32 : RegisterClass <"AMDIL", [f32, i32], 32, (add
71 $creg_list)>;
72
73 def R600_TReg32 : RegisterClass <"AMDIL", [f32, i32], 32, (add
74 $treg_string)>;
75
76 def R600_TReg32_X : RegisterClass <"AMDIL", [f32, i32], 32, (add
77 $treg_x_string)>;
78
79 def R600_Reg32 : RegisterClass <"AMDIL", [f32, i32], 32, (add
80 R600_TReg32,
81 R600_CReg32,
82 ZERO, HALF, ONE, ONE_INT, PV_X, ALU_LITERAL_X, NEG_ONE, NEG_HALF)>;
83
84 def R600_Reg128 : RegisterClass<"AMDIL", [v4f32], 128, (add
85 $t128_string)>
86 {
87 let SubRegClasses = [(R600_TReg32 sel_x, sel_y, sel_z, sel_w)];
88 }
89
90 STRING
91
92 my %index_map;
93 my %chan_map;
94
95 for ($i = 0; $i <= $#creg_list; $i++) {
96 push(@{$index_map{get_hw_index($i)}}, $creg_list[$i]);
97 push(@{$chan_map{get_chan_str($i)}}, $creg_list[$i]);
98 }
99
100 for ($i = 0; $i <= $#treg_list; $i++) {
101 push(@{$index_map{get_hw_index($i)}}, $treg_list[$i]);
102 push(@{$chan_map{get_chan_str($i)}}, $treg_list[$i]);
103 }
104
105 for ($i = 0; $i <= $#t128reg; $i++) {
106 push(@{$index_map{$i}}, $t128reg[$i]);
107 push(@{$chan_map{'X'}}, $t128reg[$i]);
108 }
109
110 open(OUTFILE, ">", "R600HwRegInfo.include");
111
112 print OUTFILE <<STRING;
113
114 unsigned R600RegisterInfo::getHWRegIndexGen(unsigned reg) const
115 {
116 switch(reg) {
117 default: assert(!"Unknown register"); return 0;
118 STRING
119 foreach my $key (keys(%index_map)) {
120 foreach my $reg (@{$index_map{$key}}) {
121 print OUTFILE " case AMDIL::$reg:\n";
122 }
123 print OUTFILE " return $key;\n\n";
124 }
125
126 print OUTFILE " }\n}\n\n";
127
128 print OUTFILE <<STRING;
129
130 unsigned R600RegisterInfo::getHWRegChanGen(unsigned reg) const
131 {
132 switch(reg) {
133 default: assert(!"Unknown register"); return 0;
134 STRING
135
136 foreach my $key (keys(%chan_map)) {
137 foreach my $reg (@{$chan_map{$key}}) {
138 print OUTFILE " case AMDIL::$reg:\n";
139 }
140 my $val;
141 if ($key eq 'X') {
142 $val = 0;
143 } elsif ($key eq 'Y') {
144 $val = 1;
145 } elsif ($key eq 'Z') {
146 $val = 2;
147 } elsif ($key eq 'W') {
148 $val = 3;
149 } else {
150 die("Unknown chan value; $key");
151 }
152 print OUTFILE " return $val;\n\n";
153 }
154
155 print OUTFILE " }\n}\n\n";
156
157 sub print_reg_defs {
158 my ($count, $prefix) = @_;
159
160 my @reg_list;
161
162 for ($i = 0; $i < $count; $i++) {
163 my $hw_index = get_hw_index($i);
164 my $chan= get_chan_str($i);
165 my $name = "$prefix$hw_index\_$chan";
166 print qq{def $name : R600Reg <"$prefix$hw_index.$chan">;\n};
167 $reg_list[$i] = $name;
168 }
169 return @reg_list;
170 }
171