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