aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/libgcc/config
diff options
context:
space:
mode:
authorYiran Wang <yiran@google.com>2015-06-23 22:33:17 (GMT)
committerYiran Wang <yiran@google.com>2015-06-29 17:56:28 (GMT)
commit1d9fec7937f45dde5e04cac966a2d9a12f2fc15a (patch)
tree3fbcd18a379a05fd6d43491a107e1f36bc61b185 /gcc-4.9/libgcc/config
parentf378ebf14df0952eae870c9865bab8326aa8f137 (diff)
downloadtoolchain_gcc-1d9fec7937f45dde5e04cac966a2d9a12f2fc15a.zip
toolchain_gcc-1d9fec7937f45dde5e04cac966a2d9a12f2fc15a.tar.gz
toolchain_gcc-1d9fec7937f45dde5e04cac966a2d9a12f2fc15a.tar.bz2
Synchronize with google/gcc-4_9 to r224707 (from r214835)
Change-Id: I3d6f06fc613c8f8b6a82143dc44b7338483aac5d
Diffstat (limited to 'gcc-4.9/libgcc/config')
-rw-r--r--gcc-4.9/libgcc/config/avr/lib1funcs.S229
-rw-r--r--gcc-4.9/libgcc/config/avr/t-avr3
-rw-r--r--gcc-4.9/libgcc/config/i386/sfp-machine.h2
-rw-r--r--gcc-4.9/libgcc/config/libbid/ChangeLog4
-rw-r--r--gcc-4.9/libgcc/config/nios2/linux-unwind.h3
-rw-r--r--gcc-4.9/libgcc/config/pa/linux-atomic.c304
-rw-r--r--gcc-4.9/libgcc/config/pa/linux-unwind.h34
-rw-r--r--gcc-4.9/libgcc/config/sh/lib1funcs.S18
8 files changed, 317 insertions, 280 deletions
diff --git a/gcc-4.9/libgcc/config/avr/lib1funcs.S b/gcc-4.9/libgcc/config/avr/lib1funcs.S
index 6f1c77e..5ad1e93 100644
--- a/gcc-4.9/libgcc/config/avr/lib1funcs.S
+++ b/gcc-4.9/libgcc/config/avr/lib1funcs.S
@@ -46,6 +46,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
input sections together are small enough to reach every
location with a RCALL/RJMP instruction. */
+#if defined (__AVR_HAVE_EIJMP_EICALL__) && !defined (__AVR_HAVE_ELPMX__)
+#error device not supported
+#endif
+
.macro mov_l r_dest, r_src
#if defined (__AVR_HAVE_MOVW__)
movw \r_dest, \r_src
@@ -79,6 +83,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define XJMP rjmp
#endif
+#if defined (__AVR_HAVE_EIJMP_EICALL__)
+#define XICALL eicall
+#define XIJMP eijmp
+#else
+#define XICALL icall
+#define XIJMP ijmp
+#endif
+
;; Prologue stuff
.macro do_prologue_saves n_pushed n_frame=0
@@ -2127,11 +2139,7 @@ DEFUN __prologue_saves__
out __SP_L__,r28
#endif /* #SP = 8/16 */
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
- eijmp
-#else
- ijmp
-#endif
+ XIJMP
ENDF __prologue_saves__
#endif /* defined (L_prologue) */
@@ -2213,38 +2221,54 @@ _cleanup:
.section .text.libgcc, "ax", @progbits
-#ifdef L_tablejump
+#ifdef L_tablejump2
DEFUN __tablejump2__
- lsl r30
- rol r31
- ;; FALLTHRU
-ENDF __tablejump2__
-
-DEFUN __tablejump__
-#if defined (__AVR_HAVE_LPMX__)
- lpm __tmp_reg__, Z+
- lpm r31, Z
- mov r30, __tmp_reg__
+ lsl r30
+ rol r31
#if defined (__AVR_HAVE_EIJMP_EICALL__)
- eijmp
-#else
- ijmp
+ ;; Word address of gs() jumptable entry in R24:Z
+ rol r24
+ out __RAMPZ__, r24
+#elif defined (__AVR_HAVE_ELPM__)
+ ;; Word address of jumptable entry in Z
+ clr __tmp_reg__
+ rol __tmp_reg__
+ out __RAMPZ__, __tmp_reg__
#endif
-#else /* !HAVE_LPMX */
- lpm
- adiw r30, 1
- push r0
- lpm
- push r0
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
- in __tmp_reg__, __EIND__
- push __tmp_reg__
+ ;; Read word address from jumptable and jump
+
+#if defined (__AVR_HAVE_ELPMX__)
+ elpm __tmp_reg__, Z+
+ elpm r31, Z
+ mov r30, __tmp_reg__
+#ifdef __AVR_HAVE_RAMPD__
+ ;; Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM
+ out __RAMPZ__, __zero_reg__
+#endif /* RAMPD */
+ XIJMP
+#elif defined (__AVR_HAVE_ELPM__)
+ elpm
+ push r0
+ adiw r30, 1
+ elpm
+ push r0
+ ret
+#elif defined (__AVR_HAVE_LPMX__)
+ lpm __tmp_reg__, Z+
+ lpm r31, Z
+ mov r30, __tmp_reg__
+ ijmp
+#else
+ lpm
+ push r0
+ adiw r30, 1
+ lpm
+ push r0
+ ret
#endif
- ret
-#endif /* !HAVE_LPMX */
-ENDF __tablejump__
-#endif /* defined (L_tablejump) */
+ENDF __tablejump2__
+#endif /* L_tablejump2 */
#ifdef L_copy_data
.section .init4,"ax",@progbits
@@ -2336,116 +2360,67 @@ ENDF __do_clear_bss
#ifdef L_ctors
.section .init6,"ax",@progbits
DEFUN __do_global_ctors
-#if defined(__AVR_HAVE_ELPM__)
- ldi r17, hi8(__ctors_start)
- ldi r28, lo8(__ctors_end)
- ldi r29, hi8(__ctors_end)
- ldi r16, hh8(__ctors_end)
- rjmp .L__do_global_ctors_start
+ ldi r17, pm_hi8(__ctors_start)
+ ldi r28, pm_lo8(__ctors_end)
+ ldi r29, pm_hi8(__ctors_end)
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ ldi r16, pm_hh8(__ctors_end)
+#endif /* HAVE_EIJMP */
+ rjmp .L__do_global_ctors_start
.L__do_global_ctors_loop:
- sbiw r28, 2
- sbc r16, __zero_reg__
- mov_h r31, r29
- mov_l r30, r28
- out __RAMPZ__, r16
- XCALL __tablejump_elpm__
+ sbiw r28, 1
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ sbc r16, __zero_reg__
+ mov r24, r16
+#endif /* HAVE_EIJMP */
+ mov_h r31, r29
+ mov_l r30, r28
+ XCALL __tablejump2__
.L__do_global_ctors_start:
- cpi r28, lo8(__ctors_start)
- cpc r29, r17
- ldi r24, hh8(__ctors_start)
- cpc r16, r24
- brne .L__do_global_ctors_loop
-#else
- ldi r17, hi8(__ctors_start)
- ldi r28, lo8(__ctors_end)
- ldi r29, hi8(__ctors_end)
- rjmp .L__do_global_ctors_start
-.L__do_global_ctors_loop:
- sbiw r28, 2
- mov_h r31, r29
- mov_l r30, r28
- XCALL __tablejump__
-.L__do_global_ctors_start:
- cpi r28, lo8(__ctors_start)
- cpc r29, r17
- brne .L__do_global_ctors_loop
-#endif /* defined(__AVR_HAVE_ELPM__) */
+ cpi r28, pm_lo8(__ctors_start)
+ cpc r29, r17
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ ldi r24, pm_hh8(__ctors_start)
+ cpc r16, r24
+#endif /* HAVE_EIJMP */
+ brne .L__do_global_ctors_loop
ENDF __do_global_ctors
#endif /* L_ctors */
#ifdef L_dtors
.section .fini6,"ax",@progbits
DEFUN __do_global_dtors
-#if defined(__AVR_HAVE_ELPM__)
- ldi r17, hi8(__dtors_end)
- ldi r28, lo8(__dtors_start)
- ldi r29, hi8(__dtors_start)
- ldi r16, hh8(__dtors_start)
- rjmp .L__do_global_dtors_start
+ ldi r17, pm_hi8(__dtors_end)
+ ldi r28, pm_lo8(__dtors_start)
+ ldi r29, pm_hi8(__dtors_start)
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ ldi r16, pm_hh8(__dtors_start)
+#endif /* HAVE_EIJMP */
+ rjmp .L__do_global_dtors_start
.L__do_global_dtors_loop:
- sbiw r28, 2
- sbc r16, __zero_reg__
- mov_h r31, r29
- mov_l r30, r28
- out __RAMPZ__, r16
- XCALL __tablejump_elpm__
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ mov r24, r16
+#endif /* HAVE_EIJMP */
+ mov_h r31, r29
+ mov_l r30, r28
+ XCALL __tablejump2__
+ adiw r28, 1
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ adc r16, __zero_reg__
+#endif /* HAVE_EIJMP */
.L__do_global_dtors_start:
- cpi r28, lo8(__dtors_end)
- cpc r29, r17
- ldi r24, hh8(__dtors_end)
- cpc r16, r24
- brne .L__do_global_dtors_loop
-#else
- ldi r17, hi8(__dtors_end)
- ldi r28, lo8(__dtors_start)
- ldi r29, hi8(__dtors_start)
- rjmp .L__do_global_dtors_start
-.L__do_global_dtors_loop:
- mov_h r31, r29
- mov_l r30, r28
- XCALL __tablejump__
- adiw r28, 2
-.L__do_global_dtors_start:
- cpi r28, lo8(__dtors_end)
- cpc r29, r17
- brne .L__do_global_dtors_loop
-#endif /* defined(__AVR_HAVE_ELPM__) */
+ cpi r28, pm_lo8(__dtors_end)
+ cpc r29, r17
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ ldi r24, pm_hh8(__dtors_end)
+ cpc r16, r24
+#endif /* HAVE_EIJMP */
+ brne .L__do_global_dtors_loop
ENDF __do_global_dtors
#endif /* L_dtors */
.section .text.libgcc, "ax", @progbits
-#ifdef L_tablejump_elpm
-DEFUN __tablejump_elpm__
-#if defined (__AVR_HAVE_ELPMX__)
- elpm __tmp_reg__, Z+
- elpm r31, Z
- mov r30, __tmp_reg__
-#if defined (__AVR_HAVE_RAMPD__)
- ;; Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM
- out __RAMPZ__, __zero_reg__
-#endif /* RAMPD */
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
- eijmp
-#else
- ijmp
-#endif
-
-#elif defined (__AVR_HAVE_ELPM__)
- elpm
- adiw r30, 1
- push r0
- elpm
- push r0
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
- in __tmp_reg__, __EIND__
- push __tmp_reg__
-#endif
- ret
-#endif
-ENDF __tablejump_elpm__
-#endif /* defined (L_tablejump_elpm) */
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loading n bytes from Flash; n = 3,4
;; R22... = Flash[Z]
diff --git a/gcc-4.9/libgcc/config/avr/t-avr b/gcc-4.9/libgcc/config/avr/t-avr
index 4613047..1f73569 100644
--- a/gcc-4.9/libgcc/config/avr/t-avr
+++ b/gcc-4.9/libgcc/config/avr/t-avr
@@ -26,8 +26,7 @@ LIB1ASMFUNCS = \
_epilogue \
_exit \
_cleanup \
- _tablejump \
- _tablejump_elpm \
+ _tablejump2 \
_load_3 _load_4 \
_xload_1 _xload_2 _xload_3 _xload_4 \
_movmemx \
diff --git a/gcc-4.9/libgcc/config/i386/sfp-machine.h b/gcc-4.9/libgcc/config/i386/sfp-machine.h
index 148044a..8a1923b 100644
--- a/gcc-4.9/libgcc/config/i386/sfp-machine.h
+++ b/gcc-4.9/libgcc/config/i386/sfp-machine.h
@@ -60,7 +60,7 @@ void __sfp_handle_exceptions (int);
__sfp_handle_exceptions (_fex); \
} while (0);
-#define FP_TRAPPING_EXCEPTIONS ((_fcw >> FP_EX_SHIFT) & FP_EX_ALL)
+#define FP_TRAPPING_EXCEPTIONS ((~_fcw >> FP_EX_SHIFT) & FP_EX_ALL)
#define FP_ROUNDMODE (_fcw & FP_RND_MASK)
#endif
diff --git a/gcc-4.9/libgcc/config/libbid/ChangeLog b/gcc-4.9/libgcc/config/libbid/ChangeLog
index c3f8386..68d46d2 100644
--- a/gcc-4.9/libgcc/config/libbid/ChangeLog
+++ b/gcc-4.9/libgcc/config/libbid/ChangeLog
@@ -1,3 +1,7 @@
+2014-10-30 Release Manager
+
+ * GCC 4.9.2 released.
+
2014-07-16 Release Manager
* GCC 4.9.1 released.
diff --git a/gcc-4.9/libgcc/config/nios2/linux-unwind.h b/gcc-4.9/libgcc/config/nios2/linux-unwind.h
index 92ff1f6..ba4bd80 100644
--- a/gcc-4.9/libgcc/config/nios2/linux-unwind.h
+++ b/gcc-4.9/libgcc/config/nios2/linux-unwind.h
@@ -67,10 +67,9 @@ nios2_fallback_frame_state (struct _Unwind_Context *context,
if (pc[0] == (0x00800004 | (__NR_rt_sigreturn << 6)))
{
struct rt_sigframe {
- char retcode[12];
siginfo_t info;
struct nios2_ucontext uc;
- } *rt_ = context->ra;
+ } *rt_ = context->cfa;
struct nios2_mcontext *regs = &rt_->uc.uc_mcontext;
int i;
diff --git a/gcc-4.9/libgcc/config/pa/linux-atomic.c b/gcc-4.9/libgcc/config/pa/linux-atomic.c
index d92d6ef..19e37b6 100644
--- a/gcc-4.9/libgcc/config/pa/linux-atomic.c
+++ b/gcc-4.9/libgcc/config/pa/linux-atomic.c
@@ -41,11 +41,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
using the kernel helper defined below. There is no support for
64-bit operations yet. */
-/* A privileged instruction to crash a userspace program with SIGILL. */
-#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%sr0, %r0)")
-
/* Determine kernel LWS function call (0=32-bit, 1=64-bit userspace). */
-#define LWS_CAS (sizeof(unsigned long) == 4 ? 0 : 1)
+#define LWS_CAS (sizeof(long) == 4 ? 0 : 1)
/* Kernel helper for compare-and-exchange a 32-bit value. */
static inline long
@@ -64,7 +61,7 @@ __kernel_cmpxchg (int oldval, int newval, int *mem)
: "r1", "r20", "r22", "r23", "r29", "r31", "memory"
);
if (__builtin_expect (lws_errno == -EFAULT || lws_errno == -ENOSYS, 0))
- ABORT_INSTRUCTION;
+ __builtin_trap ();
/* If the kernel LWS call succeeded (lws_errno == 0), lws_ret contains
the old value from memory. If this value is equal to OLDVAL, the
@@ -75,6 +72,30 @@ __kernel_cmpxchg (int oldval, int newval, int *mem)
return lws_errno;
}
+static inline long
+__kernel_cmpxchg2 (void * oldval, void * newval, void *mem, int val_size)
+{
+ register unsigned long lws_mem asm("r26") = (unsigned long) (mem);
+ register long lws_ret asm("r28");
+ register long lws_errno asm("r21");
+ register unsigned long lws_old asm("r25") = (unsigned long) oldval;
+ register unsigned long lws_new asm("r24") = (unsigned long) newval;
+ register int lws_size asm("r23") = val_size;
+ asm volatile ( "ble 0xb0(%%sr2, %%r0) \n\t"
+ "ldi %2, %%r20 \n\t"
+ : "=r" (lws_ret), "=r" (lws_errno)
+ : "i" (2), "r" (lws_mem), "r" (lws_old), "r" (lws_new), "r" (lws_size)
+ : "r1", "r20", "r22", "r29", "r31", "fr4", "memory"
+ );
+ if (__builtin_expect (lws_errno == -EFAULT || lws_errno == -ENOSYS, 0))
+ __builtin_trap ();
+
+ /* If the kernel LWS call fails, retrun EBUSY */
+ if (!lws_errno && lws_ret)
+ lws_errno = -EBUSY;
+
+ return lws_errno;
+}
#define HIDDEN __attribute__ ((visibility ("hidden")))
/* Big endian masks */
@@ -84,6 +105,80 @@ __kernel_cmpxchg (int oldval, int newval, int *mem)
#define MASK_1 0xffu
#define MASK_2 0xffffu
+#define FETCH_AND_OP_2(OP, PFX_OP, INF_OP, TYPE, WIDTH, INDEX) \
+ TYPE HIDDEN \
+ __sync_fetch_and_##OP##_##WIDTH (TYPE *ptr, TYPE val) \
+ { \
+ TYPE tmp, newval; \
+ int failure; \
+ \
+ do { \
+ tmp = *ptr; \
+ newval = PFX_OP (tmp INF_OP val); \
+ failure = __kernel_cmpxchg2 (&tmp, &newval, ptr, INDEX); \
+ } while (failure != 0); \
+ \
+ return tmp; \
+ }
+
+FETCH_AND_OP_2 (add, , +, long long, 8, 3)
+FETCH_AND_OP_2 (sub, , -, long long, 8, 3)
+FETCH_AND_OP_2 (or, , |, long long, 8, 3)
+FETCH_AND_OP_2 (and, , &, long long, 8, 3)
+FETCH_AND_OP_2 (xor, , ^, long long, 8, 3)
+FETCH_AND_OP_2 (nand, ~, &, long long, 8, 3)
+
+FETCH_AND_OP_2 (add, , +, short, 2, 1)
+FETCH_AND_OP_2 (sub, , -, short, 2, 1)
+FETCH_AND_OP_2 (or, , |, short, 2, 1)
+FETCH_AND_OP_2 (and, , &, short, 2, 1)
+FETCH_AND_OP_2 (xor, , ^, short, 2, 1)
+FETCH_AND_OP_2 (nand, ~, &, short, 2, 1)
+
+FETCH_AND_OP_2 (add, , +, signed char, 1, 0)
+FETCH_AND_OP_2 (sub, , -, signed char, 1, 0)
+FETCH_AND_OP_2 (or, , |, signed char, 1, 0)
+FETCH_AND_OP_2 (and, , &, signed char, 1, 0)
+FETCH_AND_OP_2 (xor, , ^, signed char, 1, 0)
+FETCH_AND_OP_2 (nand, ~, &, signed char, 1, 0)
+
+#define OP_AND_FETCH_2(OP, PFX_OP, INF_OP, TYPE, WIDTH, INDEX) \
+ TYPE HIDDEN \
+ __sync_##OP##_and_fetch_##WIDTH (TYPE *ptr, TYPE val) \
+ { \
+ TYPE tmp, newval; \
+ int failure; \
+ \
+ do { \
+ tmp = *ptr; \
+ newval = PFX_OP (tmp INF_OP val); \
+ failure = __kernel_cmpxchg2 (&tmp, &newval, ptr, INDEX); \
+ } while (failure != 0); \
+ \
+ return PFX_OP (tmp INF_OP val); \
+ }
+
+OP_AND_FETCH_2 (add, , +, long long, 8, 3)
+OP_AND_FETCH_2 (sub, , -, long long, 8, 3)
+OP_AND_FETCH_2 (or, , |, long long, 8, 3)
+OP_AND_FETCH_2 (and, , &, long long, 8, 3)
+OP_AND_FETCH_2 (xor, , ^, long long, 8, 3)
+OP_AND_FETCH_2 (nand, ~, &, long long, 8, 3)
+
+OP_AND_FETCH_2 (add, , +, short, 2, 1)
+OP_AND_FETCH_2 (sub, , -, short, 2, 1)
+OP_AND_FETCH_2 (or, , |, short, 2, 1)
+OP_AND_FETCH_2 (and, , &, short, 2, 1)
+OP_AND_FETCH_2 (xor, , ^, short, 2, 1)
+OP_AND_FETCH_2 (nand, ~, &, short, 2, 1)
+
+OP_AND_FETCH_2 (add, , +, signed char, 1, 0)
+OP_AND_FETCH_2 (sub, , -, signed char, 1, 0)
+OP_AND_FETCH_2 (or, , |, signed char, 1, 0)
+OP_AND_FETCH_2 (and, , &, signed char, 1, 0)
+OP_AND_FETCH_2 (xor, , ^, signed char, 1, 0)
+OP_AND_FETCH_2 (nand, ~, &, signed char, 1, 0)
+
#define FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP) \
int HIDDEN \
__sync_fetch_and_##OP##_4 (int *ptr, int val) \
@@ -105,48 +200,6 @@ FETCH_AND_OP_WORD (and, , &)
FETCH_AND_OP_WORD (xor, , ^)
FETCH_AND_OP_WORD (nand, ~, &)
-#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH
-#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH
-
-/* Implement both __sync_<op>_and_fetch and __sync_fetch_and_<op> for
- subword-sized quantities. */
-
-#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \
- TYPE HIDDEN \
- NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val) \
- { \
- int *wordptr = (int *) ((unsigned long) ptr & ~3); \
- unsigned int mask, shift, oldval, newval; \
- int failure; \
- \
- shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
- mask = MASK_##WIDTH << shift; \
- \
- do { \
- oldval = *wordptr; \
- newval = ((PFX_OP (((oldval & mask) >> shift) \
- INF_OP (unsigned int) val)) << shift) & mask; \
- newval |= oldval & ~mask; \
- failure = __kernel_cmpxchg (oldval, newval, wordptr); \
- } while (failure != 0); \
- \
- return (RETURN & mask) >> shift; \
- }
-
-SUBWORD_SYNC_OP (add, , +, unsigned short, 2, oldval)
-SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, oldval)
-SUBWORD_SYNC_OP (or, , |, unsigned short, 2, oldval)
-SUBWORD_SYNC_OP (and, , &, unsigned short, 2, oldval)
-SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, oldval)
-SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, oldval)
-
-SUBWORD_SYNC_OP (add, , +, unsigned char, 1, oldval)
-SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, oldval)
-SUBWORD_SYNC_OP (or, , |, unsigned char, 1, oldval)
-SUBWORD_SYNC_OP (and, , &, unsigned char, 1, oldval)
-SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, oldval)
-SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, oldval)
-
#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \
int HIDDEN \
__sync_##OP##_and_fetch_4 (int *ptr, int val) \
@@ -168,19 +221,41 @@ OP_AND_FETCH_WORD (and, , &)
OP_AND_FETCH_WORD (xor, , ^)
OP_AND_FETCH_WORD (nand, ~, &)
-SUBWORD_SYNC_OP (add, , +, unsigned short, 2, newval)
-SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, newval)
-SUBWORD_SYNC_OP (or, , |, unsigned short, 2, newval)
-SUBWORD_SYNC_OP (and, , &, unsigned short, 2, newval)
-SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, newval)
-SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, newval)
+typedef unsigned char bool;
+
+#define COMPARE_AND_SWAP_2(TYPE, WIDTH, INDEX) \
+ TYPE HIDDEN \
+ __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
+ TYPE newval) \
+ { \
+ TYPE actual_oldval; \
+ int fail; \
+ \
+ while (1) \
+ { \
+ actual_oldval = *ptr; \
+ \
+ if (__builtin_expect (oldval != actual_oldval, 0)) \
+ return actual_oldval; \
+ \
+ fail = __kernel_cmpxchg2 (&actual_oldval, &newval, ptr, INDEX); \
+ \
+ if (__builtin_expect (!fail, 1)) \
+ return actual_oldval; \
+ } \
+ } \
+ \
+ bool HIDDEN \
+ __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
+ TYPE newval) \
+ { \
+ int failure = __kernel_cmpxchg2 (&oldval, &newval, ptr, INDEX); \
+ return (failure != 0); \
+ }
-SUBWORD_SYNC_OP (add, , +, unsigned char, 1, newval)
-SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, newval)
-SUBWORD_SYNC_OP (or, , |, unsigned char, 1, newval)
-SUBWORD_SYNC_OP (and, , &, unsigned char, 1, newval)
-SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, newval)
-SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, newval)
+COMPARE_AND_SWAP_2 (long long, 8, 3)
+COMPARE_AND_SWAP_2 (short, 2, 1)
+COMPARE_AND_SWAP_2 (char, 1, 0)
int HIDDEN
__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval)
@@ -201,41 +276,6 @@ __sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval)
}
}
-#define SUBWORD_VAL_CAS(TYPE, WIDTH) \
- TYPE HIDDEN \
- __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
- TYPE newval) \
- { \
- int *wordptr = (int *)((unsigned long) ptr & ~3), fail; \
- unsigned int mask, shift, actual_oldval, actual_newval; \
- \
- shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
- mask = MASK_##WIDTH << shift; \
- \
- while (1) \
- { \
- actual_oldval = *wordptr; \
- \
- if (__builtin_expect (((actual_oldval & mask) >> shift) \
- != (unsigned int) oldval, 0)) \
- return (actual_oldval & mask) >> shift; \
- \
- actual_newval = (actual_oldval & ~mask) \
- | (((unsigned int) newval << shift) & mask); \
- \
- fail = __kernel_cmpxchg (actual_oldval, actual_newval, \
- wordptr); \
- \
- if (__builtin_expect (!fail, 1)) \
- return (actual_oldval & mask) >> shift; \
- } \
- }
-
-SUBWORD_VAL_CAS (unsigned short, 2)
-SUBWORD_VAL_CAS (unsigned char, 1)
-
-typedef unsigned char bool;
-
bool HIDDEN
__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval)
{
@@ -243,18 +283,24 @@ __sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval)
return (failure == 0);
}
-#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \
- bool HIDDEN \
- __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
- TYPE newval) \
+#define SYNC_LOCK_TEST_AND_SET_2(TYPE, WIDTH, INDEX) \
+TYPE HIDDEN \
+ __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \
{ \
- TYPE actual_oldval \
- = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \
- return (oldval == actual_oldval); \
+ TYPE oldval; \
+ int failure; \
+ \
+ do { \
+ oldval = *ptr; \
+ failure = __kernel_cmpxchg2 (&oldval, &val, ptr, INDEX); \
+ } while (failure != 0); \
+ \
+ return oldval; \
}
-SUBWORD_BOOL_CAS (unsigned short, 2)
-SUBWORD_BOOL_CAS (unsigned char, 1)
+SYNC_LOCK_TEST_AND_SET_2 (long long, 8, 3)
+SYNC_LOCK_TEST_AND_SET_2 (short, 2, 1)
+SYNC_LOCK_TEST_AND_SET_2 (signed char, 1, 0)
int HIDDEN
__sync_lock_test_and_set_4 (int *ptr, int val)
@@ -269,37 +315,29 @@ __sync_lock_test_and_set_4 (int *ptr, int val)
return oldval;
}
-#define SUBWORD_TEST_AND_SET(TYPE, WIDTH) \
- TYPE HIDDEN \
- __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \
- { \
- int failure; \
- unsigned int oldval, newval, shift, mask; \
- int *wordptr = (int *) ((unsigned long) ptr & ~3); \
- \
- shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
- mask = MASK_##WIDTH << shift; \
- \
- do { \
- oldval = *wordptr; \
- newval = (oldval & ~mask) \
- | (((unsigned int) val << shift) & mask); \
- failure = __kernel_cmpxchg (oldval, newval, wordptr); \
- } while (failure != 0); \
- \
- return (oldval & mask) >> shift; \
+#define SYNC_LOCK_RELEASE_2(TYPE, WIDTH, INDEX) \
+ void HIDDEN \
+ __sync_lock_release_##WIDTH (TYPE *ptr) \
+ { \
+ TYPE failure, oldval, zero = 0; \
+ \
+ do { \
+ oldval = *ptr; \
+ failure = __kernel_cmpxchg2 (&oldval, &zero, ptr, INDEX); \
+ } while (failure != 0); \
}
-SUBWORD_TEST_AND_SET (unsigned short, 2)
-SUBWORD_TEST_AND_SET (unsigned char, 1)
+SYNC_LOCK_RELEASE_2 (long long, 8, 3)
+SYNC_LOCK_RELEASE_2 (short, 2, 1)
+SYNC_LOCK_RELEASE_2 (signed char, 1, 0)
-#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \
- void HIDDEN \
- __sync_lock_release_##WIDTH (TYPE *ptr) \
- { \
- *ptr = 0; \
- }
+void HIDDEN
+__sync_lock_release_4 (int *ptr)
+{
+ int failure, oldval;
-SYNC_LOCK_RELEASE (int, 4)
-SYNC_LOCK_RELEASE (short, 2)
-SYNC_LOCK_RELEASE (char, 1)
+ do {
+ oldval = *ptr;
+ failure = __kernel_cmpxchg (oldval, 0, ptr);
+ } while (failure != 0);
+}
diff --git a/gcc-4.9/libgcc/config/pa/linux-unwind.h b/gcc-4.9/libgcc/config/pa/linux-unwind.h
index 485f2d9..4a3cfff 100644
--- a/gcc-4.9/libgcc/config/pa/linux-unwind.h
+++ b/gcc-4.9/libgcc/config/pa/linux-unwind.h
@@ -32,6 +32,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <signal.h>
#include <sys/ucontext.h>
+/* Return TRUE if read access to *P is allowed. */
+
+static inline long
+pa32_read_access_ok (void *p)
+{
+ long ret;
+
+ __asm__ ("proberi (%1),3,%0" : "=r" (ret) : "r" (p) :);
+ return ret;
+}
+
/* Unfortunately, because of various bugs and changes to the kernel,
we have several cases to deal with.
@@ -48,7 +59,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
tell us how to locate the sigcontext structure.
Note that with a 2.4 64-bit kernel, the signal context is not properly
- passed back to userspace so the unwind will not work correctly. */
+ passed back to userspace so the unwind will not work correctly.
+
+ There is also a bug in various glibc versions. The (CONTEXT)->ra
+ for the outermost frame is not marked as undefined, so we need to
+ check whether read access is allowed for all the accesses used in
+ searching for the signal trampoline. */
#define MD_FALLBACK_FRAME_STATE_FOR pa32_fallback_frame_state
@@ -73,14 +89,17 @@ pa32_fallback_frame_state (struct _Unwind_Context *context,
e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31
08000240 nop */
- if (pc[0] == 0x34190000 || pc[0] == 0x34190002)
+ if (pa32_read_access_ok (pc)
+ && (pc[0] == 0x34190000 || pc[0] == 0x34190002))
off = 4*4;
- else if (pc[4] == 0x34190000 || pc[4] == 0x34190002)
+ else if (pa32_read_access_ok (&pc[4])
+ && (pc[4] == 0x34190000 || pc[4] == 0x34190002))
{
pc += 4;
off = 10 * 4;
}
- else if (pc[5] == 0x34190000 || pc[5] == 0x34190002)
+ else if (pa32_read_access_ok (&pc[5])
+ && (pc[5] == 0x34190000 || pc[5] == 0x34190002))
{
pc += 5;
off = 10 * 4;
@@ -96,13 +115,16 @@ pa32_fallback_frame_state (struct _Unwind_Context *context,
word boundary and we can then determine the frame offset. */
sp = (unsigned long)context->ra;
pc = (unsigned int *)sp;
- if ((pc[0] == 0x34190000 || pc[0] == 0x34190002) && (sp & 4))
+ if ((sp & 4)
+ && pa32_read_access_ok (pc)
+ && (pc[0] == 0x34190000 || pc[0] == 0x34190002))
off = 5 * 4;
else
return _URC_END_OF_STACK;
}
- if (pc[1] != 0x3414015a
+ if (!pa32_read_access_ok (&pc[3])
+ || pc[1] != 0x3414015a
|| pc[2] != 0xe4008200
|| pc[3] != 0x08000240)
return _URC_END_OF_STACK;
diff --git a/gcc-4.9/libgcc/config/sh/lib1funcs.S b/gcc-4.9/libgcc/config/sh/lib1funcs.S
index 3410cf7..cfd6dc2 100644
--- a/gcc-4.9/libgcc/config/sh/lib1funcs.S
+++ b/gcc-4.9/libgcc/config/sh/lib1funcs.S
@@ -1278,7 +1278,7 @@ GLOBAL(sdivsi3_2):
#endif
ENDFUNC(GLOBAL(sdivsi3_2))
#endif
-#elif defined __SHMEDIA__
+#elif __SHMEDIA__
/* m5compact-nofpu */
// clobbered: r18,r19,r20,r21,r25,tr0,tr1,tr2
.mode SHmedia
@@ -1683,7 +1683,7 @@ GLOBAL(udivsi3):
add.l r18,r25,r0
blink tr0,r63
#endif
-#elif defined (__SHMEDIA__)
+#elif __SHMEDIA__
/* m5compact-nofpu - more emphasis on code size than on speed, but don't
ignore speed altogether - div1 needs 9 cycles, subc 7 and rotcl 4.
So use a short shmedia loop. */
@@ -1707,7 +1707,7 @@ LOCAL(udivsi3_dontsub):
bnei r25,-32,tr1
add.l r20,r63,r0
blink tr2,r63
-#else /* ! defined (__SHMEDIA__) */
+#else /* ! __SHMEDIA__ */
LOCAL(div8):
div1 r5,r4
LOCAL(div7):
@@ -1773,7 +1773,7 @@ LOCAL(large_divisor):
#endif /* L_udivsi3 */
#ifdef L_udivdi3
-#ifdef __SHMEDIA__
+#if __SHMEDIA__
.mode SHmedia
.section .text..SHmedia32,"ax"
.align 2
@@ -1901,7 +1901,7 @@ LOCAL(no_lo_adj):
#endif /* L_udivdi3 */
#ifdef L_divdi3
-#ifdef __SHMEDIA__
+#if __SHMEDIA__
.mode SHmedia
.section .text..SHmedia32,"ax"
.align 2
@@ -1925,7 +1925,7 @@ GLOBAL(divdi3):
#endif /* L_divdi3 */
#ifdef L_umoddi3
-#ifdef __SHMEDIA__
+#if __SHMEDIA__
.mode SHmedia
.section .text..SHmedia32,"ax"
.align 2
@@ -2054,7 +2054,7 @@ LOCAL(no_lo_adj):
#endif /* L_umoddi3 */
#ifdef L_moddi3
-#ifdef __SHMEDIA__
+#if __SHMEDIA__
.mode SHmedia
.section .text..SHmedia32,"ax"
.align 2
@@ -3142,7 +3142,7 @@ GLOBAL(GCC_pop_shmedia_regs_nofpu):
#ifdef L_div_table
#if __SH5__
-#if defined(__pic__) && defined(__SHMEDIA__)
+#if defined(__pic__) && __SHMEDIA__
.global GLOBAL(sdivsi3)
FUNC(GLOBAL(sdivsi3))
#if __SH5__ == 32
@@ -3215,7 +3215,7 @@ Defects for bias -330:
#else /* ! __pic__ || ! __SHMEDIA__ */
.section .rodata
#endif /* __pic__ */
-#if defined(TEXT_DATA_BUG) && defined(__pic__) && defined(__SHMEDIA__)
+#if defined(TEXT_DATA_BUG) && defined(__pic__) && __SHMEDIA__
.balign 2
.type Local_div_table,@object
.size Local_div_table,128