X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fscripts%2Fgenerate_new_opcodes.pl;h=329ca17bb6f14b0a4983dd7da94cc39199096fcd;hb=516482fa4892951b0f20a507f10cc7488ac6b250;hp=a628d696f2bebdbfc55317f3ffdb5f33d5eae78c;hpb=1161999117f5c0f56b3af2dc9bb7150e03761905;p=libfirm diff --git a/ir/be/scripts/generate_new_opcodes.pl b/ir/be/scripts/generate_new_opcodes.pl index a628d696f..329ca17bb 100755 --- a/ir/be/scripts/generate_new_opcodes.pl +++ b/ir/be/scripts/generate_new_opcodes.pl @@ -61,12 +61,14 @@ push(@obst_header, "void ".$arch."_create_opcodes(void);\n"); push(@obst_enum_op, "typedef enum _$arch\_opcodes {\n"); foreach my $op (keys(%nodes)) { - my %n = %{ $nodes{"$op"} }; - my $tuple = 0; - my $n_res = 0; + my %n = %{ $nodes{"$op"} }; + my $tuple = 0; + my $n_res = 0; + my $num_outs = 0; + my @out_flags; # determine arity from in requirements - $arity = 0; + $arity = exists($n{"arity"}) ? $n{"arity"} : 0; if (exists($n{"reg_req"}) && exists($n{"reg_req"}{"in"})) { $arity = scalar(@{ $n{"reg_req"}{"in"} }); } @@ -75,20 +77,31 @@ foreach my $op (keys(%nodes)) { $op = $arch."_".$op; $temp = ""; + # define some proj numbers if (exists($n{"outs"})) { undef my @outs; - @outs = @{ $n{"outs"} }; + + @outs = @{ $n{"outs"} }; + $num_outs = $#outs + 1; + push(@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))*)//; + } push(@obst_proj, " pn_$op\_".$outs[$idx]." = $idx,\n"); } + push(@obst_proj, "};\n"); $tuple = 1; } push(@obst_opvar, "ir_op *op_$op = NULL;\n"); push(@obst_get_opvar, "ir_op *get_op_$op(void) { return op_$op; }\n"); - push(@obst_get_opvar, "int is_$op(const ir_node *n) { return get_irn_op(n) == op_$op; }\n\n"); + push(@obst_get_opvar, "int is_$op(const ir_node *n) { return get_$arch\_irn_opcode(n) == iro_$op; }\n\n"); push(@obst_is_archirn, "is_$op(node)"); @@ -102,6 +115,8 @@ foreach my $op (keys(%nodes)) { push(@obst_cmp_attr, "static int cmp_attr_$op(ir_node *a, ir_node *b) {\n"); push(@obst_cmp_attr, " $arch\_attr_t *attr_a = get_$arch\_attr(a);\n"); push(@obst_cmp_attr, " $arch\_attr_t *attr_b = get_$arch\_attr(b);\n"); + push(@obst_cmp_attr, " (void) attr_a;\n"); + push(@obst_cmp_attr, " (void) attr_b;\n"); push(@obst_cmp_attr, $n{"cmp_attr"}); push(@obst_cmp_attr, "}\n\n"); @@ -153,6 +168,7 @@ foreach my $op (keys(%nodes)) { # $complete_args = substr($complete_args, 2); $temp .= "$complete_args)"; push(@obst_constructor, $temp." {\n"); + push(@obst_header, $n{"comment"}); push(@obst_header, $temp.";\n"); # emit constructor code @@ -221,6 +237,9 @@ foreach my $op (keys(%nodes)) { elsif ($flag eq "I") { $temp .= " flags |= arch_irn_flags_ignore; /* ignore op for register allocation */\n"; } + elsif ($flag eq "S") { + $temp .= " flags |= arch_irn_flags_modify_sp; /* op modifies stack pointer */\n"; + } } } @@ -243,14 +262,24 @@ foreach my $op (keys(%nodes)) { } if (@out) { - $out_param = $out_req_var.", ".($#out + 1); - $n_res = $#out; + $n_res = $#out + 1; + $out_param = "$out_req_var, $n_res"; } else { $out_param = "NULL, 0"; } } + else { + $in_param = "NULL"; + $out_param = "NULL, 0"; + } $temp .= "\n /* create node */\n"; + + my $latency = 1; + if (exists($n{"latency"})) { + $latency = $n{"latency"}; + } + my $mode = "mode"; if ($tuple == 1) { $mode = "mode_T"; @@ -258,7 +287,30 @@ foreach my $op (keys(%nodes)) { $temp .= " res = new_ir_node(db, irg, block, op_$op, $mode, $arity, ".($arity > 0 ? "in" : "NULL").");\n"; $temp .= "\n /* init node attributes */\n"; - $temp .= " init_$arch\_attributes(res, flags, $in_param, $out_param);\n"; + $temp .= " init_$arch\_attributes(res, flags, $in_param, $out_param, $latency);\n"; + + # set flags for outs + if ($#out_flags >= 0) { + $temp .= "\n /* set flags for outs */\n"; + for (my $idx = 0; $idx <= $#out_flags; $idx++) { + my $flags = ""; + my $prefix = ""; + + foreach my $flag (split(/\|/, $out_flags[$idx])) { + if ($flag eq "I") { + $flags .= $prefix."arch_irn_flags_ignore"; + $prefix = " | "; + } + elsif ($flag eq "S") { + $flags .= $prefix."arch_irn_flags_modify_sp"; + $prefix = " | "; + } + } + + $temp .= " set_$arch\_out_flags(res, $flags, $idx);\n"; + } + } + if (exists($n{"init_attr"})) { $temp .= " attr = get_$arch\_attr(res);\n"; @@ -279,7 +331,6 @@ foreach my $op (keys(%nodes)) { # close constructor function push(@obst_constructor, "}\n\n"); - } # constructor creation # set default values for state and flags if not given @@ -298,7 +349,10 @@ foreach my $op (keys(%nodes)) { $temp = " op_$op = new_ir_op(cur_opcode + iro_$op, \"$op\", op_pin_state_".$n{"state"}.", ".$n{"op_flags"}; $temp .= "|M, ".translate_arity($arity).", 0, sizeof($arch\_attr_t) + $n_res * sizeof(arch_register_t *), &ops);\n"; push(@obst_new_irop, $temp); + push(@obst_new_irop, " set_op_tag(op_$op, &$arch\_op_tag);\n"); push(@obst_enum_op, " iro_$op,\n"); + + push(@obst_header, "\n"); } push(@obst_enum_op, " iro_$arch\_last_generated,\n"); push(@obst_enum_op, " iro_$arch\_last = iro_$arch\_last_generated"); @@ -317,11 +371,37 @@ print OUT "\n"; print OUT @obst_get_opvar; print OUT "\n"; -print OUT<= 1) { + $a = uc(substr($arch, 0, 1)); +} + +if (length($arch) >= 2) { + $b = uc(substr($arch, 1, 1)); +} + +if (length($arch) >= 3) { + $c = uc(substr($arch, 2, 1)); +} + +if (length($arch) >= 4) { + $d = uc(substr($arch, 3, 1)); +} + +print OUT "static unsigned $arch\_op_tag = FOURCC('$a', '$b', '$c', '$d');\n"; + +print OUT< 0 && "missing opcode init"); - assert($arch\_opcode_end > 0 && "missing opcode init"); - - if (opc - (unsigned)$arch\_opcode_start < (unsigned)($arch\_opcode_end - $arch\_opcode_start)) - return 1; - - return 0; + return get_op_tag(get_irn_op(node)) == &$arch\_op_tag; } int get_$arch\_irn_opcode(const ir_node *node) { - assert(is_$arch\_irn(node)); - return get_irn_opcode(node) - $arch\_opcode_start; + if (is_$arch\_irn(node)) + return get_irn_opcode(node) - $arch\_opcode_start; + return -1; } ENDOFISIRN