Commit e0f19b55 by Iain Sandoe

Implement out-of-line FPR and GPR saves for PPC/Darwin

gcc:

	* config/rs6000/t-darwin (LIB2FUNCS_STATIC_EXTRA): 
	Move darwin-fpsave.asm from here to ... LIB2FUNCS_EXTRA.
	(LIB2FUNCS_EXTRA):  Add darwin-gpsave.asm.
	(TARGET_LIBGCC2_CFLAGS): Ensure that fPIC and -pipe are inherited from
	config/t-darwin.
	* config/rs6000/darwin.h (FP_SAVE_INLINE): Adjust to enable.
	(GP_SAVE_INLINE): Likewise.
	(SAVE_FP_PREFIX,  SAVE_FP_SUFFIX, RESTORE_FP_PREFIX,
	RESTORE_FP_SUFFIX): Set to empty strings.
	* config/rs6000/rs6000.c (rs6000_savres_strategy): Implement for Darwin.
	(debug_stack_info): Print savres_strategy.
	(rs6000_savres_routine_name): Implement for Darwin.
	(rs6000_make_savres_rtx): Adjust used register for Darwin.
	(rs6000_emit_prologue): Implement out-of-line saves for Darwin.
	(rs6000_output_function_prologue): Don't emit .extern for Mach-O.
	(rs6000_emit_epilogue): Implement out-of-line saves for Darwin.
	* config/rs6000/darwin-gpsave.asm: New file.

