diff -Nur gcc-4.7.3.orig/libgcc/config/rs6000/linux-unwind.h gcc-4.7.3/libgcc/config/rs6000/linux-unwind.h --- gcc-4.7.3.orig/libgcc/config/rs6000/linux-unwind.h 2011-11-12 18:20:58.000000000 +0100 +++ gcc-4.7.3/libgcc/config/rs6000/linux-unwind.h 2013-09-15 18:29:20.000000000 +0200 @@ -27,7 +27,6 @@ #define R_CR2 70 #define R_VR0 77 #define R_VRSAVE 109 -#define R_VSCR 110 struct gcc_vregs { @@ -176,38 +175,6 @@ } #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. */ @@ -217,8 +184,8 @@ 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; @@ -230,12 +197,15 @@ 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 @@ -251,57 +221,35 @@ 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