ia32: cleanup handling of 8/16bit operations
[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                 my $dwarf_number = 0;
210                 if (defined($_->{dwarf})) {
211                         $dwarf_number = $_->{dwarf};
212                 }
213
214                 $regtypes_def .= <<EOF;
215         {
216                 "${realname}",
217                 ${class_ptr},
218                 REG_${classuc}_${ucname},
219                 REG_${ucname},
220                 ${type},
221                 &${arch}_single_reg_req_${old_classname}_${name},
222                 ${dwarf_number}
223         },
224 EOF
225
226                 my $limitedarray = get_limited_array($name);
227                 $single_constraints .= <<EOF;
228 static const unsigned ${arch}_limited_${old_classname}_${name} [] = ${limitedarray};
229 static const arch_register_req_t ${arch}_single_reg_req_${old_classname}_${name} = {
230         arch_register_req_type_limited,
231         ${class_ptr},
232         ${arch}_limited_${old_classname}_${name},
233         0,
234         0,
235         1
236 };
237 EOF
238
239                 $lastreg = $ucname;
240                 $idx++;
241         }
242         $regcounts .= "\tN_${class_name}_REGS = $numregs,\n";
243
244         $class_idx++;
245 }
246
247 my $archuc = uc($arch);
248
249 $classdef .= "\tN_${archuc}_CLASSES = ".scalar(keys(%reg_classes))."\n";
250 $classdef .= "};\n\n";
251
252 # generate header (external usage) file
253 open(OUT, ">$target_h") || die("Fatal error: Could not open $target_h, reason: $!\n");
254
255 my $creation_time = localtime(time());
256
257 print OUT<<EOF;
258 /**
259  * \@file
260  * \@brief Contains additional external requirements defs for external includes.
261  * \@note   DO NOT EDIT THIS FILE, your changes will be lost.
262  *         Edit $specfile instead.
263  *         created by: $0 $specfile $target_dir
264  * \@date   $creation_time
265  */
266 #ifndef FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
267 #define FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
268
269 #include "bearch.h"
270 #include "${arch}_nodes_attr.h"
271
272 /** global register indices for ${arch} registers */
273 enum reg_indices {
274 ${regdef}
275         N_${archuc}_REGISTERS
276 };
277 /** local register indices for ${arch} registers */
278 enum {
279 ${regdef2}
280 };
281
282 /** number of registers in ${arch} register classes. */
283 enum {
284 ${regcounts}
285 };
286 ${classdef}
287
288 extern const arch_register_t ${arch}_registers[N_${archuc}_REGISTERS];
289
290 extern arch_register_class_t ${arch}_reg_classes[N_${archuc}_CLASSES];
291
292 void ${arch}_register_init(void);
293
294 #endif
295 EOF
296 close(OUT);
297
298
299 # generate c file
300 open(OUT, ">$target_c") || die("Fatal error: Could not open $target_c, reason: $!\n");
301
302 $creation_time = localtime(time());
303
304 print OUT<<EOF;
305 /**
306  * \@file
307  * \@brief  The generated interface for the register allocator.
308  *          Contains register classes and types and register constraints
309  *          for all nodes where constraints were given in spec.
310  * \@note    DO NOT EDIT THIS FILE, your changes will be lost.
311  *          Edit $specfile instead.
312  *          created by: $0 $specfile $target_dir
313  * \$date    $creation_time
314  */
315 #include "config.h"
316
317 #include "gen_${arch}_regalloc_if.h"
318 #include "bearch_${arch}_t.h"
319 #include "irmode.h"
320
321 ${single_constraints}
322 EOF
323
324 print OUT "arch_register_class_t ${arch}_reg_classes[] = {\n\t".join(",\n\t", @regclasses)."\n};\n\n";
325
326 print OUT<<EOF;
327
328 /** The array of all registers in the ${arch} architecture, sorted by its global index.*/
329 const arch_register_t ${arch}_registers[] = {
330 ${regtypes_def}
331 };
332
333 /**
334  * Initializes ${arch} register classes.
335  */
336 void ${arch}_register_init(void)
337 {
338 ${reginit}
339 }
340 EOF
341 close(OUT);