#!/usr/bin/perl -w
+#
+# Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
+#
+# This file is part of libFirm.
+#
+# This file may be distributed and/or modified under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation and appearing in the file LICENSE.GPL included in the
+# packaging of this file.
+#
+# Licensees holding valid libFirm Professional Edition licenses may use
+# this file in accordance with the libFirm Commercial License.
+# Agreement provided with the Software.
+#
+# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE.
+#
+
# This script generates C code which creates ands sets up functions and
# data structures for the register allocator.
# Creation: 2005/11/14
our %reg_classes;
our %nodes;
our %cpu;
+our %flags = ();
# include spec file
use strict "subs";
unless ($return = do $specfile) {
- warn "couldn't parse $specfile: $@" if $@;
- warn "couldn't do $specfile: $!" unless defined $return;
- warn "couldn't run $specfile" unless $return;
+ die "couldn't parse $specfile: $@" if $@;
+ die "couldn't do $specfile: $!" unless defined $return;
+ die "couldn't run $specfile" unless $return;
}
use strict "subs";
$class_ptr = "&".$arch."_reg_classes[CLASS_".$class_name."]";
$class_mode = pop(@class)->{"mode"};
- push(@obst_regtypes_decl, "extern arch_register_t ".$class_name."_regs[$numregs];\n");
- push(@obst_regtypes_def, "arch_register_t ".$class_name."_regs[$numregs];\n");
+ push(@obst_regtypes_decl, "extern const arch_register_t ${class_name}_regs[$numregs];\n");
push(@obst_classdef, "\tCLASS_$class_name = $class_idx,\n");
push(@obst_regclasses, "{ \"$class_name\", $numregs, NULL, ".$class_name."_regs }");
my $idx = 0;
- push(@obst_reginit, "\t/* Init of all registers in class '$class_name' */\n\n");
push(@obst_reginit, "\t/* set largest possible mode for '$class_name' */\n");
push(@obst_reginit, "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n\n");
- push(@obst_regdef, "enum reg_".$class_name."_values {\n");
+ push(@obst_regtypes_def, "const arch_register_t ${class_name}_regs[$numregs] = {\n");
+
+ push(@obst_regdef, "enum reg_${class_name}_indices {\n");
foreach (@class) {
+ my $ucname = uc($_->{"name"});
+ my $type = translate_reg_type($_->{"type"});
# realname is name if not set by user
$_->{"realname"} = $_->{"name"} if (! exists($_->{"realname"}));
+ my $realname = $_->{realname};
+ my $execunitvarname = get_execunit_variable_name($_->{"unit"});
+
$reg2class{$_->{"name"}} = { "class" => $old_classname, "index" => $idx }; # remember reg to class for later use
- push(@obst_regdef, "\tREG_".uc($_->{"name"})." = $idx,\n");
- push(@obst_reginit, "\t${class_name}_regs[$idx].name = \"".$_->{"realname"}."\";\n");
- push(@obst_reginit, "\t${class_name}_regs[$idx].reg_class = $class_ptr;\n");
- push(@obst_reginit, "\t${class_name}_regs[$idx].index = $idx;\n");
- push(@obst_reginit, "\t${class_name}_regs[$idx].type = ".translate_reg_type($_->{"type"}).";\n");
- push(@obst_reginit, "\t${class_name}_regs[$idx].data = ".get_execunit_variable_name($_->{"unit"}).";\n");
- push(@obst_reginit, "\n");
+ push(@obst_regdef, "\tREG_${ucname},\n");
+
+ push(@obst_regtypes_def, "\t{\n");
+ push(@obst_regtypes_def, "\t\t\"$realname\",\n");
+ push(@obst_regtypes_def, "\t\t$class_ptr,\n");
+ push(@obst_regtypes_def, "\t\tREG_${ucname},\n");
+ push(@obst_regtypes_def, "\t\t$type,\n");
+ push(@obst_regtypes_def, "\t\t$execunitvarname\n");
+ push(@obst_regtypes_def, "\t},\n");
+
+# push(@obst_reginit, "\t${class_name}_regs[$idx].name = \"".$_->{"realname"}."\";\n");
+# push(@obst_reginit, "\t${class_name}_regs[$idx].reg_class = $class_ptr;\n");
+# push(@obst_reginit, "\t${class_name}_regs[$idx].index = $idx;\n");
+# push(@obst_reginit, "\t${class_name}_regs[$idx].type = ".translate_reg_type($_->{"type"}).";\n");
+# push(@obst_reginit, "\t${class_name}_regs[$idx].data = ".get_execunit_variable_name($_->{"unit"}).";\n");
+# push(@obst_reginit, "\n");
$idx++;
}
+ push(@obst_regtypes_def, "};\n");
+
$regclass2len{$old_classname} = $idx;
push(@obst_regdef, "\t$numregs = $idx\n");
push(@obst_regdef, "};\n\n");
$class_idx++;
}
+push(@obst_regdef, "enum flag_indices {\n");
+foreach my $flag (keys(%flags)) {
+ my %f = %{ $flags{$flag} };
+
+ push(@obst_regdef, "\tFLAG_$flag,\n");
+}
+push(@obst_regdef, "\tFLAG_LAST\n");
+push(@obst_regdef, "};\n");
+push(@obst_regtypes_decl, "extern arch_flag_t ${arch}_flags[];\n");
+
push(@obst_classdef, "\tN_CLASSES = ".scalar(keys(%reg_classes))."\n");
push(@obst_classdef, "};\n\n");
# generate node-register constraints
foreach my $op (keys(%nodes)) {
- my %n = %{ $nodes{"$op"} };
+ my %n = %{ $nodes{$op} };
next if (!exists($n{"reg_req"}));
}
if ($has_limit == 1) {
- push(@obst_limit_func, "static const unsigned limit_reg_${op}_".($in ? "in" : "out")."_${idx}[] = { ");
+ push(@obst_limit_func, "static const unsigned limit_reg_${op}_".($in ? "in" : "out")."_". ${idx} ."[] = { ");
my $first = 1;
my $limitbitsetlen = $regclass2len{$class};
my $limitarraylen = $limitbitsetlen / 32 + ($limitbitsetlen % 32 > 0 ? 1 : 0);