From: Paul Brook Date: Wed, 11 Aug 2004 21:02:47 +0000 (+0000) Subject: * config/arm/arm-protos.h (arm_finalize_pic) Rename ... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=876f13b0bef8cb388df2fc1781dc7575590fc6b5;p=gcc.git * config/arm/arm-protos.h (arm_finalize_pic) Rename ... (arm_load_pic_register): ... to this. * config/arm/arm.c (arm_finalize_pic): Rename ... (arm_load_pic_register): ... to this. Always output insns at the current location. Load via low reg in thumb mode. (arm_expand_prologue): Call arm_load_pic_register. (thumb_expand_prologue): Ditto. * config/arm/arm.h (FINALIZE_PIC): Remove. * config/arm/arm.md (builtin_setjmp_receiver): Call arm_load_pic_register. From-SVN: r85820 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 55ceca11af7..b3aa2f3cf07 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2004-08-11 Paul Brook + + * config/arm/arm-protos.h (arm_finalize_pic) Rename ... + (arm_load_pic_register): ... to this. + * config/arm/arm.c (arm_finalize_pic): Rename ... + (arm_load_pic_register): ... to this. Always output insns at the + current location. Load via low reg in thumb mode. + (arm_expand_prologue): Call arm_load_pic_register. + (thumb_expand_prologue): Ditto. + * config/arm/arm.h (FINALIZE_PIC): Remove. + * config/arm/arm.md (builtin_setjmp_receiver): Call + arm_load_pic_register. + 2004-08-11 Paul Brook * arm.c (thumb_force_lr_save): Add prototype. diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 2f361cd6362..b6b2fc4d816 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -27,7 +27,7 @@ extern void arm_override_options (void); extern int use_return_insn (int, rtx); extern int arm_regno_class (int); -extern void arm_finalize_pic (int); +extern void arm_load_pic_register (void); extern int arm_volatile_func (void); extern const char *arm_output_epilogue (rtx); extern void arm_expand_prologue (void); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 41c27efa911..8493af03227 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3012,16 +3012,14 @@ thumb_find_work_register (int live_regs_mask) abort (); } -/* Generate code to load the PIC register. PROLOGUE is true if - called from arm_expand_prologue (in which case we want the - generated insns at the start of the function); false if called - by an exception receiver that needs the PIC register reloaded - (in which case the insns are just dumped at the current location). */ + +/* Generate code to load the PIC register. */ + void -arm_finalize_pic (int prologue ATTRIBUTE_UNUSED) +arm_load_pic_register (void) { #ifndef AOF_ASSEMBLER - rtx l1, pic_tmp, pic_tmp2, seq, pic_rtx; + rtx l1, pic_tmp, pic_tmp2, pic_rtx; rtx global_offset_table; if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE) @@ -3030,7 +3028,6 @@ arm_finalize_pic (int prologue ATTRIBUTE_UNUSED) if (!flag_pic) abort (); - start_sequence (); l1 = gen_label_rtx (); global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); @@ -3052,23 +3049,29 @@ arm_finalize_pic (int prologue ATTRIBUTE_UNUSED) } else { - emit_insn (gen_pic_load_addr_thumb (pic_offset_table_rtx, pic_rtx)); + if (REGNO (pic_offset_table_rtx) > LAST_LO_REGNUM) + { + int reg; + + /* We will have pushed the pic register, so should always be + able to find a work register. */ + reg = thumb_find_work_register (thumb_compute_save_reg_mask ()); + pic_tmp = gen_rtx_REG (SImode, reg); + emit_insn (gen_pic_load_addr_thumb (pic_tmp, pic_rtx)); + emit_insn (gen_movsi (pic_offset_table_rtx, pic_tmp)); + } + else + emit_insn (gen_pic_load_addr_thumb (pic_offset_table_rtx, pic_rtx)); emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx, l1)); } - seq = get_insns (); - end_sequence (); - if (prologue) - emit_insn_after (seq, get_insns ()); - else - emit_insn (seq); - /* Need to emit this whether or not we obey regdecls, since setjmp/longjmp can cause life info to screw up. */ emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx)); #endif /* AOF_ASSEMBLER */ } + /* Return nonzero if X is valid as an ARM state addressing register. */ static int arm_address_register_rtx_p (rtx x, int strict_p) @@ -10693,6 +10696,10 @@ arm_expand_prologue (void) hard_frame_pointer_rtx)); } + + if (flag_pic) + arm_load_pic_register (); + /* If we are profiling, make sure no instructions are scheduled before the call to mcount. Similarly if the user has requested no scheduling in the prolog. */ @@ -13357,6 +13364,11 @@ thumb_expand_prologue (void) return; } + /* Load the pic recister before setting the frame pointer, so we can use r7 + as a temporary work register. */ + if (flag_pic) + arm_load_pic_register (); + offsets = arm_get_frame_offsets (); if (frame_pointer_needed) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index c3ea52a70e8..ec924105e1a 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -2277,8 +2277,6 @@ extern const char * arm_pic_register_string; data addresses in memory. */ #define PIC_OFFSET_TABLE_REGNUM arm_pic_register -#define FINALIZE_PIC arm_finalize_pic (1) - /* We can't directly access anything that contains a symbol, nor can we indirect via the constant pool. */ #define LEGITIMATE_PIC_OPERAND_P(X) \ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 88aea277686..f19f8cd4ebe 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4462,7 +4462,7 @@ "flag_pic" " { - arm_finalize_pic (0); + arm_load_pic_register (); DONE; }")