From: amodra Date: Fri, 15 Feb 2013 13:53:40 +0000 (+0000) Subject: PR target/55431 X-Git-Url: https://repo.or.cz/w/official-gcc.git/commitdiff_plain/2a0bfd56d1b6a8ece8fb852691ea32713c7891b3 PR target/55431 * config/rs6000/linux-unwind.h (ppc_linux_aux_vector): Delete. (ppc_fallback_frame_state): Always set up save locations for fp and altivec. Don't bother with non-callee-saved regs, r0-r13 except for r2 on ppc64, fr0-fr13, v0-v19, vscr. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@196077 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index e484e048432..d4bc8109e7d 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,11 @@ +2013-02-16 Alan Modra + + PR target/55431 + * config/rs6000/linux-unwind.h (ppc_linux_aux_vector): Delete. + (ppc_fallback_frame_state): Always set up save locations for fp + and altivec. Don't bother with non-callee-saved regs, r0-r13 + except for r2 on ppc64, fr0-fr13, v0-v19, vscr. + 2013-02-12 Georg-Johann Lay PR target/54222 diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h index 3a2da6e7a8f..c9273c404e2 100644 --- a/libgcc/config/rs6000/linux-unwind.h +++ b/libgcc/config/rs6000/linux-unwind.h @@ -26,7 +26,6 @@ #define R_CR2 70 #define R_VR0 77 #define R_VRSAVE 109 -#define R_VSCR 110 struct gcc_vregs { @@ -175,38 +174,6 @@ get_regs (struct _Unwind_Context *context) } #endif -/* Find an entry in the process auxiliary vector. The canonical way to - test for VMX is to look at AT_HWCAP. */ - -static long -ppc_linux_aux_vector (long which) -{ - /* __libc_stack_end holds the original stack passed to a process. */ - extern long *__libc_stack_end; - long argc; - char **argv; - char **envp; - struct auxv - { - long a_type; - long a_val; - } *auxp; - - /* The Linux kernel puts argc first on the stack. */ - argc = __libc_stack_end[0]; - /* Followed by argv, NULL terminated. */ - argv = (char **) __libc_stack_end + 1; - /* Followed by environment string pointers, NULL terminated. */ - envp = argv + argc + 1; - while (*envp++) - continue; - /* Followed by the aux vector, zero terminated. */ - for (auxp = (struct auxv *) envp; auxp->a_type != 0; ++auxp) - if (auxp->a_type == which) - return auxp->a_val; - return 0; -} - /* Do code reading to identify a signal frame, and set the frame state data appropriately. See unwind-dw2.c for the structs. */ @@ -216,8 +183,8 @@ static _Unwind_Reason_Code ppc_fallback_frame_state (struct _Unwind_Context *context, _Unwind_FrameState *fs) { - static long hwcap = 0; struct gcc_regs *regs = get_regs (context); + struct gcc_vregs *vregs; long new_cfa; int i; @@ -229,12 +196,15 @@ ppc_fallback_frame_state (struct _Unwind_Context *context, fs->regs.cfa_reg = STACK_POINTER_REGNUM; fs->regs.cfa_offset = new_cfa - (long) context->cfa; - for (i = 0; i < 32; i++) - if (i != STACK_POINTER_REGNUM) - { - fs->regs.reg[i].how = REG_SAVED_OFFSET; - fs->regs.reg[i].loc.offset = (long) ®s->gpr[i] - new_cfa; - } +#ifdef __powerpc64__ + fs->regs.reg[2].how = REG_SAVED_OFFSET; + fs->regs.reg[2].loc.offset = (long) ®s->gpr[2] - new_cfa; +#endif + for (i = 14; i < 32; i++) + { + fs->regs.reg[i].how = REG_SAVED_OFFSET; + fs->regs.reg[i].loc.offset = (long) ®s->gpr[i] - new_cfa; + } fs->regs.reg[R_CR2].how = REG_SAVED_OFFSET; /* CR? regs are always 32-bit and PPC is big-endian, so in 64-bit @@ -250,57 +220,35 @@ ppc_fallback_frame_state (struct _Unwind_Context *context, fs->retaddr_column = ARG_POINTER_REGNUM; fs->signal_frame = 1; - if (hwcap == 0) + /* If we have a FPU... */ + for (i = 14; i < 32; i++) { - hwcap = ppc_linux_aux_vector (16); - /* These will already be set if we found AT_HWCAP. A nonzero - value stops us looking again if for some reason we couldn't - find AT_HWCAP. */ -#ifdef __powerpc64__ - hwcap |= 0xc0000000; -#else - hwcap |= 0x80000000; -#endif + fs->regs.reg[i + 32].how = REG_SAVED_OFFSET; + fs->regs.reg[i + 32].loc.offset = (long) ®s->fpr[i] - new_cfa; } - /* If we have a FPU... */ - if (hwcap & 0x08000000) - for (i = 0; i < 32; i++) - { - fs->regs.reg[i + 32].how = REG_SAVED_OFFSET; - fs->regs.reg[i + 32].loc.offset = (long) ®s->fpr[i] - new_cfa; - } - /* If we have a VMX unit... */ - if (hwcap & 0x10000000) - { - struct gcc_vregs *vregs; #ifdef __powerpc64__ - vregs = regs->vp; + vregs = regs->vp; #else - vregs = ®s->vregs; + vregs = ®s->vregs; #endif - if (regs->msr & (1 << 25)) + if (regs->msr & (1 << 25)) + { + for (i = 20; i < 32; i++) { - for (i = 0; i < 32; i++) - { - fs->regs.reg[i + R_VR0].how = REG_SAVED_OFFSET; - fs->regs.reg[i + R_VR0].loc.offset - = (long) &vregs->vr[i] - new_cfa; - } - - fs->regs.reg[R_VSCR].how = REG_SAVED_OFFSET; - fs->regs.reg[R_VSCR].loc.offset = (long) &vregs->vscr - new_cfa; + fs->regs.reg[i + R_VR0].how = REG_SAVED_OFFSET; + fs->regs.reg[i + R_VR0].loc.offset = (long) &vregs->vr[i] - new_cfa; } - - fs->regs.reg[R_VRSAVE].how = REG_SAVED_OFFSET; - fs->regs.reg[R_VRSAVE].loc.offset = (long) &vregs->vsave - new_cfa; } + fs->regs.reg[R_VRSAVE].how = REG_SAVED_OFFSET; + fs->regs.reg[R_VRSAVE].loc.offset = (long) &vregs->vsave - new_cfa; + /* If we have SPE register high-parts... we check at compile-time to avoid expanding the code for all other PowerPC. */ #ifdef __SPE__ - for (i = 0; i < 32; i++) + for (i = 14; i < 32; i++) { fs->regs.reg[i + FIRST_PSEUDO_REGISTER - 1].how = REG_SAVED_OFFSET; fs->regs.reg[i + FIRST_PSEUDO_REGISTER - 1].loc.offset