From 1d9fec7937f45dde5e04cac966a2d9a12f2fc15a Mon Sep 17 00:00:00 2001 From: Yiran Wang Date: Tue, 23 Jun 2015 15:33:17 -0700 Subject: Synchronize with google/gcc-4_9 to r224707 (from r214835) Change-Id: I3d6f06fc613c8f8b6a82143dc44b7338483aac5d --- gcc-4.9/libgcc/config/avr/lib1funcs.S | 229 ++++++++++------------ gcc-4.9/libgcc/config/avr/t-avr | 3 +- gcc-4.9/libgcc/config/i386/sfp-machine.h | 2 +- gcc-4.9/libgcc/config/libbid/ChangeLog | 4 + gcc-4.9/libgcc/config/nios2/linux-unwind.h | 3 +- gcc-4.9/libgcc/config/pa/linux-atomic.c | 304 ++++++++++++++++------------- gcc-4.9/libgcc/config/pa/linux-unwind.h | 34 +++- gcc-4.9/libgcc/config/sh/lib1funcs.S | 18 +- 8 files changed, 317 insertions(+), 280 deletions(-) (limited to 'gcc-4.9/libgcc/config') diff --git a/gcc-4.9/libgcc/config/avr/lib1funcs.S b/gcc-4.9/libgcc/config/avr/lib1funcs.S index 6f1c77edb..5ad1e93f1 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 461304706..1f7356968 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 148044a69..8a1923b6c 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 c3f83862a..68d46d29f 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 92ff1f629..ba4bd801d 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 d92d6ef79..19e37b6f3 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__and_fetch and __sync_fetch_and_ 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 485f2d98e..4a3cfffd1 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 #include +/* 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 3410cf7c1..cfd6dc2a2 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 -- cgit v1.2.3