summaryrefslogtreecommitdiff
path: root/package/gcc/patches/musl-ppc.patch
blob: f4211ee73dac4823b9f294d3057c02e1d3304542 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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) &regs->gpr[i] - new_cfa;
-      }
+#ifdef __powerpc64__
+  fs->regs.reg[2].how = REG_SAVED_OFFSET;
+  fs->regs.reg[2].loc.offset = (long) &regs->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) &regs->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) &regs->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) &regs->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 = &regs->vregs;
+  vregs = &regs->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