From: Matthias Braun Date: Fri, 8 Oct 2010 14:02:22 +0000 (+0000) Subject: make sparc+arm backend completely independent from beabi X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=8a1c0ad68eaba7cecab7a3abd552681ad893de3e;p=libfirm make sparc+arm backend completely independent from beabi [r28073] --- diff --git a/ir/be/arm/arm_spec.pl b/ir/be/arm/arm_spec.pl index 18a3a0523..f4746d44c 100644 --- a/ir/be/arm/arm_spec.pl +++ b/ir/be/arm/arm_spec.pl @@ -12,48 +12,40 @@ $mode_gp = "mode_Iu"; $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" } ], ); @@ -426,7 +418,8 @@ SwitchJmp => { 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", }, diff --git a/ir/be/bechordal.c b/ir/be/bechordal.c index 26f76f1f5..e92f1d333 100644 --- a/ir/be/bechordal.c +++ b/ir/be/bechordal.c @@ -342,7 +342,6 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, 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) { @@ -502,7 +501,6 @@ static void assign(ir_node *block, void *env_ptr) 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); @@ -520,11 +518,6 @@ static void assign(ir_node *block, void *env_ptr) 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); diff --git a/ir/be/becopyopt.c b/ir/be/becopyopt.c index cde32cd8d..4b9fcc754 100644 --- a/ir/be/becopyopt.c +++ b/ir/be/becopyopt.c @@ -228,15 +228,10 @@ void free_copy_opt(copy_opt_t *co) 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; @@ -805,7 +800,6 @@ static void build_graph_walker(ir_node *irn, void *env) 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; @@ -813,10 +807,6 @@ static void build_graph_walker(ir_node *irn, void *env) 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); poscenv->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; @@ -908,7 +900,11 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f) 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; + } } /* diff --git a/ir/be/bedump_minir.c b/ir/be/bedump_minir.c index 906ea7cf8..0809a98ee 100644 --- a/ir/be/bedump_minir.c +++ b/ir/be/bedump_minir.c @@ -243,6 +243,7 @@ static void print_regclasses(void) } 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); @@ -255,6 +256,7 @@ static void print_regclasses(void) } } end_block_mapping("flags"); +#endif end_block_mapping(NULL); } diff --git a/ir/be/benode.c b/ir/be/benode.c index 87c0b8473..b3bbb13c4 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -874,10 +874,12 @@ void be_set_constr_single_reg_in(ir_node *node, int pos, 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; } diff --git a/ir/be/bespill.c b/ir/be/bespill.c index de71ea8f6..2e54f4ed3 100644 --- a/ir/be/bespill.c +++ b/ir/be/bespill.c @@ -59,6 +59,7 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node) 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; @@ -70,15 +71,14 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node) * 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); @@ -88,7 +88,7 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node) /* 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)) @@ -100,7 +100,8 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node) 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. */ diff --git a/ir/be/bestack.c b/ir/be/bestack.c index d63e7dc61..14fa99030 100644 --- a/ir/be/bestack.c +++ b/ir/be/bestack.c @@ -305,6 +305,7 @@ void be_abi_fix_stack_nodes(ir_graph *irg) 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; @@ -322,9 +323,10 @@ void be_abi_fix_stack_nodes(ir_graph *irg) 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; } diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 0d5d57300..d233e0278 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -819,13 +819,14 @@ static void peephole_Load_IncSP_to_pop(ir_node *irn) /** * 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) @@ -907,7 +908,7 @@ static void peephole_be_IncSP(ir_node *node) 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; @@ -1196,7 +1197,7 @@ static void peephole_ia32_Imul_split(ir_node *imul) return; } /* we need a free register */ - reg = get_free_gp_reg(); + reg = get_free_gp_reg(get_irn_irg(imul)); if (reg == NULL) return; diff --git a/ir/be/scripts/generate_regalloc_if.pl b/ir/be/scripts/generate_regalloc_if.pl index 87714c936..50ebc6647 100755 --- a/ir/be/scripts/generate_regalloc_if.pl +++ b/ir/be/scripts/generate_regalloc_if.pl @@ -208,9 +208,10 @@ EOF $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}; diff --git a/ir/be/sparc/sparc_spec.pl b/ir/be/sparc/sparc_spec.pl index d7d78e7f3..41330e88a 100644 --- a/ir/be/sparc/sparc_spec.pl +++ b/ir/be/sparc/sparc_spec.pl @@ -10,103 +10,92 @@ $mode_fp = "mode_F"; $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