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
31 my $specfile = $ARGV[0];
32 my $target_dir = $ARGV[1];
43 unless ($return = do $specfile) {
44 die "Fatal error: couldn't parse $specfile: $@" if $@;
45 die "Fatal error: couldn't do $specfile: $!" unless defined $return;
46 die "Fatal error: couldn't run $specfile" unless $return;
50 my $target_c = $target_dir."/gen_".$arch."_regalloc_if.c";
51 my $target_h = $target_dir."/gen_".$arch."_regalloc_if.h";
54 sub translate_reg_type {
58 return "arch_register_type_none";
64 push(@types, "arch_register_type_caller_save");
68 push(@types, "arch_register_type_callee_save");
72 push(@types, "arch_register_type_ignore");
76 push(@types, "arch_register_type_joker");
80 push(@types, "arch_register_type_virtual");
84 push(@types, "arch_register_type_state");
87 return join(" | ", @types);
92 my $regtypes_def; # stack for the register type variables definitions
93 my $regtypes_decl;# stack for the register type variables declarations
94 my @regclasses; # stack for the register class variables
95 my $classdef; # stack to define a name for a class index
96 my $regdef; # stack to define a name for a register index
97 my $reginit; # stack for the register type inits
98 my $single_constraints_decls;
99 my $single_constraints;
107 my %regclass2len = ();
110 $classdef .= "enum reg_classes {\n";
114 foreach my $class_name (keys(%reg_classes)) {
115 my @class = @{ $reg_classes{"$class_name"} };
119 if (defined($_->{name})) {
120 $reg2class{$_->{name}} = {
121 "class" => $class_name,
127 $regclass2len{$class_name} = $idx;
130 sub get_limited_array {
132 my $regclass = $reg2class{"$reg"}{"class"};
133 my $ucname = uc($reg);
136 my $limitedbitsetlen = $regclass2len{$regclass};
137 my $arraylen = ($limitedbitsetlen+31) / 32;
139 for (my $i = 0; $i < $arraylen; ++$i) {
146 my $index = $reg2class{"$reg"}{"index"};
147 if ($index >= $i*32 && $index < ($i+1)*32) {
149 $result .= "(1 << (REG_${ucname} % 32))";
151 $result .= "(1 << REG_${ucname})";
160 # generate register type and class variable, init function and default requirements
161 foreach my $class_name (keys(%reg_classes)) {
162 my @class = @{ $reg_classes{"$class_name"} };
163 my $old_classname = $class_name;
165 $class_name = $arch."_".$class_name;
166 $numregs = "N_".$class_name."_REGS";
167 $class_ptr = "&".$arch."_reg_classes[CLASS_".$class_name."]";
168 my $flags = pop(@class);
169 $class_mode = $flags->{"mode"};
170 my $class_flags = $flags->{"flags"};
171 my $flags_prepared = "";
173 if(defined($class_flags)) {
175 foreach my $flag (split(/\|/, $class_flags)) {
177 $flags_prepared .= "|";
181 $flags_prepared .= "arch_register_class_flag_$flag";
184 $flags_prepared = "0";
187 $single_constraints_decls .= <<EOF;
188 static const arch_register_req_t ${arch}_class_reg_req_${old_classname};
191 $single_constraints .= <<EOF;
192 static const arch_register_req_t ${arch}_class_reg_req_${old_classname} = {
193 arch_register_req_type_normal,
194 &${arch}_reg_classes[CLASS_${arch}_${old_classname}],
202 $regtypes_decl .= "extern const arch_register_t ${class_name}_regs[$numregs];\n";
204 $classdef .= "\tCLASS_$class_name = $class_idx,\n";
205 push(@regclasses, "{ $class_idx, \"$class_name\", $numregs, NULL, ".$class_name."_regs, $flags_prepared, &${arch}_class_reg_req_${old_classname} }");
208 $reginit .= "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n";
209 $regtypes_def .= "const arch_register_t ${class_name}_regs[$numregs] = {\n";
211 $regdef .= "enum reg_${class_name}_indices {\n";
213 my $name = $_->{"name"};
214 my $ucname = uc($name);
215 my $type = translate_reg_type($_->{"type"});
216 # realname is name if not set by user
217 $_->{"realname"} = $_->{"name"} if (! exists($_->{"realname"}));
218 my $realname = $_->{realname};
220 $regdef .= "\tREG_${ucname},\n";
222 $regtypes_def .= <<EOF;
228 &${arch}_single_reg_req_${old_classname}_${name}
232 my $limitedarray = get_limited_array($name);
233 $single_constraints .= <<EOF;
234 static const unsigned ${arch}_limited_${old_classname}_${name} [] = ${limitedarray};
235 static const arch_register_req_t ${arch}_single_reg_req_${old_classname}_${name} = {
236 arch_register_req_type_limited,
238 ${arch}_limited_${old_classname}_${name},
247 $regtypes_def .= "};\n";
249 $regdef .= "\t$numregs = $idx\n";
255 $classdef .= "\tN_CLASSES = ".scalar(keys(%reg_classes))."\n";
256 $classdef .= "};\n\n";
260 # generate header (external usage) file
261 open(OUT, ">$target_h") || die("Fatal error: Could not open $target_h, reason: $!\n");
263 my $creation_time = localtime(time());
268 * \@brief Contains additional external requirements defs for external includes.
269 * \@note DO NOT EDIT THIS FILE, your changes will be lost.
270 * Edit $specfile instead.
271 * created by: $0 $specfile $target_dir
272 * \@date $creation_time
274 #ifndef FIRM_BE_${tmp}_GEN_${tmp}_REGALLOC_IF_H
275 #define FIRM_BE_${tmp}_GEN_${tmp}_REGALLOC_IF_H
277 #include "../bearch.h"
278 #include "${arch}_nodes_attr.h"
284 extern arch_register_class_t ${arch}_reg_classes[N_CLASSES];
286 void ${arch}_register_init(void);
287 unsigned ${arch}_get_n_regs(void);
295 open(OUT, ">$target_c") || die("Fatal error: Could not open $target_c, reason: $!\n");
297 $creation_time = localtime(time());
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
312 #include "gen_${arch}_regalloc_if.h"
313 #include "gen_${arch}_machine.h"
314 #include "bearch_${arch}_t.h"
317 ${single_constraints_decls}
320 print OUT "arch_register_class_t ${arch}_reg_classes[] = {\n\t".join(",\n\t", @regclasses)."\n};\n\n";
323 ${single_constraints}
326 void ${arch}_register_init(void)
334 # Gets the variable name for the execution unit assigned to this register.
336 sub get_execunit_variable_name {
339 my $uc_arch = uc($arch);
343 SRCH: foreach my $cur_type (keys(%cpu)) {
344 foreach my $cur_unit (@{ $cpu{"$cur_type"} }) {
345 if ($unit eq $cur_unit) {
346 my $tp_name = "$arch\_execution_units_$cur_type";
347 my $unit_name = "$uc_arch\_EXECUNIT_TP_$cur_type\_$unit";
348 $name = "&".$tp_name."[".$unit_name."]";
356 print STDERR "Invalid execution unit $unit specified!\n";