From-SVN: r180610
parent ee3b466d
2011-10-28 Iain Sandoe <iains@gcc.gnu.org>
* config/rs6000/t-darwin (LIB2FUNCS_STATIC_EXTRA):
Move darwin-fpsave.asm from here to ... LIB2FUNCS_EXTRA.
(LIB2FUNCS_EXTRA): Add darwin-gpsave.asm.
(TARGET_LIBGCC2_CFLAGS): Ensure that fPIC and -pipe are inherited from
config/t-darwin.
* config/rs6000/darwin.h (FP_SAVE_INLINE): Adjust to enable.
(GP_SAVE_INLINE): Likewise.
(SAVE_FP_PREFIX, SAVE_FP_SUFFIX, RESTORE_FP_PREFIX,
RESTORE_FP_SUFFIX): Set to empty strings.
* config/rs6000/rs6000.c (rs6000_savres_strategy): Implement for Darwin.
(debug_stack_info): Print savres_strategy.
(rs6000_savres_routine_name): Implement for Darwin.
(rs6000_make_savres_rtx): Adjust used register for Darwin.
(rs6000_emit_prologue): Implement out-of-line saves for Darwin.
(rs6000_output_function_prologue): Don't emit .extern for Mach-O.
(rs6000_emit_epilogue): Implement out-of-line saves for Darwin.
* config/rs6000/darwin-gpsave.asm: New file.
2011-10-28 Jakub Jelinek <jakub@redhat.com>
* config/i386/sse.md (VI4SD_AVX2): Removed.
/* This file contains the GPR save and restore routines for Darwin.
*
* Copyright (C) 2011 Free Software Foundation, Inc.
*
* This file is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3, or (at your option) any
* later version.
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* Under Section 7 of GPL version 3, you are granted additional
* permissions described in the GCC Runtime Library Exception, version
* 3.1, as published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License and
* a copy of the GCC Runtime Library Exception along with this program;
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
* <http://www.gnu.org/licenses/>.
*/
/* Contributed by Iain Sandoe <iains@gcc.gnu.org> */
/* Like their FP and VEC counterparts, these routines have only one externally
visible entry point. Calls have to be constructed as offsets from this.
(I.E. callers have to jump to "saveGPR+((x-13)*4" to save registers x..31).
Each save/load instruction is 4 bytes long (for both m32 and m64 builds).
The save/restores here are done w.r.t r11.
restGPRx restores the link reg from the stack and returns to the saved
address.
*/
#include "darwin-asm.h"
.text
.align 2
.private_extern saveGPR
saveGPR:
stg r13,(-19 * GPR_BYTES)(r11)
stg r14,(-18 * GPR_BYTES)(r11)
stg r15,(-17 * GPR_BYTES)(r11)
stg r16,(-16 * GPR_BYTES)(r11)
stg r17,(-15 * GPR_BYTES)(r11)
stg r18,(-14 * GPR_BYTES)(r11)
stg r19,(-13 * GPR_BYTES)(r11)
stg r20,(-12 * GPR_BYTES)(r11)
stg r21,(-11 * GPR_BYTES)(r11)
stg r22,(-10 * GPR_BYTES)(r11)
stg r23,( -9 * GPR_BYTES)(r11)
stg r24,( -8 * GPR_BYTES)(r11)
stg r25,( -7 * GPR_BYTES)(r11)
stg r26,( -6 * GPR_BYTES)(r11)
stg r27,( -5 * GPR_BYTES)(r11)
stg r28,( -4 * GPR_BYTES)(r11)
stg r29,( -3 * GPR_BYTES)(r11)
stg r30,( -2 * GPR_BYTES)(r11)
stg r31,( -1 * GPR_BYTES)(r11)
blr
/* */
.private_extern restGPR
restGPR:
lg r13,(-19 * GPR_BYTES)(r11)
lg r14,(-18 * GPR_BYTES)(r11)
lg r15,(-17 * GPR_BYTES)(r11)
lg r16,(-16 * GPR_BYTES)(r11)
lg r17,(-15 * GPR_BYTES)(r11)
lg r18,(-14 * GPR_BYTES)(r11)
lg r19,(-13 * GPR_BYTES)(r11)
lg r20,(-12 * GPR_BYTES)(r11)
lg r21,(-11 * GPR_BYTES)(r11)
lg r22,(-10 * GPR_BYTES)(r11)
lg r23,( -9 * GPR_BYTES)(r11)
lg r24,( -8 * GPR_BYTES)(r11)
lg r25,( -7 * GPR_BYTES)(r11)
lg r26,( -6 * GPR_BYTES)(r11)
lg r27,( -5 * GPR_BYTES)(r11)
lg r28,( -4 * GPR_BYTES)(r11)
lg r29,( -3 * GPR_BYTES)(r11)
lg r30,( -2 * GPR_BYTES)(r11)
lg r31,( -1 * GPR_BYTES)(r11)
blr
.private_extern restGPRx
restGPRx:
lg r13,(-19 * GPR_BYTES)(r11)
lg r14,(-18 * GPR_BYTES)(r11)
lg r15,(-17 * GPR_BYTES)(r11)
lg r16,(-16 * GPR_BYTES)(r11)
lg r17,(-15 * GPR_BYTES)(r11)
lg r18,(-14 * GPR_BYTES)(r11)
lg r19,(-13 * GPR_BYTES)(r11)
lg r20,(-12 * GPR_BYTES)(r11)
lg r21,(-11 * GPR_BYTES)(r11)
lg r22,(-10 * GPR_BYTES)(r11)
lg r23,( -9 * GPR_BYTES)(r11)
lg r24,( -8 * GPR_BYTES)(r11)
lg r25,( -7 * GPR_BYTES)(r11)
lg r26,( -6 * GPR_BYTES)(r11)
lg r27,( -5 * GPR_BYTES)(r11)
lg r28,( -4 * GPR_BYTES)(r11)
lg r29,( -3 * GPR_BYTES)(r11)
/* Like the FP restore, we start from the offset for r30
thus a restore of only r31 is not going to work. */
lg r0,SAVED_LR_OFFSET(r1)
lg r30,( -2 * GPR_BYTES)(r11)
mtlr r0
lg r31,( -1 * GPR_BYTES)(r11)
blr
......@@ -173,18 +173,27 @@ extern int darwin_emit_branch_islands;
(RS6000_ALIGN (crtl->outgoing_args_size, 16) \
+ (STACK_POINTER_OFFSET))
/* Define cutoff for using external functions to save floating point.
Currently on Darwin, always use inline stores. */
/* Define cutoff for using out-of-line functions to save registers.
Currently on Darwin, we implement FP and GPR out-of-line-saves plus the
special routine for 'save everything'. */
#undef FP_SAVE_INLINE
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) > 60 && (FIRST_REG) < 64)
#undef FP_SAVE_INLINE
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64)
#undef GP_SAVE_INLINE
#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32)
#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) > 29 && (FIRST_REG) < 32)
/* Darwin uses a function call if everything needs to be saved/restored. */
#undef WORLD_SAVE_P
#define WORLD_SAVE_P(INFO) ((INFO)->world_save_p)
/* We don't use these on Darwin, they are just place-holders. */
#define SAVE_FP_PREFIX ""
#define SAVE_FP_SUFFIX ""
#define RESTORE_FP_PREFIX ""
#define RESTORE_FP_SUFFIX ""
/* The assembler wants the alternate register names, but without
leading percent sign. */
#undef REGISTER_NAMES
......@@ -234,12 +243,6 @@ extern int darwin_emit_branch_islands;
#undef ASM_COMMENT_START
#define ASM_COMMENT_START ";"
/* FP save and restore routines. */
#define SAVE_FP_PREFIX "._savef"
#define SAVE_FP_SUFFIX ""
#define RESTORE_FP_PREFIX "._restf"
#define RESTORE_FP_SUFFIX ""
/* This is how to output an assembler line that says to advance
the location counter to a multiple of 2**LOG bytes using the
"nop" instruction as padding. */
......
......@@ -17983,9 +17983,11 @@ rs6000_savres_strategy (rs6000_stack_t *info,
/* Don't bother to try to save things out-of-line if r11 is occupied
by the static chain. It would require too much fiddling and the
static chain is rarely used anyway. */
static chain is rarely used anyway. FPRs are saved w.r.t the stack
pointer on Darwin. */
if (using_static_chain_p)
strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
strategy |= (DEFAULT_ABI == ABI_DARWIN ? 0 : SAVE_INLINE_FPRS)
| SAVE_INLINE_GPRS;
/* If we are going to use store multiple, then don't even bother
with the out-of-line routines, since the store-multiple
......@@ -18033,6 +18035,9 @@ rs6000_savres_strategy (rs6000_stack_t *info,
if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
#endif
if (TARGET_MACHO && !(strategy & SAVE_INLINE_FPRS))
strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
return strategy;
}
......@@ -18628,6 +18633,8 @@ debug_stack_info (rs6000_stack_t *info)
if (info->reg_size != 4)
fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
fprintf (stderr, "\tsave-strategy = %04x\n", info->savres_strategy);
fprintf (stderr, "\n");
}
......@@ -19573,10 +19580,25 @@ rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
}
}
else if (DEFAULT_ABI == ABI_DARWIN)
sorry ("out-of-line save/restore routines not supported on Darwin");
sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
if (DEFAULT_ABI == ABI_DARWIN)
{
/* The Darwin approach is (slightly) different, in order to be
compatible with code generated by the system toolchain. There is a
single symbol for the start of save sequence, and the code here
embeds an offset into that code on the basis of the first register
to be saved. */
prefix = savep ? "save" : "rest" ;
if (gpr)
sprintf (savres_routine_name, "*%sGPR%s%s%.0d ; %s r%d-r31",
prefix, (lr ? "x" : ""), (regno == 13 ? "" : "+"),
(regno-13) * 4, prefix, regno);
else
sprintf (savres_routine_name, "*%sFP%s%.0d ; %s f%d-f31",
prefix, (regno == 14 ? "" : "+"), (regno-14) * 4, prefix, regno);
}
else
sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
return savres_routine_name;
}
......@@ -19678,7 +19700,7 @@ rs6000_emit_savres_rtx (rs6000_stack_t *info,
bool savep, bool gpr, bool lr)
{
int i;
int offset, start_reg, end_reg, n_regs;
int offset, start_reg, end_reg, n_regs, use_reg;
int reg_size = GET_MODE_SIZE (reg_mode);
rtx sym;
rtvec p;
......@@ -19700,11 +19722,12 @@ rs6000_emit_savres_rtx (rs6000_stack_t *info,
sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
use_reg = DEFAULT_ABI == ABI_AIX ? (gpr && !lr ? 12 : 1)
: DEFAULT_ABI == ABI_DARWIN && !gpr ? 1
: 11;
RTVEC_ELT (p, offset++)
= gen_rtx_USE (VOIDmode,
gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
: gpr && !lr ? 12
: 1));
gen_rtx_REG (Pmode, use_reg));
for (i = 0; i < end_reg - start_reg; i++)
{
......@@ -20148,8 +20171,21 @@ rs6000_emit_prologue (void)
}
else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
{
if (DEFAULT_ABI == ABI_DARWIN)
{
rtx dest_reg = gen_rtx_REG (reg_mode, 11);
if (info->first_fp_reg_save == 64)
/* we only need a copy, no fprs were saved. */
emit_move_insn (dest_reg, frame_reg_rtx);
else
{
rtx offset = GEN_INT (sp_offset
+ (-8 * (64-info->first_fp_reg_save)));
emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
}
}
/* Need to adjust r11 (r12) if we saved any FPRs. */
if (info->first_fp_reg_save != 64)
else if (info->first_fp_reg_save != 64)
{
rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
? 12 : 11);
......@@ -20515,7 +20551,8 @@ rs6000_output_function_prologue (FILE *file,
/* Write .extern for any function we will call to save and restore
fp values. */
if (info->first_fp_reg_save < 64)
if (info->first_fp_reg_save < 64
&& !TARGET_MACHO)
{
char *name;
int regno = info->first_fp_reg_save - 32;
......@@ -21138,7 +21175,11 @@ rs6000_emit_epilogue (int sibcall)
if (can_use_exit)
{
rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
sp_offset, can_use_exit);
sp_offset, can_use_exit);
if (DEFAULT_ABI == ABI_DARWIN)
/* we only need a copy, no fprs were saved. */
emit_move_insn (gen_rtx_REG (reg_mode, 11), frame_reg_rtx);
if (info->cr_save_p)
rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
}
......
......@@ -19,21 +19,21 @@
LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-tramp.asm \
$(srcdir)/config/darwin-64.c \
$(srcdir)/config/rs6000/darwin-fpsave.asm \
$(srcdir)/config/rs6000/darwin-gpsave.asm \
$(srcdir)/config/rs6000/darwin-world.asm
LIB2FUNCS_STATIC_EXTRA = \
$(srcdir)/config/rs6000/darwin-fpsave.asm \
$(srcdir)/config/rs6000/darwin-vecsave.asm
# The .asm files above are designed to run on all processors,
# even though they use AltiVec instructions. -Wa is used because
# -force_cpusubtype_ALL doesn't work with -dynamiclib.
#
# -pipe because there's an assembler bug, 4077127, which causes
# it to not properly process the first # directive, causing temporary
# file names to appear in stabs, causing the bootstrap to fail. Using -pipe
# works around this by not having any temporary file names.
TARGET_LIBGCC2_CFLAGS = -Wa,-force_cpusubtype_ALL -pipe -mmacosx-version-min=10.4
# The .asm files above are designed to run on all processors, even though
# they use AltiVec instructions.
# -Wa is used because -force_cpusubtype_ALL doesn't work with -dynamiclib.
# -mmacosx-version-min=10.4 is used to provide compatibility for code from
# earlier OSX versions.
TARGET_LIBGCC2_CFLAGS += -Wa,-force_cpusubtype_ALL -mmacosx-version-min=10.4
darwin-fpsave.o: $(srcdir)/config/rs6000/darwin-asm.h
darwin-gpsave.o: $(srcdir)/config/rs6000/darwin-asm.h
darwin-tramp.o: $(srcdir)/config/rs6000/darwin-asm.h
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment