sparc: fix mode of fdiv result
[libfirm] / ir / be / scripts / generate_new_opcodes.pl
index 43ae908..08ce0c9 100755 (executable)
@@ -70,7 +70,7 @@ if(!defined($default_attr_type)) {
 }
 if(!defined(%init_attr)) {
        %init_attr = (
-               "$default_attr_type" => "\tinit_${arch}_attributes(res, flags, in_reqs, exec_units, n_res);",
+               "$default_attr_type" => "\tinit_${arch}_attributes(res, irn_flags_, in_reqs, exec_units, n_res);",
        );
 }
 if(!defined($default_cmp_attr)) {
@@ -270,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  irn_flags_ = arch_irn_flags_none;
+       ir_node          *res;
+       backend_info_t   *info;
 EOF
 
        if($arity == $ARITY_DYNAMIC) {
@@ -375,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 {
@@ -416,6 +417,7 @@ EOF
                        "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);
@@ -424,16 +426,19 @@ EOF
                        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 .= "\tirn_flags_ |= " . $known_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)irn_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)) {
@@ -446,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_verify_irg(res, current_ir_graph);
+       irn_verify_irg(res, irg);
 
        return res;
 EOF
@@ -529,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";
@@ -554,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
@@ -591,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");
                }
@@ -606,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}};
@@ -665,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");
@@ -778,7 +802,7 @@ print OUT <<END;
 #ifdef BIT
 #undef BIT
 #endif
-#define BIT(x)  (1 << (x % 32))
+#define BIT(x)  (1 << (x))
 
 END
 
@@ -796,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;
@@ -833,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;
@@ -1024,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 {
@@ -1239,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}");