adapt generators to new header style
[libfirm] / ir / be / scripts / generate_new_opcodes.pl
index 11e271d..4faf79b 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 the C code which creates the irop's and
 # their coresponding node constructors for all operations in a given spec
 # so they can be used as normal firm nodes.
@@ -27,9 +46,9 @@ my $return;
 
 no 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";
 
@@ -61,6 +80,20 @@ $n_opcodes += $additional_opcodes if (defined($additional_opcodes));
 
 push(@obst_header, "void ".$arch."_create_opcodes(void);\n");
 
+# create default compare function
+if(defined($default_cmp_attr)) {
+       my $cmpcode = $default_cmp_attr;
+       push(@obst_cmp_attr, "static int default_cmp_attr(ir_node *a, ir_node *b) {\n");
+       if($cmpcode =~ m/attr_a/) {
+               push(@obst_cmp_attr, "\t$arch\_attr_t *attr_a = get_$arch\_attr(a);\n");
+       }
+       if($cmpcode =~ m/attr_b/) {
+               push(@obst_cmp_attr, "\t$arch\_attr_t *attr_b = get_$arch\_attr(b);\n");
+       }
+       push(@obst_cmp_attr, "\t${cmpcode}\n");
+       push(@obst_cmp_attr, "}\n\n");
+}
+
 push(@obst_enum_op, "typedef enum _$arch\_opcodes {\n");
 foreach my $op (keys(%nodes)) {
        my %n        = %{ $nodes{"$op"} };
@@ -90,9 +123,9 @@ foreach my $op (keys(%nodes)) {
 
                for (my $idx = 0; $idx <= $#outs; $idx++) {
                        # check, if we have additional flags annotated to out
-                       if ($outs[$idx] =~ /:(S|I(\|(S|I))*)/) {
+                       if ($outs[$idx] =~ /:((S|I)(\|(S|I))*)/) {
                                push(@out_flags, $1);
-                               $outs[$idx] =~ s/:(S|I(\|(S|I))*)//;
+                               $outs[$idx] =~ s/:((S|I)(\|(S|I))*)//;
                        }
                        push(@obst_proj, "  pn_$op\_".$outs[$idx]." = $idx,\n");
                }
@@ -114,22 +147,25 @@ foreach my $op (keys(%nodes)) {
        push(@obst_header, "ir_op *get_op_$op(void);\n");
        push(@obst_header, "int is_$op(const ir_node *n);\n");
 
-       $cmp_attr_func = 0;
+       my $cmp_attr_func;
+       if(defined($default_cmp_attr)) {
+               $cmp_attr_func = "default_cmp_attr";
+       }
        # create compare attribute function if needed
-       if (exists($n{"cmp_attr"}) || defined($default_cmp_attr)) {
+       if (exists($n{"cmp_attr"})) {
+               my $cmpcode = $n{"cmp_attr"};
+
                push(@obst_cmp_attr, "static int cmp_attr_$op(ir_node *a, ir_node *b) {\n");
-               push(@obst_cmp_attr, "\t$arch\_attr_t *attr_a = get_$arch\_attr(a);\n");
-               push(@obst_cmp_attr, "\t$arch\_attr_t *attr_b = get_$arch\_attr(b);\n");
-               push(@obst_cmp_attr, "\t(void) attr_a;\n");
-               push(@obst_cmp_attr, "\t(void) attr_b;\n");
-               if(exists($n{"cmp_attr"})) {
-                       push(@obst_cmp_attr, "\t".$n{"cmp_attr"}."\n");
-               } else {
-                       push(@obst_cmp_attr, "\t$default_cmp_attr\n");
+               if($cmpcode =~ m/attr_a/) {
+                       push(@obst_cmp_attr, "\t$arch\_attr_t *attr_a = get_$arch\_attr(a);\n");
+               }
+               if($cmpcode =~ m/attr_b/) {
+                       push(@obst_cmp_attr, "\t$arch\_attr_t *attr_b = get_$arch\_attr(b);\n");
                }
+               push(@obst_cmp_attr, "\t${cmpcode}\n");
                push(@obst_cmp_attr, "}\n\n");
 
-               $cmp_attr_func = 1;
+               $cmp_attr_func = "cmp_attr_${op}";
        }
 
        if (exists($n{"rd_constructor"}) && $n{"rd_constructor"} =~ /^NONE$/i) {
@@ -214,10 +250,10 @@ foreach my $op (keys(%nodes)) {
 
                                if (@in) {
                                        $in_req_var = "_in_req_$op";
-                                       $temp .= "\tstatic const $arch\_register_req_t *".$in_req_var."[] =\n";
+                                       $temp .= "\tstatic const arch_register_req_t *".$in_req_var."[] =\n";
                                        $temp .= "\t{\n";
                                        for ($idx = 0; $idx <= $#in; $idx++) {
-                                               $temp .= "\t\t".$op."_reg_req_in_".$idx.",\n";
+                                               $temp .= "\t\t&".$op."_reg_req_in_".$idx.",\n";
                                        }
                                        $temp .= "\t};\n";
                                }
@@ -225,20 +261,18 @@ foreach my $op (keys(%nodes)) {
                                if (@out) {
                                        $out_req_var = "_out_req_$op";
 
-                                       $temp .= "\tstatic const $arch\_register_req_t *".$out_req_var."[] =\n";
+                                       $temp .= "\tstatic const arch_register_req_t *".$out_req_var."[] =\n";
                                        $temp .= "\t{\n";
                                        for ($idx = 0; $idx <= $#out; $idx++) {
-                                               $temp .= "\t\t".$op."_reg_req_out_".$idx.",\n";
+                                               $temp .= "\t\t&".$op."_reg_req_out_".$idx.",\n";
                                        }
                                        $temp .= "\t};\n";
                                }
                        }
 
                        $temp .= "\n";
-                       $temp .= "\tif (!op_$op) {\n";
-                       $temp .= "\t\tassert(0);\n";
-                       $temp .= "\t\treturn NULL;\n";
-                       $temp .= "\t}\n\n";
+                       $temp .= "\tassert(op_$op != NULL);\n\n";
+
                        for (my $i = 1; $i <= $arity; $i++) {
                                $temp .= "\tin[".($i - 1)."] = op".$i.";\n";
                        }
@@ -359,8 +393,8 @@ foreach my $op (keys(%nodes)) {
        push(@obst_new_irop, "\n\tmemset(&ops, 0, sizeof(ops));\n");
        push(@obst_new_irop, "\tops.dump_node     = $arch\_dump_node;\n");
 
-       if ($cmp_attr_func) {
-               push(@obst_new_irop, "\tops.node_cmp_attr = cmp_attr_$op;\n");
+       if (defined($cmp_attr_func)) {
+               push(@obst_new_irop, "\tops.node_cmp_attr = ${cmp_attr_func};\n");
        }
 
        $n_opcodes++;
@@ -465,8 +499,15 @@ void $arch\_create_opcodes(void) {
 #define O   irop_flag_machine_op
 #define R   (irop_flag_user << 0)
 
-       ir_op_ops ops;
-       int cur_opcode = get_next_ir_opcodes(iro_$arch\_last);
+       ir_op_ops  ops;
+       int        cur_opcode;
+       static int run_once = 0;
+
+       if (run_once)
+               return;
+       run_once = 1;
+
+       cur_opcode = get_next_ir_opcodes(iro_$arch\_last);
 
        $arch\_opcode_start = cur_opcode;
 ENDOFMAIN
@@ -483,8 +524,23 @@ close(OUT);
 
 open(OUT, ">$target_h") || die("Could not open $target_h, reason: $!\n");
 
-print OUT "#ifndef __GEN_$arch\_NEW_NODES_H__\n";
-print OUT "#define __GEN_$arch\_NEW_NODES_H__\n\n";
+my $creation_time = localtime(time());
+my $tmp = uc($arch);
+
+print OUT<<EOF;
+/**
+ * \@file
+ * \@brief Function prototypes for the new opcode functions.
+ * \@note  DO NOT EDIT THIS FILE, your changes will be lost.
+ *        Edit $specfile instead.
+ *        created by: $0 $specfile $target_dir
+ * \@date  $creation_time
+ */
+#ifndef FIRM_BE_${tmp}_GEN_${tmp}_NEW_NODES_H
+#define FIRM_BE_${tmp}_GEN_${tmp}_NEW_NODES_H
+
+EOF
+
 print OUT @obst_enum_op;
 print OUT "int is_$arch\_irn(const ir_node *node);\n\n";
 print OUT "int get_$arch\_opcode_first(void);\n";
@@ -492,7 +548,10 @@ print OUT "int get_$arch\_opcode_last(void);\n";
 print OUT "int get_$arch\_irn_opcode(const ir_node *node);\n";
 print OUT @obst_header;
 print OUT @obst_proj;
-print OUT "\n#endif /* __GEN_$arch\_NEW_NODES_H__ */\n";
+
+print OUT <<EOF;
+#endif
+EOF
 
 close(OUT);
 
@@ -516,7 +575,7 @@ sub translate_arity {
                        return "oparity_trinary";
                }
                else {
-                       return "$arity";
+                       return "oparity_any";
                }
        }
        else {