X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fscripts%2Fgenerate_regalloc_if.pl;h=284ca6bac3b4393c853c46ecb9ea4faeeef77364;hb=0c2e8bedc56cb9dba9b2544927a8093ddb7ee614;hp=3fb2bfce267483265da99c5d1c4d6c0d4dd43c7f;hpb=57f7225b1ac3c6f936d938eeebc9ae0624eb7143;p=libfirm diff --git a/ir/be/scripts/generate_regalloc_if.pl b/ir/be/scripts/generate_regalloc_if.pl index 3fb2bfce2..284ca6bac 100755 --- a/ir/be/scripts/generate_regalloc_if.pl +++ b/ir/be/scripts/generate_regalloc_if.pl @@ -61,26 +61,18 @@ sub translate_reg_type { my @types; if ($t & 1) { - push(@types, "arch_register_type_caller_save"); - } - - if ($t & 2) { - push(@types, "arch_register_type_callee_save"); - } - - if ($t & 4) { push(@types, "arch_register_type_ignore"); } - if ($t & 8) { + if ($t & 2) { push(@types, "arch_register_type_joker"); } - if ($t & 16) { + if ($t & 4) { push(@types, "arch_register_type_virtual"); } - if ($t & 32) { + if ($t & 8) { push(@types, "arch_register_type_state"); } @@ -89,36 +81,81 @@ sub translate_reg_type { } # stacks for output -my @obst_regtypes_def; # stack for the register type variables definitions -my @obst_regtypes_decl;# stack for the register type variables declarations -my @obst_regclasses; # stack for the register class variables -my @obst_classdef; # stack to define a name for a class index -my @obst_regdef; # stack to define a name for a register index -my @obst_reginit; # stack for the register type inits -my @obst_req; # stack for the register requirements -my @obst_limit_func; # stack for functions to return a subset of a register class -my @obst_header_all; # stack for some extern struct defs needed for bearch_$arch include - -my $numregs; +my $regtypes_def; # stack for the register type variables definitions +my $regtypes_decl;# stack for the register type variables declarations +my @regclasses; # stack for the register class variables +my $classdef; # stack to define a name for a class index +my $regdef; # stack to define a name for a register index +my $regdef2; +my $regcounts; +my $reginit; # stack for the register type inits +my $single_constraints_decls; +my $single_constraints; + my $class_ptr; my $class_idx = 0; -my $tmp; - -my %reg2class; -my %regclass2len; +my %regclass2len = (); +my %reg2class = (); -push(@obst_classdef, "enum reg_classes {\n"); +$classdef .= "enum reg_classes {\n"; my $class_mode; +foreach my $class_name (keys(%reg_classes)) { + my @class = @{ $reg_classes{"$class_name"} }; + + my $idx = 0; + foreach (@class) { + if (defined($_->{name})) { + $reg2class{$_->{name}} = { + "class" => $class_name, + "index" => $idx + }; + } + $idx++; + } + $regclass2len{$class_name} = $idx; +} + +sub get_limited_array { + my $reg = shift; + my $regclass = $reg2class{"$reg"}{"class"}; + my $ucname = uc($reg); + my $result = "{ "; + + my $limitedbitsetlen = $regclass2len{$regclass}; + my $arraylen = ($limitedbitsetlen+31) / 32; + my $firstreg = uc($reg_classes{$regclass}[0]->{"name"}); + my $classuc = uc($regclass); + my $first = 1; + for (my $i = 0; $i < $arraylen; ++$i) { + if ($first) { + $first = 0; + } else { + $result .= ", "; + } + + my $index = $reg2class{"$reg"}{"index"}; + if ($index >= $i*32 && $index < ($i+1)*32) { + if ($i > 0) { + $result .= "(1 << (REG_${classuc}_${ucname} % 32))"; + } else { + $result .= "(1 << REG_${classuc}_${ucname})"; + } + } else { + $result .= "0"; + } + } + $result .= " }"; +} + # generate register type and class variable, init function and default requirements foreach my $class_name (keys(%reg_classes)) { my @class = @{ $reg_classes{"$class_name"} }; my $old_classname = $class_name; $class_name = $arch."_".$class_name; - $numregs = "N_".$class_name."_REGS"; $class_ptr = "&".$arch."_reg_classes[CLASS_".$class_name."]"; my $flags = pop(@class); $class_mode = $flags->{"mode"}; @@ -136,53 +173,77 @@ foreach my $class_name (keys(%reg_classes)) { $flags_prepared .= "arch_register_class_flag_$flag"; } } else { - $flags_prepared = "0"; + $flags_prepared = "arch_register_class_flag_none"; } - push(@obst_regtypes_decl, "extern const arch_register_t ${class_name}_regs[$numregs];\n"); + $single_constraints .= <{"name"}) . "]"; + push(@regclasses, "{ $class_idx, \"$class_name\", $numregs, NULL, $first_reg, $flags_prepared, &${arch}_class_reg_req_${old_classname} }"); my $idx = 0; - push(@obst_reginit, "\t/* set largest possible mode for '$class_name' */\n"); - push(@obst_reginit, "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n\n"); - push(@obst_regtypes_def, "const arch_register_t ${class_name}_regs[$numregs] = {\n"); - - push(@obst_regdef, "enum reg_${class_name}_indices {\n"); + $reginit .= "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n"; + my $lastreg; foreach (@class) { - my $ucname = uc($_->{"name"}); - my $type = translate_reg_type($_->{"type"}); + my $name = $_->{"name"}; + my $ucname = uc($name); + my $type = "arch_register_type_none"; + $type = translate_reg_type($_->{"type"}) if (exists($_->{"type"})); # realname is name if not set by user $_->{"realname"} = $_->{"name"} if (! exists($_->{"realname"})); my $realname = $_->{realname}; + my $classuc = uc($old_classname); + + $regdef .= "\tREG_${ucname},\n"; + $regdef2 .= "\tREG_${classuc}_${ucname} = $idx,\n"; + + $regtypes_def .= <{"name"}} = { "class" => $old_classname, "index" => $idx }; # remember reg to class for later use - push(@obst_regdef, "\tREG_${ucname},\n"); - - push(@obst_regtypes_def, "\t{\n"); - push(@obst_regtypes_def, "\t\t\"$realname\",\n"); - push(@obst_regtypes_def, "\t\t$class_ptr,\n"); - push(@obst_regtypes_def, "\t\tREG_${ucname},\n"); - push(@obst_regtypes_def, "\t\t$type\n"); - push(@obst_regtypes_def, "\t},\n"); - + $lastreg = $ucname; $idx++; } - push(@obst_regtypes_def, "};\n"); - - $regclass2len{$old_classname} = $idx; - push(@obst_regdef, "\t$numregs = $idx\n"); - push(@obst_regdef, "};\n\n"); + $regcounts .= "\tN_${class_name}_REGS = $numregs,\n"; $class_idx++; } -push(@obst_classdef, "\tN_CLASSES = ".scalar(keys(%reg_classes))."\n"); -push(@obst_classdef, "};\n\n"); +my $archuc = uc($arch); -$tmp = uc($arch); +$classdef .= "\tN_${archuc}_CLASSES = ".scalar(keys(%reg_classes))."\n"; +$classdef .= "};\n\n"; # generate header (external usage) file open(OUT, ">$target_h") || die("Fatal error: Could not open $target_h, reason: $!\n"); @@ -198,32 +259,39 @@ print OUT<$target_c") || die("Fatal error: Could not open $target_c, reason: $!\n"); @@ -245,23 +313,28 @@ print OUT<