X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fscripts%2Fgenerate_new_opcodes.pl;h=1a634a6e37c5ba6b7623fdcf873022de63c0566a;hb=1872920c09708b361d06c0dc9f4c1fd0a03544f5;hp=8aedc397b4035aee59f80c2cc256e46c631bfc3f;hpb=94f4a791ce59facde3a91d62c6cd6e4385843a1b;p=libfirm diff --git a/ir/be/scripts/generate_new_opcodes.pl b/ir/be/scripts/generate_new_opcodes.pl index 8aedc397b..1a634a6e3 100755 --- a/ir/be/scripts/generate_new_opcodes.pl +++ b/ir/be/scripts/generate_new_opcodes.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl -w # -# Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. +# Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. # # This file is part of libFirm. # @@ -39,10 +39,12 @@ our $additional_opcodes; our %nodes; our %operands; our %cpu; +our $default_op_attr_type; our $default_attr_type; our $default_cmp_attr; our $default_copy_attr; our %init_attr; +our $custom_init_attr_func; our %compare_attr; our %copy_attr; our %reg_classes; @@ -67,7 +69,7 @@ if(!defined($default_attr_type)) { } if(!defined(%init_attr)) { %init_attr = ( - "$default_attr_type" => "\tinit_${arch}_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", + "$default_attr_type" => "\tinit_${arch}_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);", ); } if(!defined($default_cmp_attr)) { @@ -156,7 +158,7 @@ foreach my $class_name (keys(%reg_classes)) { # for registering additional opcodes $n_opcodes += $additional_opcodes if (defined($additional_opcodes)); -push(@obst_header, "void ".$arch."_create_opcodes(void);\n"); +push(@obst_header, "void ".$arch."_create_opcodes(const arch_irn_ops_t *be_ops);\n"); push(@obst_enum_op, "typedef enum _$arch\_opcodes {\n"); foreach my $op (keys(%nodes)) { @@ -263,6 +265,12 @@ foreach my $op (keys(%nodes)) { $attr_type = $default_attr_type; } + # determine hash function + my $hash_func; + if (exists($n{"hash_func"})) { + $hash_func = $n{"hash_func"}; + } + # determine compare function my $cmp_attr_func; if (exists($n{"cmp_attr"})) { @@ -375,12 +383,6 @@ foreach my $op (keys(%nodes)) { $temp .= "\tint n_res = ${out_arity};\n"; } - my $latency = $n{"latency"}; - if (!defined($latency)) { - $latency = 1; - } - $temp .= "\tunsigned latency = ${latency};\n"; - if (defined($known_mode)) { $temp .= "\tir_mode *mode = ${known_mode};\n"; } @@ -506,32 +508,38 @@ foreach my $op (keys(%nodes)) { die "Fatal error: Couldn't find attribute initialisation code for type '${attr_type}'"; } $temp .= "${attr_init_code}\n"; + if(defined($custom_init_attr_func)) { + $temp .= &$custom_init_attr_func(\%n, $op); + } $temp .= "\n"; # set flags for outs - if ($#out_flags >= 0) { - $temp .= "\t/* 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 = " | "; + if (exists($n{"outs"})) { + undef my @outs; + @outs = @{ $n{"outs"} }; + + for (my $idx = 0; $idx <= $#outs; $idx++) { + # check, if we have additional flags annotated to out + if ($outs[$idx] =~ /:((S|I)(\|(S|I))*)/) { + my $flag_string = $1; + my $prefix = ""; + my $flags = ""; + + foreach my $flag (split(/\|/, $flag_string)) { + if ($flag eq "I") { + $flags .= $prefix."arch_irn_flags_ignore"; + $prefix = " | "; + } elsif ($flag eq "S") { + $flags .= $prefix."arch_irn_flags_modify_sp"; + $prefix = " | "; + } } - } - $temp .= "\tset_$arch\_out_flags(res, $flags, $idx);\n"; + $temp .= "\tset_$arch\_out_flags(res, $flags, $idx);\n"; + } } - $temp .= "\n"; } - if (exists($n{"init_attr"})) { $temp .= "\tattr = get_irn_generic_attr(res);\n"; $temp .= "\t".$n{"init_attr"}."\n"; @@ -560,6 +568,7 @@ foreach my $op (keys(%nodes)) { push(@obst_new_irop, "\n\tmemset(&ops, 0, sizeof(ops));\n"); + push(@obst_new_irop, "\tops.be_ops = be_ops;\n"); push(@obst_new_irop, "\tops.dump_node = $arch\_dump_node;\n"); if (defined($cmp_attr_func)) { @@ -572,6 +581,9 @@ foreach my $op (keys(%nodes)) { if (defined($copy_attr_func)) { push(@obst_new_irop, "\tops.copy_attr = ${copy_attr_func};\n"); } + if (defined($hash_func)) { + push(@obst_new_irop, "\tops.hash = ${hash_func};\n"); + } $n_opcodes++; my $n_res = $out_arity; @@ -581,7 +593,15 @@ foreach my $op (keys(%nodes)) { $temp = "\top_$op = new_ir_op(cur_opcode + iro_$op, \"$op\", op_pin_state_".$n{"state"}.", ".$n{"op_flags"}; $temp .= "|M, ".translate_arity($arity).", 0, sizeof(${attr_type}), &ops);\n"; push(@obst_new_irop, $temp); - push(@obst_new_irop, "\tset_op_tag(op_$op, &$arch\_op_tag);\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"); + if(defined($n{op_attr_init})) { + push(@obst_new_irop, "\t".$n{op_attr_init}."\n"); + } + push(@obst_new_irop, "\tset_op_attr(op_$op, attr);\n"); + } + push(@obst_enum_op, "\tiro_$op,\n"); push(@obst_header, "\n"); @@ -633,7 +653,7 @@ if (length($arch) >= 4) { print OUT<ops.be_ops == NULL) + op->ops.be_ops = be_ops; + } + cur_opcode = get_next_ir_opcodes(iro_$arch\_last); $arch\_opcode_start = cur_opcode; 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 @obst_new_irop; print OUT "\n"; print OUT "\t$arch\_register_additional_opcodes(cur_opcode);\n" if (defined($additional_opcodes)); @@ -855,7 +897,8 @@ TP_SEARCH: foreach my $cur_type (keys(%cpu)) { } sub mangle_requirements { - my $reqs = shift; + my $reqs = shift; + my $class = shift; my @alternatives = split(/ /, $reqs); for(my $idx = 0; $idx < scalar(@alternatives); $idx++) { @@ -864,7 +907,7 @@ sub mangle_requirements { @alternatives = sort @alternatives; - my $name = join('_', @alternatives); + my $name = $class."_".join('_', @alternatives); return $name; } @@ -957,8 +1000,8 @@ sub build_subset_class_func { my $class = undef; my $has_limit = 0; my $limit_name; - my $same_pos = undef; - my $different_pos = undef; + my $same_pos = 0; + my $different_pos = 0; my $temp; my @obst_init; my @obst_limits; @@ -973,29 +1016,38 @@ sub build_subset_class_func { my $is_in = shift; my @regs = split(/ /, shift); - my $outin = $is_in ? "out" : "in"; - my @idx_class = build_inout_idx_class($node, $op, !$is_in); # set/unset registers CHECK_REQS: foreach (@regs) { - if (/(!)?$outin\_r(\d+)/) { - if (($1 && defined($different_pos)) || (!$1 && defined($same_pos))) { - print STDERR "Multiple in/out references of same type in one requirement not allowed.\n"; + if (!$is_in && /(!)?in_r(\d+)/) { + my $bit_pos = 1 << ($2 - 1); + if ($different_pos & $bit_pos) { + if ($1) { + print STDERR "duplicate !in constraint\n"; + } else { + print STDERR "conflicting !in and in constraints\n"; + } + return (undef, undef, undef, undef); + } + + if ($same_pos & $bit_pos) { + if ($1) { + print STDERR "conflicting !in and in constraints\n"; + } else { + print STDERR "duplicate in constraint\n"; + } return (undef, undef, undef, undef); } if ($1) { - $different_pos = $is_in ? -$2 : $2 - 1; + $different_pos |= $bit_pos; } else { - $same_pos = $is_in ? -$2 : $2 - 1; + $same_pos |= $bit_pos; } $class = $idx_class[$2 - 1]; next CHECK_REQS; - } elsif (/!in/) { - $class = $idx_class[0]; - return ($class, "NULL", undef, 666); } # check for negate @@ -1054,8 +1106,8 @@ CHECK_REQS: foreach (@regs) { my @cur_class = @{ $reg_classes{"$class"} }; for (my $idx = 0; $idx <= $#cur_class; $idx++) { if (defined($cur_class[$idx]{"type"}) && ($cur_class[$idx]{"type"} & 4)) { - my $reg = $cur_class[$idx]{"name"}; - my $regix = get_reg_index($reg); + my $reg = $cur_class[$idx]{"name"}; + my $regix = get_reg_index($reg); my $arrayp = $regix / 32; push(@{$limit_array[$arrayp]}, $reg); $limit_reqs .= "$reg "; @@ -1064,10 +1116,11 @@ CHECK_REQS: foreach (@regs) { } if ($has_limit == 1) { - $limit_name = "${arch}_limit_".mangle_requirements($limit_reqs); + $limit_name = "${arch}_limit_".mangle_requirements($limit_reqs, $class); if(defined($limit_bitsets{$limit_name})) { - return $limit_bitsets{$limit_name}; + $limit_name = $limit_bitsets{$limit_name}; + return ($class, $limit_name, $same_pos, $different_pos); } $limit_bitsets{$limit_name} = $limit_name; @@ -1117,92 +1170,79 @@ sub generate_requirements { my $op = shift; my $idx = shift; my $is_in = shift; - - my $name = "${arch}_requirements_".mangle_requirements($reqs); - if(defined($requirements{$name})) { - return $name; - } - $requirements{$name} = $name; + my $class = ""; + my $result; if ($reqs eq "none") { - push(@obst_reg_reqs, <