Fixed some warning about unused variables.
[libfirm] / ir / be / scripts / generate_new_opcodes.pl
index 6486086..88b1d51 100755 (executable)
@@ -48,6 +48,7 @@ our $custom_init_attr_func;
 our %compare_attr;
 our %copy_attr;
 our %reg_classes;
+our %custom_irn_flags;
 
 # include spec file
 
@@ -206,7 +207,9 @@ sub create_constructor {
        } elsif($out_arity eq "dynamic") {
                $out_arity = $ARITY_DYNAMIC;
        }
-
+       if ($out_arity != 0 && $out_arity != 1 && !defined($known_mode)) {
+               $known_mode = "mode_T";
+       }
 
        my $comment = $n->{"comment"};
        if(!exists($n->{"comment"})) {
@@ -267,10 +270,11 @@ sub create_constructor {
 
        # emit constructor code
        $temp = <<EOF;
-       ir_node        *res;
-       ir_op          *op      = op_${arch}_${op};
-       int             flags   = 0;
-       backend_info_t *info;
+       ir_graph         *irg     = get_irn_irg(block);
+       ir_op            *op      = op_${arch}_${op};
+       arch_irn_flags_t  flags   = arch_irn_flags_none;
+       ir_node          *res;
+       backend_info_t   *info;
 EOF
 
        if($arity == $ARITY_DYNAMIC) {
@@ -372,7 +376,7 @@ EOF
                                my $req = $out[$idx];
                                my $reqstruct = generate_requirements($req, $n, "${arch}_${op}", $idx, 0);
                                $set_out_reqs .= <<EOF;
-info->out_infos[${idx}].req = &${reqstruct};
+       info->out_infos[${idx}].req = &${reqstruct};
 EOF
                        }
                } else {
@@ -407,23 +411,34 @@ EOF
        # set flags
        if (exists($n->{"irn_flags"})) {
                $temp .= "\t/* flags */\n";
-               my %known_irn_flags = map { $_ => 1 } (
-                       "none", "dont_spill", "rematerializable",
-                       "modify_flags", "simple_jump"
+               my %known_irn_flags = (
+                       "none"             => "arch_irn_flags_none",
+                       "dont_spill"       => "arch_irn_flags_dont_spill",
+                       "rematerializable" => "arch_irn_flags_rematerializable",
+                       "modify_flags"     => "arch_irn_flags_modify_flags",
+                       "simple_jump"      => "arch_irn_flags_simple_jump",
+                       "not_scheduled"    => "arch_irn_flags_not_scheduled",
                );
+               if (defined(%custom_irn_flags)) {
+                       %known_irn_flags = (%known_irn_flags, %custom_irn_flags);
+               }
                foreach my $flag (@{$n->{"irn_flags"}}) {
                        if (not defined($known_irn_flags{$flag})) {
                                print STDERR "WARNING: irn_flag '$flag' in opcode $op is unknown\n";
+                       } else {
+                               $temp .= "\tflags |= " . $known_irn_flags{$flag} . ";\n";
                        }
-                       $temp .= "\tflags |= arch_irn_flags_$flag;\n";
                }
                $temp .= "\n";
        }
 
        # lookup init function
-       my $attr_init_code = $init_attr{$attr_type};
-       if(!defined($attr_init_code)) {
-               die "Fatal error: Couldn't find attribute initialisation code for type '${attr_type}'";
+       my $attr_init_code = "(void)in;(void)exec_units;(void)flags;(void)in_reqs;(void)n_res;";
+       if ($attr_type ne "") {
+               $attr_init_code = $init_attr{$attr_type};
+               if(!defined($attr_init_code)) {
+                       die "Fatal error: Couldn't find attribute initialisation code for type '${attr_type}'";
+               }
        }
        my $custominit = "";
        if(defined($custom_init_attr_func)) {
@@ -436,26 +451,27 @@ EOF
        $temp .= <<EOF;
        /* create node */
        assert(op != NULL);
-       res = new_ir_node(dbgi, current_ir_graph, block, op, mode, arity, in);
+       res = new_ir_node(dbgi, irg, block, op, mode, arity, in);
 
        /* init node attributes */
        ${attr_init_code}
        ${custominit}
        info = be_get_info(res);
        (void) info; /* avoid potential warning */
-       ${set_out_reqs}
+${set_out_reqs}
 
 EOF
 
        if (exists($n->{"init_attr"})) {
-               $temp .= "\tattr = get_irn_generic_attr(res);\n";
+               $temp .= "\tattr = (${attr_type}*)get_irn_generic_attr(res);\n";
+               $temp .= "\t(void) attr; /* avoid potential warning */\n";
                $temp .= "\t".$n->{"init_attr"}."\n";
        }
 
        $temp .= <<EOF;
        /* optimize node */
        res = optimize_node(res);
-       irn_vrfy_irg(res, current_ir_graph);
+       irn_verify_irg(res, irg);
 
        return res;
 EOF
@@ -466,7 +482,7 @@ EOF
        $obst_constructor .= "}\n\n";
 }
 
-push(@obst_enum_op, "typedef enum _${arch}_opcodes {\n");
+push(@obst_enum_op, "typedef enum ${arch}_opcodes {\n");
 foreach my $op (keys(%nodes)) {
        my %n        = %{ $nodes{"$op"} };
        my $known_mode;
@@ -519,18 +535,20 @@ foreach my $op (keys(%nodes)) {
 
                $num_outs = $#outs + 1;
 
-               $obst_proj .= "\nenum pn_${op} {\n";
+               if ($num_outs > 0) {
+                       $obst_proj .= "\nenum pn_${op} {\n";
 
-               for (my $idx = 0; $idx <= $#outs; $idx++) {
-                       # check, if we have additional flags annotated to out
-                       if ($outs[$idx] =~ /:((S|I)(\|(S|I))*)/) {
-                               push(@out_flags, $1);
-                               $outs[$idx] =~ s/:((S|I)(\|(S|I))*)//;
+                       for (my $idx = 0; $idx <= $#outs; $idx++) {
+                               # check, if we have additional flags annotated to out
+                               if ($outs[$idx] =~ /:((S|I)(\|(S|I))*)/) {
+                                       push(@out_flags, $1);
+                                       $outs[$idx] =~ s/:((S|I)(\|(S|I))*)//;
+                               }
+                               $obst_proj .= "\tpn_${op}_".$outs[$idx]." = ${idx},\n";
                        }
-                       $obst_proj .= "\tpn_${op}_".$outs[$idx]." = ${idx},\n";
-               }
 
-               $obst_proj .= "};\n";
+                       $obst_proj .= "};\n";
+               }
                # outs have names, it must be a mode_T node
                if (!defined($n{mode})) {
                        $n{mode} = "mode_T";
@@ -544,11 +562,13 @@ foreach my $op (keys(%nodes)) {
                        die "Fatal error: Op ${op} has different number of ins and arity\n";
                }
 
-               $obst_proj .= "\nenum n_$op {\n";
-               for (my $idx = 0; $idx <= $#ins; $idx++) {
-                       $obst_proj .= "\tn_${op}_".$ins[$idx]." = ${idx},\n";
+               if ($#ins >= 0) {
+                       $obst_proj .= "\nenum n_$op {\n";
+                       for (my $idx = 0; $idx <= $#ins; $idx++) {
+                               $obst_proj .= "\tn_${op}_".$ins[$idx]." = ${idx},\n";
+                       }
+                       $obst_proj .= "};\n";
                }
-               $obst_proj .= "};\n";
        }
 
        # Create opcode
@@ -581,14 +601,14 @@ EOF
        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, "static int cmp_attr_$op(const ir_node *a, const ir_node *b) {\n");
                if($cmpcode =~ m/attr_a/) {
-                       push(@obst_cmp_attr, "\t${attr_type} *attr_a = get_irn_generic_attr(a);\n");
+                       push(@obst_cmp_attr, "\tconst ${attr_type} *attr_a = get_irn_generic_attr_const(a);\n");
                } else {
                        push(@obst_cmp_attr, "\t(void) a;\n");
                }
                if($cmpcode =~ m/attr_b/) {
-                       push(@obst_cmp_attr, "\t${attr_type} *attr_b = get_irn_generic_attr(b);\n");
+                       push(@obst_cmp_attr, "\tconst ${attr_type} *attr_b = get_irn_generic_attr_const(b);\n");
                } else {
                        push(@obst_cmp_attr, "\t(void) b;\n");
                }
@@ -596,6 +616,8 @@ EOF
                push(@obst_cmp_attr, "}\n\n");
 
                $cmp_attr_func = "cmp_attr_${op}";
+       } elsif ($attr_type eq "") {
+               $cmp_attr_func = "NULL";
        } else {
                if(defined($compare_attr{${attr_type}})) {
                        $cmp_attr_func = $compare_attr{${attr_type}};
@@ -655,23 +677,35 @@ EOF
        }
 
        my %known_flags = map { $_ => 1 } (
-               "none", "labeled", "commutative", "cfopcode", "op_cfopcode",
-               "fragile", "forking", "highlevel", "constlike", "always_opt",
-               "keep", "start_block", "uses_memory", "dump_noblock",
-               "dump_noinput", "machine", "machine_op", "cse_neutral"
+               "none", "labeled", "commutative", "cfopcode", "unknown_jump", "fragile",
+               "forking", "highlevel", "constlike", "always_opt", "keep",
+               "start_block", "uses_memory", "dump_noblock", "dump_noinput",
+               "machine", "machine_op", "cse_neutral"
        );
+       my $is_fragile = 0;
        foreach my $flag (@{$n{"op_flags"}}) {
                if (not defined($known_flags{$flag})) {
                        print STDERR "WARNING: Flag '$flag' in opcode $op is unknown\n";
                }
+               if ($flag eq "fragile") {
+                       $is_fragile = 1;
+               }
        }
        my @mapped = map { "irop_flag_$_" } @{$n{"op_flags"}};
        my $op_flags = join('|', @mapped);
 
+       my $attr_size = "0";
+       if ($attr_type ne "") {
+               $attr_size = "sizeof(${attr_type})"
+       }
+
        $n_opcodes++;
        $temp  = "\top_$op = new_ir_op(cur_opcode + iro_$op, \"$op\", op_pin_state_".$n{"state"}.", $op_flags";
-       $temp .= "|irop_flag_machine, ".translate_arity($arity).", 0, sizeof(${attr_type}), &ops);\n";
+       $temp .= "|irop_flag_machine, ".translate_arity($arity).", 0, ${attr_size}, &ops);\n";
        push(@obst_new_irop, $temp);
+       if ($is_fragile) {
+               push(@obst_new_irop, "\tir_op_set_fragile_indices(op_${op}, n_${op}_mem, pn_${op}_X_regular, pn_${op}_X_except);\n");
+       }
        push(@obst_new_irop, "\tset_op_tag(op_$op, $arch\_op_tag);\n");
        if(defined($default_op_attr_type)) {
                push(@obst_new_irop, "\tattr = &attrs[iro_$op];\n");
@@ -694,7 +728,9 @@ push(@obst_enum_op, "\n} $arch\_opcodes;\n\n");
 
 open(OUT, ">$target_c") || die("Fatal error: Could not open $target_c, reason: $!\n");
 
-print OUT "#include \"gen_$arch\_regalloc_if.h\"\n\n";
+print OUT "#include \"gen_$arch\_regalloc_if.h\"\n";
+print OUT "#include \"irverify_t.h\"\n";
+print OUT "\n";
 print OUT @obst_cmp_attr;
 print OUT "\n";
 print OUT @obst_opvar;
@@ -766,7 +802,7 @@ print OUT <<END;
 #ifdef BIT
 #undef BIT
 #endif
-#define BIT(x)  (1 << (x % 32))
+#define BIT(x)  (1 << (x))
 
 END
 
@@ -784,22 +820,6 @@ $obst_constructor
  * needed for the assembler irgs.
  */
 void $arch\_create_opcodes(const arch_irn_ops_t *be_ops) {
-#define N   irop_flag_none
-#define L   irop_flag_labeled
-#define C   irop_flag_commutative
-#define X   irop_flag_cfopcode
-#define F   irop_flag_fragile
-#define Y   irop_flag_forking
-#define H   irop_flag_highlevel
-#define c   irop_flag_constlike
-#define K   irop_flag_keep
-#define M   irop_flag_machine
-#define O   irop_flag_machine_op
-#define NB  irop_flag_dump_noblock
-#define NI  irop_flag_dump_noinput
-#define n   irop_flag_cse_neutral
-#define R   (irop_flag_user << 0)
-
        ir_op_ops  ops;
        int        cur_opcode;
        static int run_once = 0;
@@ -821,8 +841,7 @@ print OUT<<ENDOFMAIN;
 ENDOFMAIN
 
        if (defined($default_op_attr_type)) {
-               print OUT "\tattrs = xmalloc(sizeof(attr[0]) * iro_$arch\_last);\n";
-               print OUT "\tmemset(attrs, 0, sizeof(attr[0]) * iro_$arch\_last);\n";
+               print OUT "\tattrs = XMALLOCNZ(${default_op_attr_type}, iro_${arch}_last);\n";
        }
 
 print OUT @obst_new_irop;
@@ -1012,7 +1031,7 @@ sub get_reg_class {
 }
 
 ###
-# Returns the index of a given register within it's register class.
+# Returns the index of a given register within its register class.
 # @return index or undef
 ###
 sub get_reg_index {
@@ -1227,7 +1246,10 @@ CHECK_REQS: foreach (@regs) {
                                } elsif(defined($temp)) {
                                        $temp .= " | ";
                                }
-                               $temp .= "BIT(REG_".uc(${reg}).")";
+                               my $firstreg = uc($reg_classes{$class}[0]->{"name"});
+                               my $classuc = uc($class);
+                               my $reguc = uc($reg);
+                               $temp .= "BIT(REG_${classuc}_${reguc})";
                        }
                        if(defined($temp)) {
                                push(@obst_limit_func, "${temp}");
@@ -1251,6 +1273,7 @@ sub generate_requirements {
        my $idx   = shift;
        my $is_in = shift;
        my $class = "";
+       my $width = 1;
        my $result;
 
        my @req_type_mask;
@@ -1260,6 +1283,10 @@ sub generate_requirements {
                                push(@req_type_mask, "arch_register_req_type_ignore");
                        } elsif ($f eq "S") {
                                push(@req_type_mask, "arch_register_req_type_produces_sp");
+                       } elsif ($f eq "a") {
+                               push(@req_type_mask, "arch_register_req_type_aligned");
+                       } elsif ($f eq "2" or $f eq "4" or $f eq "8") {
+                               $width = int($f);
                        }
                }
        }
@@ -1272,7 +1299,8 @@ sub generate_requirements {
        NULL,                         /* regclass */
        NULL,                         /* limit bitset */
        0,                            /* same pos */
-       0                             /* different pos */
+       0,                            /* different pos */
+       0                             /* width */
 };
 
 EOF
@@ -1286,7 +1314,8 @@ EOF
        & ${arch}_reg_classes[CLASS_${arch}_${class}],
        NULL,        /* limit bitset */
        0,           /* same pos */
-       0            /* different pos */
+       0,           /* different pos */
+       $width            /* width */
 };
 
 EOF
@@ -1321,7 +1350,8 @@ EOF
        & ${arch}_reg_classes[CLASS_${arch}_${class}],
        ${limit_bitset},
        ${same_pos},        /* same pos */
-       ${different_pos}        /* different pos */
+       ${different_pos},       /* different pos */
+       $width             /* width */
 };
 
 EOF