replaced inline by __inline to allow to be compiled in gcc and msvc modes
[libfirm] / ir / be / scripts / generate_regalloc_if.pl
index a379169..6462a8c 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";
 
@@ -96,13 +116,6 @@ push(@obst_classdef, "enum reg_classes {\n");
 
 my $class_mode;
 
-# assure, the initialization is done only once
-push(@obst_reginit, "\tstatic int run_once = 0;\n");
-push(@obst_reginit, "\n");
-push(@obst_reginit, "\tif (run_once)\n");
-push(@obst_reginit, "\t\treturn;\n");
-push(@obst_reginit, "\trun_once = 1;\n");
-
 # generate register type and class variable, init function and default requirements
 foreach my $class_name (keys(%reg_classes)) {
        my @class         = @{ $reg_classes{"$class_name"} };
@@ -113,31 +126,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 +174,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"}));
 
@@ -180,15 +219,15 @@ $tmp = uc($arch);
 
 print OUT<<EOF;
 /**
- * Generated register classes from spec.
- *
- * DO NOT EDIT THIS FILE, your changes will be lost.
- * Edit $specfile instead.
- * created by: $0 $specfile $target_dir
- * date:       $creation_time
+ * \@file
+ * \@brief    Generated register classes from spec.
+ * \@note     DO NOT EDIT THIS FILE, your changes will be lost.
+ *           Edit $specfile instead.
+ *           created by: $0 $specfile $target_dir
+ * \$date     $creation_time
  */
-#ifndef _GEN_${tmp}_REGALLOC_IF_T_H_
-#define _GEN_${tmp}_REGALLOC_IF_T_H_
+#ifndef FIRM_BE_${tmp}_GEN_${tmp}_REGALLOC_IF_T_H
+#define FIRM_BE_${tmp}_GEN_${tmp}_REGALLOC_IF_T_H
 
 #include "gen_${arch}_regalloc_if.h"
 
@@ -196,8 +235,7 @@ EOF
 
 print OUT @obst_header_t;
 
-print OUT "\n#endif /* _GEN_$tmp\_REGALLOC_IF_T_H_ */\n";
-
+print OUT "\n#endif\n";
 
 
 # generate header (external usage) file
@@ -207,15 +245,15 @@ $creation_time = localtime(time());
 
 print OUT<<EOF;
 /**
- * Contains additional external requirements defs for external includes.
- *
- * DO NOT EDIT THIS FILE, your changes will be lost.
- * Edit $specfile instead.
- * created by: $0 $specfile $target_dir
- * date:       $creation_time
+ * \@file
+ * \@brief Contains additional external requirements defs for external includes.
+ * \@note   DO NOT EDIT THIS FILE, your changes will be lost.
+ *         Edit $specfile instead.
+ *         created by: $0 $specfile $target_dir
+ * \@date   $creation_time
  */
-#ifndef _GEN_${tmp}_REGALLOC_IF_H_
-#define _GEN_${tmp}_REGALLOC_IF_H_
+#ifndef FIRM_BE_${tmp}_GEN_${tmp}_REGALLOC_IF_H
+#define FIRM_BE_${tmp}_GEN_${tmp}_REGALLOC_IF_H
 
 #include "../bearch.h"
 #include "${arch}_nodes_attr.h"
@@ -234,7 +272,7 @@ print OUT "void ".$arch."_register_init(void *isa_ptr);\n\n";
 
 print OUT @obst_header_all, "\n";
 
-print OUT "\n#endif /* _GEN_$tmp\_REGALLOC_IF_H_ */\n";
+print OUT "\n#endif\n";
 
 close(OUT);
 
@@ -247,14 +285,14 @@ $creation_time = localtime(time());
 
 print OUT<<EOF;
 /**
- * The generated interface for the register allocator.
- * Contains register classes and types and register constraints
- * for all nodes where constraints were given in spec.
- *
- * DO NOT EDIT THIS FILE, your changes will be lost.
- * Edit $specfile instead.
- * created by: $0 $specfile $target_dir
- * date:       $creation_time
+ * \@file
+ * \@brief  The generated interface for the register allocator.
+ *          Contains register classes and types and register constraints
+ *          for all nodes where constraints were given in spec.
+ * \@note    DO NOT EDIT THIS FILE, your changes will be lost.
+ *          Edit $specfile instead.
+ *          created by: $0 $specfile $target_dir
+ * \$date    $creation_time
  */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -574,7 +612,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);