* [Patch Darwin/PPC] implement out-of-line FPR/GPR saves/restores.
@ 2011-10-14 9:47 Iain Sandoe
2011-10-14 10:00 ` Mike Stump
0 siblings, 1 reply; 4+ messages in thread
From: Iain Sandoe @ 2011-10-14 9:47 UTC (permalink / raw)
To: GCC Patches; +Cc: Mike Stump
[-- Attachment #1: Type: text/plain, Size: 1368 bytes --]
we've been building the FPR routines for ages (for compatibility with
system tools)..
This implements their use and also the GPRs - the latter makes an
appreciable reduction in code size,
the former is neutral for non-fp intensive code but, for example,
makes an appreciable reduction to the size of gnat1.
this has been around my local tree for quite a few bootstrap/regtest
cycles (incl. Ada and Java).
OK for trunk?
Iain
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): Do not emit .extern for Mach-O
targets.
(rs6000_emit_epilogue): Implement out-of-line saves for Darwin.
* config/rs6000/darwin-gpsave.asm: New file.
[-- Attachment #2: 179962-ppc-ools-diff.txt --]
[-- Type: text/plain, Size: 12684 bytes --]
Index: gcc/config/rs6000/t-darwin
===================================================================
--- gcc/config/rs6000/t-darwin (revision 179962)
+++ gcc/config/rs6000/t-darwin (working copy)
@@ -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
Index: gcc/config/rs6000/darwin.h
===================================================================
--- gcc/config/rs6000/darwin.h (revision 179962)
+++ gcc/config/rs6000/darwin.h (working copy)
@@ -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) < 64)
+#undef FP_SAVE_INLINE
+#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) > 60 && (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. */
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 179962)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -18047,9 +18047,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
@@ -18097,6 +18099,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;
}
@@ -18692,6 +18697,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");
}
@@ -19637,10 +19644,25 @@ rs6000_savres_routine_name (rs6000_stack_t *info,
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;
}
@@ -19739,7 +19761,7 @@ rs6000_make_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;
@@ -19760,11 +19782,12 @@ rs6000_make_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++)
{
@@ -20207,8 +20230,21 @@ rs6000_emit_prologue (void)
{
rtx par;
+ 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);
@@ -20575,7 +20611,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;
@@ -21186,8 +21223,13 @@ rs6000_emit_epilogue (int sibcall)
/* Emit stack reset code if we need it. */
if (can_use_exit)
- rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
+ {
+ rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
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);
+ }
else
{
emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
Index: gcc/config/rs6000/darwin-gpsave.asm
===================================================================
--- gcc/config/rs6000/darwin-gpsave.asm (revision 0)
+++ gcc/config/rs6000/darwin-gpsave.asm (revision 0)
@@ -0,0 +1,118 @@
+/* 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
[-- Attachment #3: Type: text/plain, Size: 3 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch Darwin/PPC] implement out-of-line FPR/GPR saves/restores.
2011-10-14 9:47 [Patch Darwin/PPC] implement out-of-line FPR/GPR saves/restores Iain Sandoe
@ 2011-10-14 10:00 ` Mike Stump
2011-10-28 11:04 ` Iain Sandoe
0 siblings, 1 reply; 4+ messages in thread
From: Mike Stump @ 2011-10-14 10:00 UTC (permalink / raw)
To: Iain Sandoe; +Cc: GCC Patches, Mike Stump
On Oct 14, 2011, at 2:05 AM, Iain Sandoe wrote:
> This implements their use and also the GPRs - the latter makes an appreciable reduction in code size,
> OK for trunk?
Ok. Watch for problems with async stack walking (hitting sample in Activity Monitor, or the walking done by CrashReporter)... that's the only thing I can think of that might be strange.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch Darwin/PPC] implement out-of-line FPR/GPR saves/restores.
2011-10-14 10:00 ` Mike Stump
@ 2011-10-28 11:04 ` Iain Sandoe
2011-10-28 19:24 ` Mike Stump
0 siblings, 1 reply; 4+ messages in thread
From: Iain Sandoe @ 2011-10-28 11:04 UTC (permalink / raw)
To: Mike Stump; +Cc: GCC Patches, David Edelsohn
[-- Attachment #1: Type: text/plain, Size: 1478 bytes --]
On 14 Oct 2011, at 10:29, Mike Stump wrote:
> On Oct 14, 2011, at 2:05 AM, Iain Sandoe wrote:
>> This implements their use and also the GPRs - the latter makes an
>> appreciable reduction in code size,
>
>> OK for trunk?
>
> Ok. Watch for problems with async stack walking (hitting sample in
> Activity Monitor, or the walking done by CrashReporter)... that's
> the only thing I can think of that might be strange.
This has taken some time to apply because of various bootstrap issues
(version applied is attached)
In answer to your observation;
I didn't expect problems with FPR saves because the vendor's tools
implement those.
To test what you suggested I built some code that dropped down a few
stack levels (with saves of FPR/GPR) and then either aborts or spins
on a sleep.
The crashlogs from the abort() and the instrumentation samples from
the sleep were OK.
====
During doing this (and checking crosses to aix and eabisim) I noticed
the following in rs6000/sysv4.h:
/* And similarly for general purpose registers. */
#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32 \
&& !optimize_size)
which gives rise to code (with -Os) like:
main:
mr 11,1 #,
stwu 1,-504(1) #,,
mflr 0 #,
bl _savegpr_31 #
lis 31,.LANCHOR0@ha # tmp137,
which I doubt is what was intended ....
... copying David in case he feels that should be amended.
cheers
Iain
[-- Attachment #2: 180609-darwinppc-ools-diff.txt --]
[-- Type: text/plain, Size: 13899 bytes --]
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog (revision 180609)
+++ gcc/ChangeLog (working copy)
@@ -1,3 +1,23 @@
+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.
Index: gcc/config/rs6000/t-darwin
===================================================================
--- gcc/config/rs6000/t-darwin (revision 180609)
+++ gcc/config/rs6000/t-darwin (working copy)
@@ -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
Index: gcc/config/rs6000/darwin.h
===================================================================
--- gcc/config/rs6000/darwin.h (revision 180609)
+++ gcc/config/rs6000/darwin.h (working copy)
@@ -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) < 64)
+#undef FP_SAVE_INLINE
+#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) > 60 && (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. */
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 180609)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -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,
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);
}
Index: gcc/config/rs6000/darwin-gpsave.asm
===================================================================
--- gcc/config/rs6000/darwin-gpsave.asm (revision 0)
+++ gcc/config/rs6000/darwin-gpsave.asm (revision 0)
@@ -0,0 +1,118 @@
+/* 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
[-- Attachment #3: Type: text/plain, Size: 3 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch Darwin/PPC] implement out-of-line FPR/GPR saves/restores.
2011-10-28 11:04 ` Iain Sandoe
@ 2011-10-28 19:24 ` Mike Stump
0 siblings, 0 replies; 4+ messages in thread
From: Mike Stump @ 2011-10-28 19:24 UTC (permalink / raw)
To: Iain Sandoe; +Cc: Mike Stump, GCC Patches, David Edelsohn
On Oct 28, 2011, at 3:40 AM, Iain Sandoe wrote:
> To test what you suggested I built some code that dropped down a few stack levels (with saves of FPR/GPR) and then either aborts or spins on a sleep.
Uhm, that's not enough, for async, you need to spawn threads that do the interesting stuff in those threads and then have the main code abort.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-10-28 18:48 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-14 9:47 [Patch Darwin/PPC] implement out-of-line FPR/GPR saves/restores Iain Sandoe
2011-10-14 10:00 ` Mike Stump
2011-10-28 11:04 ` Iain Sandoe
2011-10-28 19:24 ` Mike Stump
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).