sparc: implement float->unsigned conversions
[libfirm] / ir / be / scripts / generate_regalloc_if.pl
1 #!/usr/bin/perl -w
2
3 #
4 # Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
5 #
6 # This file is part of libFirm.
7 #
8 # This file may be distributed and/or modified under the terms of the
9 # GNU General Public License version 2 as published by the Free Software
10 # Foundation and appearing in the file LICENSE.GPL included in the
11 # packaging of this file.
12 #
13 # Licensees holding valid libFirm Professional Edition licenses may use
14 # this file in accordance with the libFirm Commercial License.
15 # Agreement provided with the Software.
16 #
17 # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 # WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE.
20 #
21
22 # This script generates C code which creates ands sets up functions and
23 # data structures for the register allocator.
24 # Creation: 2005/11/14
25
26 use strict;
27 use Data::Dumper;
28 use integer;
29
30 my $specfile   = $ARGV[0];
31 my $target_dir = $ARGV[1];
32
33 our $arch;
34 our %reg_classes;
35 our %cpu;
36
37 # include spec file
38
39 my $return;
40
41 use strict "subs";
42 unless ($return = do $specfile) {
43         die "Fatal error: couldn't parse $specfile: $@" if $@;
44         die "Fatal error: couldn't do $specfile: $!"    unless defined $return;
45         die "Fatal error: couldn't run $specfile"       unless $return;
46 }
47 use strict "subs";
48
49 my $target_c   = $target_dir."/gen_".$arch."_regalloc_if.c";
50 my $target_h   = $target_dir."/gen_".$arch."_regalloc_if.h";
51
52 # helper function
53 sub translate_reg_type {
54         my $t = shift;
55
56         if ($t == 0) {
57                 return "arch_register_type_none";
58         }
59         else {
60                 my @types;
61
62                 if ($t & 1) {
63                         push(@types, "arch_register_type_ignore");
64                 }
65
66                 if ($t & 2) {
67                         push(@types, "arch_register_type_joker");
68                 }
69
70                 if ($t & 4) {
71                         push(@types, "arch_register_type_virtual");
72                 }
73
74                 if ($t & 8) {
75                         push(@types, "arch_register_type_state");
76                 }
77
78                 return join(" | ", @types);
79         }
80 }
81
82 # stacks for output
83 my $regtypes_def; # stack for the register type variables definitions
84 my $regtypes_decl;# stack for the register type variables declarations
85 my @regclasses;   # stack for the register class variables
86 my $classdef;     # stack to define a name for a class index
87 my $regdef;       # stack to define a name for a register index
88 my $regdef2;
89 my $regcounts;
90 my $reginit;      # stack for the register type inits
91 my $single_constraints_decls;
92 my $single_constraints;
93
94 my $class_ptr;
95 my $class_idx = 0;
96
97 my %regclass2len = ();
98 my %reg2class = ();
99
100 $classdef .= "enum reg_classes {\n";
101
102 my $class_mode;
103
104 foreach my $class_name (keys(%reg_classes)) {
105         my @class = @{ $reg_classes{"$class_name"} };
106
107         my $idx = 0;
108         foreach (@class) {
109                 if (defined($_->{name})) {
110                         $reg2class{$_->{name}} = {
111                                 "class" => $class_name,
112                                 "index" => $idx
113                         };
114                 }
115                 $idx++;
116         }
117         $regclass2len{$class_name} = $idx;
118 }
119
120 sub get_limited_array {
121         my $reg      = shift;
122         my $regclass = $reg2class{"$reg"}{"class"};
123         my $ucname   = uc($reg);
124         my $result   = "{ ";
125
126         my $limitedbitsetlen = $regclass2len{$regclass};
127         my $arraylen         = ($limitedbitsetlen+31) / 32;
128         my $firstreg         = uc($reg_classes{$regclass}[0]->{"name"});
129         my $classuc          = uc($regclass);
130         my $first            = 1;
131         for (my $i = 0; $i < $arraylen; ++$i) {
132                 if ($first) {
133                         $first = 0;
134                 } else {
135                         $result .= ", ";
136                 }
137
138                 my $index = $reg2class{"$reg"}{"index"};
139                 if ($index >= $i*32 && $index < ($i+1)*32) {
140                         if ($i > 0) {
141                                 $result .= "(1 << (REG_${classuc}_${ucname} % 32))";
142                         } else {
143                                 $result .= "(1 << REG_${classuc}_${ucname})";
144                         }
145                 } else {
146                         $result .= "0";
147                 }
148         }
149         $result .= " }";
150 }
151
152 # generate register type and class variable, init function and default requirements
153 foreach my $class_name (keys(%reg_classes)) {
154         my @class         = @{ $reg_classes{"$class_name"} };
155         my $old_classname = $class_name;
156
157         $class_name = $arch."_".$class_name;
158         $class_ptr  = "&".$arch."_reg_classes[CLASS_".$class_name."]";
159         my $flags = pop(@class);
160         $class_mode  = $flags->{"mode"};
161         my $class_flags = $flags->{"flags"};
162         my $flags_prepared = "";
163
164         if(defined($class_flags)) {
165                 my $first = 1;
166                 foreach my $flag (split(/\|/, $class_flags)) {
167                         if(!$first) {
168                                 $flags_prepared .= "|";
169                         } else {
170                                 $first = 0;
171                         }
172                         $flags_prepared .= "arch_register_class_flag_$flag";
173                 }
174         } else {
175                 $flags_prepared = "arch_register_class_flag_none";
176         }
177
178         $single_constraints .= <<EOF;
179 static const arch_register_req_t ${arch}_class_reg_req_${old_classname} = {
180         arch_register_req_type_normal,
181         &${arch}_reg_classes[CLASS_${arch}_${old_classname}],
182         NULL,
183         0,
184         0,
185         1
186 };
187 EOF
188
189         $classdef .= "\tCLASS_$class_name = $class_idx,\n";
190         my $numregs = @class;
191         my $first_reg = "&${arch}_registers[REG_". uc($class[0]->{"name"}) . "]";
192         push(@regclasses, "{ $class_idx, \"$class_name\", $numregs, NULL, $first_reg, $flags_prepared, &${arch}_class_reg_req_${old_classname} }");
193
194         my $idx = 0;
195         $reginit .= "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n";
196         my $lastreg;
197         foreach (@class) {
198                 my $name   = $_->{"name"};
199                 my $ucname = uc($name);
200                 my $type   = "arch_register_type_none";
201                 $type = translate_reg_type($_->{"type"}) if (exists($_->{"type"}));
202                 # realname is name if not set by user
203                 $_->{"realname"} = $_->{"name"} if (! exists($_->{"realname"}));
204                 my $realname = $_->{realname};
205                 my $classuc = uc($old_classname);
206
207                 $regdef  .= "\tREG_${ucname},\n";
208                 $regdef2 .= "\tREG_${classuc}_${ucname} = $idx,\n";
209
210                 $regtypes_def .= <<EOF;
211         {
212                 "${realname}",
213                 ${class_ptr},
214                 REG_${classuc}_${ucname},
215                 REG_${ucname},
216                 ${type},
217                 &${arch}_single_reg_req_${old_classname}_${name}
218         },
219 EOF
220
221                 my $limitedarray = get_limited_array($name);
222                 $single_constraints .= <<EOF;
223 static const unsigned ${arch}_limited_${old_classname}_${name} [] = ${limitedarray};
224 static const arch_register_req_t ${arch}_single_reg_req_${old_classname}_${name} = {
225         arch_register_req_type_limited,
226         ${class_ptr},
227         ${arch}_limited_${old_classname}_${name},
228         0,
229         0,
230         1
231 };
232 EOF
233
234                 $lastreg = $ucname;
235                 $idx++;
236         }
237         $regcounts .= "\tN_${class_name}_REGS = $numregs,\n";
238
239         $class_idx++;
240 }
241
242 my $archuc = uc($arch);
243
244 $classdef .= "\tN_${archuc}_CLASSES = ".scalar(keys(%reg_classes))."\n";
245 $classdef .= "};\n\n";
246
247 # generate header (external usage) file
248 open(OUT, ">$target_h") || die("Fatal error: Could not open $target_h, reason: $!\n");
249
250 my $creation_time = localtime(time());
251
252 print OUT<<EOF;
253 /**
254  * \@file
255  * \@brief Contains additional external requirements defs for external includes.
256  * \@note   DO NOT EDIT THIS FILE, your changes will be lost.
257  *         Edit $specfile instead.
258  *         created by: $0 $specfile $target_dir
259  * \@date   $creation_time
260  */
261 #ifndef FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
262 #define FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
263
264 #include "bearch.h"
265 #include "${arch}_nodes_attr.h"
266
267 /** global register indices for ${arch} registers */
268 enum reg_indices {
269 ${regdef}
270         N_${archuc}_REGISTERS
271 };
272 /** local register indices for ${arch} registers */
273 enum {
274 ${regdef2}
275 };
276
277 /** number of registers in ${arch} register classes. */
278 enum {
279 ${regcounts}
280 };
281 ${classdef}
282
283 extern const arch_register_t ${arch}_registers[N_${archuc}_REGISTERS];
284
285 extern arch_register_class_t ${arch}_reg_classes[N_${archuc}_CLASSES];
286
287 void ${arch}_register_init(void);
288
289 #endif
290 EOF
291 close(OUT);
292
293
294 # generate c file
295 open(OUT, ">$target_c") || die("Fatal error: Could not open $target_c, reason: $!\n");
296
297 $creation_time = localtime(time());
298
299 print OUT<<EOF;
300 /**
301  * \@file
302  * \@brief  The generated interface for the register allocator.
303  *          Contains register classes and types and register constraints
304  *          for all nodes where constraints were given in spec.
305  * \@note    DO NOT EDIT THIS FILE, your changes will be lost.
306  *          Edit $specfile instead.
307  *          created by: $0 $specfile $target_dir
308  * \$date    $creation_time
309  */
310 #include "config.h"
311
312 #include "gen_${arch}_regalloc_if.h"
313 #include "bearch_${arch}_t.h"
314 #include "irmode.h"
315
316 ${single_constraints}
317 EOF
318
319 print OUT "arch_register_class_t ${arch}_reg_classes[] = {\n\t".join(",\n\t", @regclasses)."\n};\n\n";
320
321 print OUT<<EOF;
322
323 /** The array of all registers in the ${arch} architecture, sorted by its global index.*/
324 const arch_register_t ${arch}_registers[] = {
325 ${regtypes_def}
326 };
327
328 /**
329  * Initializes ${arch} register classes.
330  */
331 void ${arch}_register_init(void)
332 {
333 ${reginit}
334 }
335 EOF
336 close(OUT);