bearch: remove arch_register_type_joker.
[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_virtual");
68                 }
69
70                 if ($t & 4) {
71                         push(@types, "arch_register_type_state");
72                 }
73
74                 return join(" | ", @types);
75         }
76 }
77
78 # stacks for output
79 my $regtypes_def; # stack for the register type variables definitions
80 my $regtypes_decl;# stack for the register type variables declarations
81 my @regclasses;   # stack for the register class variables
82 my $classdef;     # stack to define a name for a class index
83 my $regdef;       # stack to define a name for a register index
84 my $regdef2;
85 my $regcounts;
86 my $reginit;      # stack for the register type inits
87 my $single_constraints_decls;
88 my $single_constraints;
89
90 my $class_ptr;
91 my $class_idx = 0;
92
93 my %regclass2len = ();
94 my %reg2class = ();
95
96 $classdef .= "enum reg_classes {\n";
97
98 my $class_mode;
99
100 foreach my $class_name (keys(%reg_classes)) {
101         my @class = @{ $reg_classes{"$class_name"} };
102
103         my $idx = 0;
104         foreach (@class) {
105                 if (defined($_->{name})) {
106                         $reg2class{$_->{name}} = {
107                                 "class" => $class_name,
108                                 "index" => $idx
109                         };
110                 }
111                 $idx++;
112         }
113         $regclass2len{$class_name} = $idx;
114 }
115
116 sub get_limited_array {
117         my $reg      = shift;
118         my $regclass = $reg2class{"$reg"}{"class"};
119         my $ucname   = uc($reg);
120         my $result   = "{ ";
121
122         my $limitedbitsetlen = $regclass2len{$regclass};
123         my $arraylen         = ($limitedbitsetlen+31) / 32;
124         my $firstreg         = uc($reg_classes{$regclass}[0]->{"name"});
125         my $classuc          = uc($regclass);
126         my $first            = 1;
127         for (my $i = 0; $i < $arraylen; ++$i) {
128                 if ($first) {
129                         $first = 0;
130                 } else {
131                         $result .= ", ";
132                 }
133
134                 my $index = $reg2class{"$reg"}{"index"};
135                 if ($index >= $i*32 && $index < ($i+1)*32) {
136                         if ($i > 0) {
137                                 $result .= "(1 << (REG_${classuc}_${ucname} % 32))";
138                         } else {
139                                 $result .= "(1 << REG_${classuc}_${ucname})";
140                         }
141                 } else {
142                         $result .= "0";
143                 }
144         }
145         $result .= " }";
146 }
147
148 # generate register type and class variable, init function and default requirements
149 foreach my $class_name (keys(%reg_classes)) {
150         my @class         = @{ $reg_classes{"$class_name"} };
151         my $old_classname = $class_name;
152
153         $class_name = $arch."_".$class_name;
154         $class_ptr  = "&".$arch."_reg_classes[CLASS_".$class_name."]";
155         my $flags = pop(@class);
156         $class_mode  = $flags->{"mode"};
157         my $class_flags = $flags->{"flags"};
158         my $flags_prepared = "";
159
160         if(defined($class_flags)) {
161                 my $first = 1;
162                 foreach my $flag (split(/\|/, $class_flags)) {
163                         if(!$first) {
164                                 $flags_prepared .= "|";
165                         } else {
166                                 $first = 0;
167                         }
168                         $flags_prepared .= "arch_register_class_flag_$flag";
169                 }
170         } else {
171                 $flags_prepared = "arch_register_class_flag_none";
172         }
173
174         $single_constraints .= <<EOF;
175 static const arch_register_req_t ${arch}_class_reg_req_${old_classname} = {
176         arch_register_req_type_normal,
177         &${arch}_reg_classes[CLASS_${arch}_${old_classname}],
178         NULL,
179         0,
180         0,
181         1
182 };
183 EOF
184
185         $classdef .= "\tCLASS_$class_name = $class_idx,\n";
186         my $numregs = @class;
187         my $first_reg = "&${arch}_registers[REG_". uc($class[0]->{"name"}) . "]";
188         push(@regclasses, "{ $class_idx, \"$class_name\", $numregs, NULL, $first_reg, $flags_prepared, &${arch}_class_reg_req_${old_classname} }");
189
190         my $idx = 0;
191         $reginit .= "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n";
192         my $lastreg;
193         foreach (@class) {
194                 my $name   = $_->{"name"};
195                 my $ucname = uc($name);
196                 my $type   = "arch_register_type_none";
197                 $type = translate_reg_type($_->{"type"}) if (exists($_->{"type"}));
198                 # realname is name if not set by user
199                 $_->{"realname"} = $_->{"name"} if (! exists($_->{"realname"}));
200                 my $realname = $_->{realname};
201                 my $classuc = uc($old_classname);
202
203                 $regdef  .= "\tREG_${ucname},\n";
204                 $regdef2 .= "\tREG_${classuc}_${ucname} = $idx,\n";
205                 my $dwarf_number = 0;
206                 if (defined($_->{dwarf})) {
207                         $dwarf_number = $_->{dwarf};
208                 }
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                 ${dwarf_number}
219         },
220 EOF
221
222                 my $limitedarray = get_limited_array($name);
223                 $single_constraints .= <<EOF;
224 static const unsigned ${arch}_limited_${old_classname}_${name} [] = ${limitedarray};
225 static const arch_register_req_t ${arch}_single_reg_req_${old_classname}_${name} = {
226         arch_register_req_type_limited,
227         ${class_ptr},
228         ${arch}_limited_${old_classname}_${name},
229         0,
230         0,
231         1
232 };
233 EOF
234
235                 $lastreg = $ucname;
236                 $idx++;
237         }
238         $regcounts .= "\tN_${class_name}_REGS = $numregs,\n";
239
240         $class_idx++;
241 }
242
243 my $archuc = uc($arch);
244
245 $classdef .= "\tN_${archuc}_CLASSES = ".scalar(keys(%reg_classes))."\n";
246 $classdef .= "};\n\n";
247
248 # generate header (external usage) file
249 open(OUT, ">$target_h") || die("Fatal error: Could not open $target_h, reason: $!\n");
250
251 my $creation_time = localtime(time());
252
253 print OUT<<EOF;
254 /**
255  * \@file
256  * \@brief Contains additional external requirements defs for external includes.
257  * \@note   DO NOT EDIT THIS FILE, your changes will be lost.
258  *         Edit $specfile instead.
259  *         created by: $0 $specfile $target_dir
260  * \@date   $creation_time
261  */
262 #ifndef FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
263 #define FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
264
265 #include "bearch.h"
266 #include "${arch}_nodes_attr.h"
267
268 /** global register indices for ${arch} registers */
269 enum reg_indices {
270 ${regdef}
271         N_${archuc}_REGISTERS
272 };
273 /** local register indices for ${arch} registers */
274 enum {
275 ${regdef2}
276 };
277
278 /** number of registers in ${arch} register classes. */
279 enum {
280 ${regcounts}
281 };
282 ${classdef}
283
284 extern const arch_register_t ${arch}_registers[N_${archuc}_REGISTERS];
285
286 extern arch_register_class_t ${arch}_reg_classes[N_${archuc}_CLASSES];
287
288 void ${arch}_register_init(void);
289
290 #endif
291 EOF
292 close(OUT);
293
294
295 # generate c file
296 open(OUT, ">$target_c") || die("Fatal error: Could not open $target_c, reason: $!\n");
297
298 $creation_time = localtime(time());
299
300 print OUT<<EOF;
301 /**
302  * \@file
303  * \@brief  The generated interface for the register allocator.
304  *          Contains register classes and types and register constraints
305  *          for all nodes where constraints were given in spec.
306  * \@note    DO NOT EDIT THIS FILE, your changes will be lost.
307  *          Edit $specfile instead.
308  *          created by: $0 $specfile $target_dir
309  * \$date    $creation_time
310  */
311 #include "config.h"
312
313 #include "gen_${arch}_regalloc_if.h"
314 #include "bearch_${arch}_t.h"
315 #include "irmode.h"
316
317 ${single_constraints}
318 EOF
319
320 print OUT "arch_register_class_t ${arch}_reg_classes[] = {\n\t".join(",\n\t", @regclasses)."\n};\n\n";
321
322 print OUT<<EOF;
323
324 /** The array of all registers in the ${arch} architecture, sorted by its global index.*/
325 const arch_register_t ${arch}_registers[] = {
326 ${regtypes_def}
327 };
328
329 /**
330  * Initializes ${arch} register classes.
331  */
332 void ${arch}_register_init(void)
333 {
334 ${reginit}
335 }
336 EOF
337 close(OUT);