OSDN Git Service

radeonsi: initial WIP SI code
[android-x86/external-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