$mode_flags = "mode_Bu";
$mode_fp = "mode_E";
-# register types:
-$normal = 0; # no special type
-$caller_save = 1; # caller save (register must be saved by the caller of a function)
-$callee_save = 2; # callee save (register must be saved by the called function)
-$ignore = 4; # ignore (do not assign this register)
-$arbitrary = 8; # emitter can choose an arbitrary register of this class
-$virtual = 16; # the register is a virtual one
-$state = 32; # register represents a state
# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
%reg_classes = (
gp => [
- { name => "r0", type => $caller_save },
- { name => "r1", type => $caller_save },
- { name => "r2", type => $caller_save },
- { name => "r3", type => $caller_save },
- { name => "r4", type => $callee_save },
- { name => "r5", type => $callee_save },
- { name => "r6", type => $callee_save },
- { name => "r7", type => $callee_save },
- { name => "r8", type => $callee_save },
- { name => "r9", type => $callee_save },
- { name => "r10", type => $callee_save },
- { name => "r11", type => $callee_save },
- { name => "r12", type => $ignore }, # reserved for linker/immediate fixups
- { name => "sp", type => $ignore }, # this is our stack pointer
- { name => "lr", type => $callee_save | $caller_save }, # this is our return address
- { name => "pc", type => $ignore }, # this is our program counter
+ { name => "r0" },
+ { name => "r1" },
+ { name => "r2" },
+ { name => "r3" },
+ { name => "r4" },
+ { name => "r5" },
+ { name => "r6" },
+ { name => "r7" },
+ { name => "r8" },
+ { name => "r9" },
+ { name => "r10" },
+ { name => "r11" },
+ { name => "r12" },
+ { name => "sp" },
+ { name => "lr" },
+ { name => "pc" },
{ mode => $mode_gp }
],
fpa => [
- { name => "f0", type => $caller_save },
- { name => "f1", type => $caller_save },
- { name => "f2", type => $caller_save },
- { name => "f3", type => $caller_save },
- { name => "f4", type => $caller_save },
- { name => "f5", type => $caller_save },
- { name => "f6", type => $caller_save },
- { name => "f7", type => $caller_save },
+ { name => "f0" },
+ { name => "f1" },
+ { name => "f2" },
+ { name => "f3" },
+ { name => "f4" },
+ { name => "f5" },
+ { name => "f6" },
+ { name => "f7" },
{ mode => $mode_fp }
],
flags => [
- { name => "fl", type => 0 },
+ { name => "fl" },
{ mode => $mode_flags, flags => "manual_ra" }
],
);
mode => "mode_T",
attr => "int n_projs, long def_proj_num",
init_attr => "\tset_arm_SwitchJmp_n_projs(res, n_projs);\n".
- "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);",
+ "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);\n".
+ "\tinfo->out_infos = NULL;",
reg_req => { in => [ "gp" ], out => [ "none" ] },
attr_type => "arm_SwitchJmp_attr_t",
},
assert(assignment[i] >= 0 && "there must have been a register assigned (node not register pressure faithful?)");
reg = arch_register_for_index(env->cls, assignment[i]);
- assert(! (reg->type & arch_register_type_ignore));
irn = alloc_nodes[i];
if (irn != NULL) {
col = get_next_free_reg(alloc_env, colors);
reg = arch_register_for_index(env->cls, col);
assert(arch_get_irn_register(irn) == NULL && "This node must not have been assigned a register yet");
- assert(!arch_register_type_is(reg, ignore) && "Must not assign ignore register");
}
bitset_set(colors, col);
assert(reg && "Register must have been assigned");
col = arch_register_get_index(reg);
-#ifndef NDEBUG
- if (!arch_register_type_is(reg, ignore)) {
- assert(bitset_is_set(live, nr) && "Cannot have a non live use");
- }
-#endif
bitset_clear(colors, col);
bitset_clear(live, nr);
static int co_is_optimizable_root(ir_node *irn)
{
const arch_register_req_t *req;
- const arch_register_t *reg;
if (arch_irn_is_ignore(irn))
return 0;
- reg = arch_get_irn_register(irn);
- if (arch_register_type_is(reg, ignore))
- return 0;
-
if (is_Reg_Phi(irn) || is_Perm_Proj(irn))
return 1;
const arch_register_req_t *req;
copy_opt_t *co = env;
int pos, max;
- const arch_register_t *reg;
if (get_irn_mode(irn) == mode_T)
return;
if (req->cls != co->cls || arch_irn_is_ignore(irn))
return;
- reg = arch_get_irn_register(irn);
- if (arch_register_type_is(reg, ignore))
- return;
-
if (is_Reg_Phi(irn)) { /* Phis */
for (pos=0, max=get_irn_arity(irn); pos<max; ++pos) {
ir_node *arg = get_irn_n(irn, pos);
be_ifg_t *ifg = co->cenv->ifg;
int *color_map = ALLOCAN(int, co->cls->n_regs);
int *node_map = XMALLOCN(int, get_irg_last_idx(co->irg) + 1);
+ ir_graph *irg = co->irg;
+ be_irg_t *birg = be_birg_from_irg(irg);
ir_node *irn;
nodes_iter_t it;
n_regs = 0;
for (i = 0; i < co->cls->n_regs; ++i) {
const arch_register_t *reg = &co->cls->regs[i];
- color_map[i] = arch_register_type_is(reg, ignore) ? -1 : n_regs++;
+ if (rbitset_is_set(birg->allocatable_regs, reg->global_index)) {
+ color_map[i] = n_regs++;
+ } else {
+ color_map[i] = -1;
+ }
}
/*
}
end_list("registers");
+#if 0
begin_block_mapping("flags");
for (r = 0; r < n_regs; ++r) {
const arch_register_t *reg = arch_register_for_index(cls, r);
}
}
end_block_mapping("flags");
+#endif
end_block_mapping(NULL);
}
void be_set_constr_single_reg_out(ir_node *node, int pos,
const arch_register_t *reg, arch_register_req_type_t additional_types)
{
+ ir_graph *irg = get_irn_irg(node);
+ be_irg_t *birg = be_birg_from_irg(irg);
const arch_register_req_t *req;
/* if we have an ignore register, add ignore flag and just assign it */
- if (reg->type & arch_register_type_ignore) {
+ if (!rbitset_is_set(birg->allocatable_regs, reg->global_index)) {
additional_types |= arch_register_req_type_ignore;
}
const arch_register_class_t *cls = env->cls;
ir_node *block = get_nodes_block(node);
const ir_graph *irg = env->irg;
+ be_irg_t *birg = be_birg_from_irg(irg);
be_lv_t *lv = be_get_irg_liveness(irg);
unsigned *tmp = NULL;
unsigned *def_constr = NULL;
* fullfil the constraint
* (typical example: stack pointer as input to copyb)
* TODO: This really just checks precolored registers at the moment and
- * ignore the general case of not matching in/out constraints
+ * ignores the general case of not matching in/out constraints
*/
for (i = 0; i < arity; ++i) {
- ir_node *op = get_irn_n(node, i);
- ir_node *copy;
- const arch_register_t *reg;
- const arch_register_req_t *req;
+ ir_node *op = get_irn_n(node, i);
+ const arch_register_req_t *req = arch_get_register_req(node, i);
+ const arch_register_t *reg;
+ ir_node *copy;
- req = arch_get_register_req(node, i);
if (req->cls != cls)
continue;
reg = arch_get_irn_register(op);
/* precolored with an ignore register (which is not a joker like
unknown/noreg) */
if (arch_register_type_is(reg, joker)
- || !arch_register_type_is(reg, ignore))
+ || rbitset_is_set(birg->allocatable_regs, reg->global_index))
continue;
if (! (req->type & arch_register_req_type_limited))
stat_ev_int("constr_copy", 1);
sched_add_before(node, copy);
set_irn_n(node, i, copy);
- DBG((dbg, LEVEL_3, "inserting ignore arg copy %+F for %+F pos %d\n", copy, node, i));
+ DBG((dbg, LEVEL_3, "inserting ignore arg copy %+F for %+F pos %d\n",
+ copy, node, i));
}
/* insert copies for nodes that occur constrained more than once. */
const arch_env_t *arch_env = be_get_irg_arch_env(irg);
be_irg_t *birg = be_birg_from_irg(irg);
const arch_register_req_t *sp_req = birg->sp_req;
+ const arch_register_t *sp = arch_env->sp;
be_ssa_construction_env_t senv;
int i, len;
ir_node **phis;
new_sp_req->width = 1;
limited_bitset = rbitset_obstack_alloc(obst, new_sp_req->cls->n_regs);
- rbitset_set(limited_bitset, arch_register_get_index(arch_env->sp));
+ rbitset_set(limited_bitset, arch_register_get_index(sp));
new_sp_req->limited = limited_bitset;
- if (arch_env->sp->type & arch_register_type_ignore) {
+
+ if (!rbitset_is_set(birg->allocatable_regs, sp->global_index)) {
new_sp_req->type |= arch_register_req_type_ignore;
}
/**
* Find a free GP register if possible, else return NULL.
*/
-static const arch_register_t *get_free_gp_reg(void)
+static const arch_register_t *get_free_gp_reg(ir_graph *irg)
{
+ be_irg_t *birg = be_birg_from_irg(irg);
int i;
for (i = 0; i < N_ia32_gp_REGS; ++i) {
const arch_register_t *reg = &ia32_reg_classes[CLASS_ia32_gp].regs[i];
- if (arch_register_type_is(reg, ignore))
+ if (!rbitset_is_set(birg->allocatable_regs, reg->global_index))
continue;
if (be_peephole_get_value(CLASS_ia32_gp, i) == NULL)
if (offset < 0) {
/* we need a free register for pop */
- reg = get_free_gp_reg();
+ reg = get_free_gp_reg(get_irn_irg(node));
if (reg == NULL)
return;
return;
}
/* we need a free register */
- reg = get_free_gp_reg();
+ reg = get_free_gp_reg(get_irn_irg(imul));
if (reg == NULL)
return;
$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 = "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};
$mode_fp2 = "mode_D";
$mode_fp4 = "mode_E"; # not correct, we need to register a new mode
-$normal = 0; # no special type
-$caller_save = 1; # caller save (register must be saved by the caller of a function)
-$callee_save = 2; # callee save (register must be saved by the called function)
-$ignore = 4; # ignore (do not assign this register)
-$arbitrary = 8; # emitter can choose an arbitrary register of this class
-$virtual = 16; # the register is a virtual one
-$state = 32; # register represents a state
-
# available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
%reg_classes = (
gp => [
- { name => "g0", type => $ignore }, # hardwired 0, behaves like /dev/null
- { name => "g1", type => $caller_save }, # temp. value
- { name => "g2", type => $caller_save },
- { name => "g3", type => $caller_save },
- { name => "g4", type => $caller_save },
- { name => "g5", type => $ignore }, # reserved by SPARC ABI
- { name => "g6", type => $ignore }, # reserved by SPARC ABI
- { name => "g7", type => $ignore }, # reserved by SPARC ABI
-
- # window's out registers
- { name => "o0", type => $caller_save }, # param 1 / return value from callee
- { name => "o1", type => $caller_save }, # param 2
- { name => "o2", type => $caller_save }, # param 3
- { name => "o3", type => $caller_save }, # param 4
- { name => "o4", type => $caller_save }, # param 5
- { name => "o5", type => $caller_save }, # param 6
- { name => "sp", type => $ignore }, # our stackpointer
- { name => "o7", type => $ignore }, # temp. value / address of CALL instr.
-
- # window's local registers
- { name => "l0", type => 0 },
- { name => "l1", type => 0 },
- { name => "l2", type => 0 },
- { name => "l3", type => 0 },
- { name => "l4", type => 0 },
- { name => "l5", type => 0 },
- { name => "l6", type => 0 },
- { name => "l7", type => 0 },
-
- # window's in registers
- { name => "i0", type => 0 }, # incoming param1 / return value to caller
- { name => "i1", type => 0 }, # param 2
- { name => "i2", type => 0 }, # param 3
- { name => "i3", type => 0 }, # param 4
- { name => "i4", type => 0 }, # param 5
- { name => "i5", type => 0 }, # param 6
- { name => "frame_pointer", realname => "fp", type => $ignore }, # our framepointer
- { name => "i7", type => $ignore }, # return address - 8
+ { name => "g0" },
+ { name => "g1" },
+ { name => "g2" },
+ { name => "g3" },
+ { name => "g4" },
+ { name => "g5" },
+ { name => "g6" },
+ { name => "g7" },
+
+ { name => "o0" },
+ { name => "o1" },
+ { name => "o2" },
+ { name => "o3" },
+ { name => "o4" },
+ { name => "o5" },
+ { name => "sp" },
+ { name => "o7" },
+
+ { name => "l0" },
+ { name => "l1" },
+ { name => "l2" },
+ { name => "l3" },
+ { name => "l4" },
+ { name => "l5" },
+ { name => "l6" },
+ { name => "l7" },
+
+ { name => "i0" },
+ { name => "i1" },
+ { name => "i2" },
+ { name => "i3" },
+ { name => "i4" },
+ { name => "i5" },
+ { name => "frame_pointer", realname => "fp" },
+ { name => "i7" },
{ mode => $mode_gp }
],
fpflags_class => [
- { name => "fpflags", type => $ignore },
+ { name => "fpflags" },
{ mode => $mode_fpflags, flags => "manual_ra" }
],
flags_class => [
- { name => "flags", type => $ignore },
+ { name => "flags" },
{ mode => $mode_flags, flags => "manual_ra" }
],
mul_div_high_res => [
- { name => "y", type => $ignore },
+ { name => "y" },
{ mode => $mode_gp, flags => "manual_ra" }
],
# fp registers can be accessed any time
fp => [
- { name => "f0", type => $caller_save },
- { name => "f1", type => $caller_save },
- { name => "f2", type => $caller_save },
- { name => "f3", type => $caller_save },
- { name => "f4", type => $caller_save },
- { name => "f5", type => $caller_save },
- { name => "f6", type => $caller_save },
- { name => "f7", type => $caller_save },
- { name => "f8", type => $caller_save },
- { name => "f9", type => $caller_save },
- { name => "f10", type => $caller_save },
- { name => "f11", type => $caller_save },
- { name => "f12", type => $caller_save },
- { name => "f13", type => $caller_save },
- { name => "f14", type => $caller_save },
- { name => "f15", type => $caller_save },
- { name => "f16", type => $caller_save },
- { name => "f17", type => $caller_save },
- { name => "f18", type => $caller_save },
- { name => "f19", type => $caller_save },
- { name => "f20", type => $caller_save },
- { name => "f21", type => $caller_save },
- { name => "f22", type => $caller_save },
- { name => "f23", type => $caller_save },
- { name => "f24", type => $caller_save },
- { name => "f25", type => $caller_save },
- { name => "f26", type => $caller_save },
- { name => "f27", type => $caller_save },
- { name => "f28", type => $caller_save },
- { name => "f29", type => $caller_save },
- { name => "f30", type => $caller_save },
- { name => "f31", type => $caller_save },
+ { name => "f0" },
+ { name => "f1" },
+ { name => "f2" },
+ { name => "f3" },
+ { name => "f4" },
+ { name => "f5" },
+ { name => "f6" },
+ { name => "f7" },
+ { name => "f8" },
+ { name => "f9" },
+ { name => "f10" },
+ { name => "f11" },
+ { name => "f12" },
+ { name => "f13" },
+ { name => "f14" },
+ { name => "f15" },
+ { name => "f16" },
+ { name => "f17" },
+ { name => "f18" },
+ { name => "f19" },
+ { name => "f20" },
+ { name => "f21" },
+ { name => "f22" },
+ { name => "f23" },
+ { name => "f24" },
+ { name => "f25" },
+ { name => "f26" },
+ { name => "f27" },
+ { name => "f28" },
+ { name => "f29" },
+ { name => "f30" },
+ { name => "f31" },
{ mode => $mode_fp }
]
); # %reg_classes