added new licence header
[libfirm] / ir / be / scripts / generate_regalloc_if.pl
index a379169..6043999 100755 (executable)
@@ -1,5 +1,24 @@
 #!/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
@@ -16,6 +35,7 @@ our $arch;
 our %reg_classes;
 our %nodes;
 our %cpu;
+our %flags = ();
 
 # include spec file
 
@@ -23,9 +43,9 @@ my $return;
 
 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";
 
@@ -113,31 +133,47 @@ foreach my $class_name (keys(%reg_classes)) {
        $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");
@@ -145,12 +181,22 @@ foreach my $class_name (keys(%reg_classes)) {
        $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"}));
 
@@ -574,7 +620,7 @@ CHECK_REQS: foreach (@regs) {
        }
 
        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);