4 # Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
6 # This file is part of libFirm.
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.
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.
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
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
30 my $specfile = $ARGV[0];
31 my $target_dir = $ARGV[1];
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;
49 my $target_c = $target_dir."/gen_".$arch."_regalloc_if.c";
50 my $target_h = $target_dir."/gen_".$arch."_regalloc_if.h";
53 sub translate_reg_type {
57 return "arch_register_type_none";
63 push(@types, "arch_register_type_ignore");
67 push(@types, "arch_register_type_joker");
71 push(@types, "arch_register_type_virtual");
75 push(@types, "arch_register_type_state");
78 return join(" | ", @types);
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
90 my $reginit; # stack for the register type inits
91 my $single_constraints_decls;
92 my $single_constraints;
97 my %regclass2len = ();
100 $classdef .= "enum reg_classes {\n";
104 foreach my $class_name (keys(%reg_classes)) {
105 my @class = @{ $reg_classes{"$class_name"} };
109 if (defined($_->{name})) {
110 $reg2class{$_->{name}} = {
111 "class" => $class_name,
117 $regclass2len{$class_name} = $idx;
120 sub get_limited_array {
122 my $regclass = $reg2class{"$reg"}{"class"};
123 my $ucname = uc($reg);
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);
131 for (my $i = 0; $i < $arraylen; ++$i) {
138 my $index = $reg2class{"$reg"}{"index"};
139 if ($index >= $i*32 && $index < ($i+1)*32) {
141 $result .= "(1 << (REG_${classuc}_${ucname} % 32))";
143 $result .= "(1 << REG_${classuc}_${ucname})";
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;
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 = "";
164 if(defined($class_flags)) {
166 foreach my $flag (split(/\|/, $class_flags)) {
168 $flags_prepared .= "|";
172 $flags_prepared .= "arch_register_class_flag_$flag";
175 $flags_prepared = "arch_register_class_flag_none";
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}],
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} }");
195 $reginit .= "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n";
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);
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};
214 $regtypes_def .= <<EOF;
218 REG_${classuc}_${ucname},
221 &${arch}_single_reg_req_${old_classname}_${name},
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,
232 ${arch}_limited_${old_classname}_${name},
242 $regcounts .= "\tN_${class_name}_REGS = $numregs,\n";
247 my $archuc = uc($arch);
249 $classdef .= "\tN_${archuc}_CLASSES = ".scalar(keys(%reg_classes))."\n";
250 $classdef .= "};\n\n";
252 # generate header (external usage) file
253 open(OUT, ">$target_h") || die("Fatal error: Could not open $target_h, reason: $!\n");
255 my $creation_time = localtime(time());
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
266 #ifndef FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
267 #define FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
270 #include "${arch}_nodes_attr.h"
272 /** global register indices for ${arch} registers */
275 N_${archuc}_REGISTERS
277 /** local register indices for ${arch} registers */
282 /** number of registers in ${arch} register classes. */
288 extern const arch_register_t ${arch}_registers[N_${archuc}_REGISTERS];
290 extern arch_register_class_t ${arch}_reg_classes[N_${archuc}_CLASSES];
292 void ${arch}_register_init(void);
300 open(OUT, ">$target_c") || die("Fatal error: Could not open $target_c, reason: $!\n");
302 $creation_time = localtime(time());
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
317 #include "gen_${arch}_regalloc_if.h"
318 #include "bearch_${arch}_t.h"
321 ${single_constraints}
324 print OUT "arch_register_class_t ${arch}_reg_classes[] = {\n\t".join(",\n\t", @regclasses)."\n};\n\n";
328 /** The array of all registers in the ${arch} architecture, sorted by its global index.*/
329 const arch_register_t ${arch}_registers[] = {
334 * Initializes ${arch} register classes.
336 void ${arch}_register_init(void)