# This script generates C code which creates ands sets up functions and
# data structures for the register allocator.
# Creation: 2005/11/14
-# $Id$
use strict;
use Data::Dumper;
my $target_h = $target_dir."/gen_".$arch."_regalloc_if.h";
# helper function
-sub translate_reg_type {
- my $t = shift;
-
- if ($t == 0) {
- return "arch_register_type_none";
- }
- else {
- 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) {
- push(@types, "arch_register_type_joker");
- }
-
- if ($t & 16) {
- push(@types, "arch_register_type_virtual");
- }
-
- if ($t & 32) {
- push(@types, "arch_register_type_state");
- }
-
- return join(" | ", @types);
- }
+sub map_flags {
+ my $prefix = shift;
+ my $flags = shift || "none";
+ return join(" | ", map { "$prefix$_" } split(/\s*\|\s*/, $flags));
}
# stacks for output
$class_ptr = "&".$arch."_reg_classes[CLASS_".$class_name."]";
my $flags = pop(@class);
$class_mode = $flags->{"mode"};
- my $class_flags = $flags->{"flags"};
- my $flags_prepared = "";
-
- if(defined($class_flags)) {
- my $first = 1;
- foreach my $flag (split(/\|/, $class_flags)) {
- if(!$first) {
- $flags_prepared .= "|";
- } else {
- $first = 0;
- }
- $flags_prepared .= "arch_register_class_flag_$flag";
- }
- } else {
- $flags_prepared = "0";
- }
-
- $single_constraints_decls .= <<EOF;
-static const arch_register_req_t ${arch}_class_reg_req_${old_classname};
-EOF
+ my $flags_prepared = map_flags("arch_register_class_flag_", $flags->{"flags"});
$single_constraints .= <<EOF;
static const arch_register_req_t ${arch}_class_reg_req_${old_classname} = {
$reginit .= "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n";
my $lastreg;
foreach (@class) {
- my $name = $_->{"name"};
+ my $name = $_->{"name"};
my $ucname = uc($name);
- my $type = translate_reg_type($_->{"type"});
+ my $type = map_flags("arch_register_type_", $_->{"type"});
# realname is name if not set by user
$_->{"realname"} = $_->{"name"} if (! exists($_->{"realname"}));
my $realname = $_->{realname};
$regdef .= "\tREG_${ucname},\n";
$regdef2 .= "\tREG_${classuc}_${ucname} = $idx,\n";
+ my $dwarf_number = 0;
+ if (defined($_->{dwarf})) {
+ $dwarf_number = $_->{dwarf};
+ }
$regtypes_def .= <<EOF;
{
REG_${classuc}_${ucname},
REG_${ucname},
${type},
- &${arch}_single_reg_req_${old_classname}_${name}
+ &${arch}_single_reg_req_${old_classname}_${name},
+ ${dwarf_number}
},
EOF
#ifndef FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
#define FIRM_BE_${archuc}_GEN_${archuc}_REGALLOC_IF_H
-#include "../bearch.h"
+#include "bearch.h"
#include "${arch}_nodes_attr.h"
+/** global register indices for ${arch} registers */
enum reg_indices {
${regdef}
N_${archuc}_REGISTERS
};
+/** local register indices for ${arch} registers */
enum {
${regdef2}
};
+/** number of registers in ${arch} register classes. */
enum {
${regcounts}
};
extern arch_register_class_t ${arch}_reg_classes[N_${archuc}_CLASSES];
void ${arch}_register_init(void);
-unsigned ${arch}_get_n_regs(void);
#endif
EOF
#include "config.h"
#include "gen_${arch}_regalloc_if.h"
-#include "gen_${arch}_machine.h"
#include "bearch_${arch}_t.h"
#include "irmode.h"
-${single_constraints_decls}
+${single_constraints}
EOF
print OUT "arch_register_class_t ${arch}_reg_classes[] = {\n\t".join(",\n\t", @regclasses)."\n};\n\n";
print OUT<<EOF;
-${single_constraints}
+/** The array of all registers in the ${arch} architecture, sorted by its global index.*/
const arch_register_t ${arch}_registers[] = {
${regtypes_def}
};
+/**
+ * Initializes ${arch} register classes.
+ */
void ${arch}_register_init(void)
{
${reginit}
}
EOF
close(OUT);
-
-###
-# Gets the variable name for the execution unit assigned to this register.
-###
-sub get_execunit_variable_name {
- my $unit = shift;
- my $name = "NULL";
- my $uc_arch = uc($arch);
-
- if ($unit) {
- my $found = 0;
-SRCH: foreach my $cur_type (keys(%cpu)) {
- foreach my $cur_unit (@{ $cpu{"$cur_type"} }) {
- if ($unit eq $cur_unit) {
- my $tp_name = "$arch\_execution_units_$cur_type";
- my $unit_name = "$uc_arch\_EXECUNIT_TP_$cur_type\_$unit";
- $name = "&".$tp_name."[".$unit_name."]";
- $found = 1;
- last SRCH;
- }
- }
- }
-
- if (! $found) {
- print STDERR "Invalid execution unit $unit specified!\n";
- }
- }
-
- return $name;
-}