Here is the patch to build arm-elf target with simulator. It has been committed to the branch.
2011-06-01 Vladimir Makarov <vmaka...@redhat.com> * lra-eliminations.c (lra_eliminate_reg_if_possible): Fix a typo. (process_insn_for_elimination): Invalidate insn data if the insn code was changed. * lra-constraints.c (check_and_process_move): Set up temporarily reg_renumber for secondary_reload hook. (process_addr_reg): Use class of elimination. (curr_insn_transform): Remove subreg before address processing.
Index: lra-eliminations.c =================================================================== --- lra-eliminations.c (revision 174485) +++ lra-eliminations.c (working copy) @@ -1266,7 +1266,7 @@ lra_eliminate_reg_if_possible (rtx *loc) struct elim_table *ep; gcc_assert (REG_P (*loc)); - if ((regno = REG_P (*loc)) >= FIRST_PSEUDO_REGISTER + if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER /* Virtual registers are not allocatable. ??? */ || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)) return; @@ -1282,6 +1282,16 @@ process_insn_for_elimination (rtx insn, eliminate_regs_in_insn (insn, final_p); if (! final_p) { + /* Check that insn changed its code. This is a case when a move + insn becomes an add insn and we do not want to process the + insn as a move anymore. */ + int icode = recog (PATTERN (insn), insn, 0); + + if (icode >= 0 && icode != INSN_CODE (insn)) + { + INSN_CODE (insn) = icode; + lra_update_insn_recog_data (insn); + } lra_update_insn_regno_info (insn); lra_push_insn (insn); lra_set_used_insn_alternative (insn, -1); Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 174485) +++ lra-constraints.c (working copy) @@ -902,10 +902,11 @@ reg_class_from_constraints (const char * static bool check_and_process_move (bool *change_p) { + int regno; rtx set, dest, src, dreg, sr, dr, sreg, new_reg, before, x, scratch_reg; - enum reg_class dclass, sclass, rclass, secondary_class; + enum reg_class dclass, sclass, xclass, rclass, secondary_class; secondary_reload_info sri; - bool in_p; + bool in_p, temp_assign_p; *change_p = false; if ((set = single_set (curr_insn)) == NULL || side_effects_p (set)) @@ -981,18 +982,34 @@ check_and_process_move (bool *change_p) in_p = true; rclass = dclass; x = sreg; + xclass = sclass; } else if (sclass != NO_REGS) { in_p = false; rclass = sclass; x = dreg; + xclass = dclass; } else return false; + temp_assign_p = false; + /* Set up hard register for a reload pseudo for hook + secondary_reload because some targets just ignore pseudos in the + hook. */ + if (xclass != NO_REGS + && REG_P (x) && (regno = REGNO (x)) >= new_regno_start + && ! bitmap_bit_p (&lra_inheritance_pseudos, regno) + && lra_get_regno_hard_regno (regno) < 0) + { + reg_renumber[regno] = ira_class_hard_regs[xclass][0]; + temp_assign_p = true; + } secondary_class = (enum reg_class) targetm.secondary_reload (in_p, x, (reg_class_t) rclass, GET_MODE (src), &sri); + if (temp_assign_p) + reg_renumber [REGNO (x)] = -1; if (secondary_class == NO_REGS && sri.icode == CODE_FOR_nothing) return false; *change_p = true; @@ -1090,7 +1107,7 @@ static int curr_swapped; static bool process_addr_reg (rtx *loc, rtx *before, rtx *after, enum reg_class cl) { - int regno; + int regno, final_regno; enum reg_class rclass, new_class; rtx reg = *loc; rtx new_reg; @@ -1098,8 +1115,19 @@ process_addr_reg (rtx *loc, rtx *before, bool change_p = false; gcc_assert (REG_P (reg)); - regno = REGNO (reg); - rclass = get_reg_class (regno); + final_regno = regno = REGNO (reg); + if (regno < FIRST_PSEUDO_REGISTER) + { + rtx final_reg = reg; + rtx *final_loc = &final_reg; + + lra_eliminate_reg_if_possible (final_loc); + final_regno = REGNO (*final_loc); + } + /* Use class of hard register after elimination because some targets + do not recognize virtual hard registers as valid address + registers. */ + rclass = get_reg_class (final_regno); if ((*loc = get_equiv_substitution (reg)) != reg) { if (lra_dump_file != NULL) @@ -1113,7 +1141,7 @@ process_addr_reg (rtx *loc, rtx *before, *loc = copy_rtx (*loc); change_p = true; } - if (*loc != reg || ! in_class_p (regno, cl, &new_class)) + if (*loc != reg || ! in_class_p (final_regno, cl, &new_class)) { mode = GET_MODE (reg); reg = *loc; @@ -2629,16 +2657,9 @@ curr_insn_transform (void) curr_swapped = false; goal_alternative_swapped = false; - /* Reload address registers and displacements. We do it before - finding an alternative because of memory constraints. */ - before = after = NULL_RTX; - for (i = 0; i < n_operands; i++) - if (process_address (i, &before, &after)) - { - change_p = true; - lra_update_dups (curr_id, i, -1); - } - + /* Make equivalence substitution and memory subreg elimination + before address processing because an address legitimacy can + depend on memory mode. */ for (i = 0; i < n_operands; i++) { rtx op = *curr_id->operand_loc[i]; @@ -2665,15 +2686,6 @@ curr_insn_transform (void) fprintf (lra_dump_file, "\n"); } op_change_p = change_p = true; - if (GET_CODE (subst) == MEM) - { - if (GET_CODE (op) == SUBREG) - /* Do memory subreg simplification before processing - address because it might change the address - displacement and make the address illegitimate. */ - simplify_operand_subreg (i, GET_MODE (old)); - process_address (i, &before, &after); - } } if (simplify_operand_subreg (i, GET_MODE (old)) || op_change_p) { @@ -2682,6 +2694,16 @@ curr_insn_transform (void) } } + /* Reload address registers and displacements. We do it before + finding an alternative because of memory constraints. */ + before = after = NULL_RTX; + for (i = 0; i < n_operands; i++) + if (process_address (i, &before, &after)) + { + change_p = true; + lra_update_dups (curr_id, i, -1); + } + try_swapped: reused_alternative_num = curr_id->used_insn_alternative;