diff options
Diffstat (limited to 'gcc-4.6/gcc/config/rs6000/rs6000.c')
-rw-r--r-- | gcc-4.6/gcc/config/rs6000/rs6000.c | 164 |
1 files changed, 81 insertions, 83 deletions
diff --git a/gcc-4.6/gcc/config/rs6000/rs6000.c b/gcc-4.6/gcc/config/rs6000/rs6000.c index d7407fa..ae0cc17 100644 --- a/gcc-4.6/gcc/config/rs6000/rs6000.c +++ b/gcc-4.6/gcc/config/rs6000/rs6000.c @@ -2612,6 +2612,7 @@ darwin_rs6000_override_options (void) off. */ rs6000_altivec_abi = 1; TARGET_ALTIVEC_VRSAVE = 1; + rs6000_current_abi = ABI_DARWIN; if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT) @@ -6824,6 +6825,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, #if TARGET_MACHO && DEFAULT_ABI == ABI_DARWIN && (flag_pic || MACHO_DYNAMIC_NO_PIC_P) + && machopic_symbol_defined_p (x) #else && DEFAULT_ABI == ABI_V4 && !flag_pic @@ -16613,7 +16615,7 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p) if (TARGET_RELOCATABLE && in_section != toc_section && in_section != text_section - && !unlikely_text_section_p (in_section) + && (in_section && (in_section->common.flags & SECTION_CODE)) == 0 && !recurse && GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_DOUBLE @@ -18498,7 +18500,7 @@ compute_save_world_info (rs6000_stack_t *info_ptr) info_ptr->world_save_p = (WORLD_SAVE_P (info_ptr) && DEFAULT_ABI == ABI_DARWIN - && ! (cfun->calls_setjmp && flag_exceptions) + && !cfun->has_nonlocal_label && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO @@ -19838,7 +19840,8 @@ output_probe_stack_range (rtx reg1, rtx reg2) output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops); /* Probe at TEST_ADDR and branch. */ - output_asm_insn ("{st|stw} 0,0(%0)", xops); + xops[1] = gen_rtx_REG (Pmode, 0); + output_asm_insn ("{st|stw} %1,0(%0)", xops); fprintf (asm_out_file, "\tb "); assemble_name_raw (asm_out_file, loop_lab); fputc ('\n', asm_out_file); @@ -20226,7 +20229,7 @@ rs6000_emit_stack_reset (rs6000_stack_t *info, { /* This blockage is needed so that sched doesn't decide to move the sp change before the register restores. */ - if (frame_reg_rtx != sp_reg_rtx + if (DEFAULT_ABI == ABI_V4 || (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0 && info->first_gp_reg_save != 32)) @@ -20643,56 +20646,52 @@ rs6000_emit_prologue (void) { int i; rtx spe_save_area_ptr; - + int save_ptr_to_sp; + int ool_adjust = 0; + /* Determine whether we can address all of the registers that need - to be saved with an offset from the stack pointer that fits in + to be saved with an offset from frame_reg_rtx that fits in the small const field for SPE memory instructions. */ - int spe_regs_addressable_via_sp - = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset - + (32 - info->first_gp_reg_save - 1) * reg_size) + int spe_regs_addressable + = (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + sp_offset + + reg_size * (32 - info->first_gp_reg_save - 1)) && saving_GPRs_inline); int spe_offset; - - if (spe_regs_addressable_via_sp) + + if (spe_regs_addressable) { spe_save_area_ptr = frame_reg_rtx; + save_ptr_to_sp = info->total_size - sp_offset; spe_offset = info->spe_gp_save_offset + sp_offset; } else { /* Make r11 point to the start of the SPE save area. We need to be careful here if r11 is holding the static chain. If - it is, then temporarily save it in r0. We would use r0 as - our base register here, but using r0 as a base register in - loads and stores means something different from what we - would like. */ - int ool_adjust = (saving_GPRs_inline - ? 0 - : (info->first_gp_reg_save - - (FIRST_SAVRES_REGISTER+1))*8); - HOST_WIDE_INT offset = (info->spe_gp_save_offset - + sp_offset - ool_adjust); + it is, then temporarily save it in r0. */ + int offset; + + if (!saving_GPRs_inline) + ool_adjust = 8 * (info->first_gp_reg_save + - (FIRST_SAVRES_REGISTER + 1)); + offset = info->spe_gp_save_offset + sp_offset - ool_adjust; + spe_save_area_ptr = gen_rtx_REG (Pmode, 11); + save_ptr_to_sp = info->total_size - sp_offset + offset; + spe_offset = 0; if (using_static_chain_p) { rtx r0 = gen_rtx_REG (Pmode, 0); gcc_assert (info->first_gp_reg_save > 11); - - emit_move_insn (r0, gen_rtx_REG (Pmode, 11)); + + emit_move_insn (r0, spe_save_area_ptr); } - - spe_save_area_ptr = gen_rtx_REG (Pmode, 11); - insn = emit_insn (gen_addsi3 (spe_save_area_ptr, - frame_reg_rtx, - GEN_INT (offset))); - /* We need to make sure the move to r11 gets noted for - properly outputting unwind information. */ - if (!saving_GPRs_inline) - rs6000_frame_related (insn, frame_reg_rtx, offset, - NULL_RTX, NULL_RTX); - spe_offset = 0; + emit_insn (gen_addsi3 (spe_save_area_ptr, + frame_reg_rtx, GEN_INT (offset))); + if (REGNO (frame_reg_rtx) == 11) + sp_offset = -info->spe_gp_save_offset + ool_adjust; } - + if (saving_GPRs_inline) { for (i = 0; i < 32 - info->first_gp_reg_save; i++) @@ -20704,36 +20703,34 @@ rs6000_emit_prologue (void) /* We're doing all this to ensure that the offset fits into the immediate offset of 'evstdd'. */ gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset)); - + offset = GEN_INT (reg_size * i + spe_offset); addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset); mem = gen_rtx_MEM (V2SImode, addr); - + insn = emit_move_insn (mem, reg); - - rs6000_frame_related (insn, spe_save_area_ptr, - info->spe_gp_save_offset - + sp_offset + reg_size * i, - offset, const0_rtx); + + rs6000_frame_related (insn, + spe_save_area_ptr, save_ptr_to_sp, + NULL_RTX, NULL_RTX); } } else { rtx par; - par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), - 0, reg_mode, + par = rs6000_make_savres_rtx (info, spe_save_area_ptr, + ool_adjust, reg_mode, /*savep=*/true, /*gpr=*/true, /*lr=*/false); insn = emit_insn (par); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + rs6000_frame_related (insn, spe_save_area_ptr, save_ptr_to_sp, NULL_RTX, NULL_RTX); } - - + /* Move the static chain pointer back. */ - if (using_static_chain_p && !spe_regs_addressable_via_sp) - emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0)); + if (using_static_chain_p && !spe_regs_addressable) + emit_move_insn (spe_save_area_ptr, gen_rtx_REG (Pmode, 0)); } else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline) { @@ -20742,10 +20739,12 @@ rs6000_emit_prologue (void) /* Need to adjust r11 (r12) if we saved any FPRs. */ if (info->first_fp_reg_save != 64) { - rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX - ? 12 : 11); - rtx offset = GEN_INT (sp_offset - + (-8 * (64-info->first_fp_reg_save))); + rtx dest_reg = gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX ? 12 : 11); + int save_off = 8 * (64 - info->first_fp_reg_save); + rtx offset = GEN_INT (sp_offset - save_off); + + if (REGNO (dest_reg) == REGNO (frame_reg_rtx)) + sp_offset = save_off; emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset)); } @@ -21621,40 +21620,39 @@ rs6000_emit_epilogue (int sibcall) && info->first_gp_reg_save != 32) { /* Determine whether we can address all of the registers that need - to be saved with an offset from the stack pointer that fits in - the small const field for SPE memory instructions. */ - int spe_regs_addressable_via_sp - = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset - + (32 - info->first_gp_reg_save - 1) * reg_size) + to be saved with an offset from frame_reg_rtx that fits in + the small const field for SPE memory instructions. */ + int spe_regs_addressable + = (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + sp_offset + + reg_size * (32 - info->first_gp_reg_save - 1)) && restoring_GPRs_inline); int spe_offset; + int ool_adjust = 0; - if (spe_regs_addressable_via_sp) + if (spe_regs_addressable) spe_offset = info->spe_gp_save_offset + sp_offset; else - { + { rtx old_frame_reg_rtx = frame_reg_rtx; - /* Make r11 point to the start of the SPE save area. We worried about - not clobbering it when we were saving registers in the prologue. - There's no need to worry here because the static chain is passed - anew to every function. */ - int ool_adjust = (restoring_GPRs_inline - ? 0 - : (info->first_gp_reg_save - - (FIRST_SAVRES_REGISTER+1))*8); - - if (frame_reg_rtx == sp_reg_rtx) - frame_reg_rtx = gen_rtx_REG (Pmode, 11); - emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx, + /* Make r11 point to the start of the SPE save area. We worried about + not clobbering it when we were saving registers in the prologue. + There's no need to worry here because the static chain is passed + anew to every function. */ + + if (!restoring_GPRs_inline) + ool_adjust = 8 * (info->first_gp_reg_save + - (FIRST_SAVRES_REGISTER + 1)); + frame_reg_rtx = gen_rtx_REG (Pmode, 11); + emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx, GEN_INT (info->spe_gp_save_offset + sp_offset - ool_adjust))); /* Keep the invariant that frame_reg_rtx + sp_offset points at the top of the stack frame. */ - sp_offset = -info->spe_gp_save_offset; + sp_offset = -info->spe_gp_save_offset + ool_adjust; - spe_offset = 0; - } + spe_offset = 0; + } if (restoring_GPRs_inline) { @@ -21694,8 +21692,8 @@ rs6000_emit_epilogue (int sibcall) { rtx par; - par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), - 0, reg_mode, + par = rs6000_make_savres_rtx (info, frame_reg_rtx, + ool_adjust, reg_mode, /*savep=*/false, /*gpr=*/true, /*lr=*/true); emit_jump_insn (par); @@ -21716,12 +21714,12 @@ rs6000_emit_epilogue (int sibcall) sp_offset, can_use_exit); else { - emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX - ? 12 : 11), - frame_reg_rtx, + rtx src_reg = gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX ? 12 : 11); + + emit_insn (gen_add3_insn (src_reg, frame_reg_rtx, GEN_INT (sp_offset - info->fp_size))); - if (REGNO (frame_reg_rtx) == 11) - sp_offset += info->fp_size; + if (REGNO (frame_reg_rtx) == REGNO (src_reg)) + sp_offset = info->fp_size; } par = rs6000_make_savres_rtx (info, frame_reg_rtx, @@ -27762,7 +27760,7 @@ rs6000_inner_target_options (tree args, bool attr_p) if (strcmp (r, rs6000_opt_vars[i].name) == 0) { size_t j = rs6000_opt_vars[i].global_offset; - ((int *) &global_options)[j] = !invert; + *((int *) ((char *)&global_options + j)) = !invert; error_p = false; break; } |