diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-10-25 23:18:41 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-10-25 23:18:41 +0000 |
commit | 0cec14923830569b8727d461bcf64adaf965de83 (patch) | |
tree | 39212625ea993fb193b64da0b13d64cd323dc23b /libgcc/config | |
parent | f67dc76907675065f34ed0bd14915df8d0b63b2d (diff) | |
parent | 9bdc2a8f06cef54650798fcb4c343e4415fd5992 (diff) | |
download | gcc-0cec14923830569b8727d461bcf64adaf965de83.zip gcc-0cec14923830569b8727d461bcf64adaf965de83.tar.gz gcc-0cec14923830569b8727d461bcf64adaf965de83.tar.bz2 |
Merge from trunk revision 277462.
From-SVN: r277464
Diffstat (limited to 'libgcc/config')
-rw-r--r-- | libgcc/config/msp430/lib2hw_mul.S | 170 | ||||
-rw-r--r-- | libgcc/config/msp430/lib2mul.c | 3 | ||||
-rw-r--r-- | libgcc/config/pa/fptr.c | 16 | ||||
-rw-r--r-- | libgcc/config/pa/lib2funcs.S | 12 | ||||
-rw-r--r-- | libgcc/config/pa/milli64.S | 23 |
5 files changed, 137 insertions, 87 deletions
diff --git a/libgcc/config/msp430/lib2hw_mul.S b/libgcc/config/msp430/lib2hw_mul.S index 1a0e6e8..894c551 100644 --- a/libgcc/config/msp430/lib2hw_mul.S +++ b/libgcc/config/msp430/lib2hw_mul.S @@ -81,9 +81,9 @@ .type \gcc_name , @function \gcc_name: #ifdef __MSP430X_LARGE__ - BRA \eabi_soft_name + BRA #\eabi_soft_name #else - BR \eabi_soft_name + BR #\eabi_soft_name #endif .size \gcc_name , . - \gcc_name .popsection @@ -109,7 +109,7 @@ MOV.W &\RESULT, r12 ; Move result into return register .endm -.macro mult1632 OP1, OP2, RESULT_LO, RESULT_HI +.macro mult1632 OP1, OP2, RESLO, RESHI ;* * 16-bit hardware multiply with a 32-bit result: ;* int32 = int16 * int16 ;* uint32 = uint16 * uint16 @@ -127,11 +127,11 @@ MOV.W r12, &\OP1 ; Load operand 1 into multiplier MOV.W r13, &\OP2 ; Load operand 2 which triggers MPY - MOV.W &\RESULT_LO, r12 ; Move low result into return register - MOV.W &\RESULT_HI, r13 ; Move high result into return register + MOV.W &\RESLO, r12 ; Move low result into return register + MOV.W &\RESHI, r13 ; Move high result into return register .endm -.macro mult32 OP1, OP2, MAC_OP1, MAC_OP2, RESULT_LO, RESULT_HI +.macro mult32 OP1, OP2, MAC_OP1, MAC_OP2, RESLO, RESHI ;* * 32-bit hardware multiply with a 32-bit result using 16 multiply and accumulate: ;* int32 = int32 * int32 ;* @@ -149,16 +149,16 @@ MOV.W r12, &\OP1 ; Load operand 1 Low into multiplier MOV.W r14, &\OP2 ; Load operand 2 Low which triggers MPY MOV.W r12, &\MAC_OP1 ; Load operand 1 Low into mac - MOV.W &\RESULT_LO, r12 ; Low 16-bits of result ready for return - MOV.W &\RESULT_HI, &\RESULT_LO; MOV intermediate mpy high into low + MOV.W &\RESLO, r12 ; Low 16-bits of result ready for return + MOV.W &\RESHI, &\RESLO ; MOV intermediate mpy high into low MOV.W r15, &\MAC_OP2 ; Load operand 2 High, trigger MAC MOV.W r13, &\MAC_OP1 ; Load operand 1 High MOV.W r14, &\MAC_OP2 ; Load operand 2 Lo, trigger MAC - MOV.W &\RESULT_LO, r13 ; Upper 16-bits result ready for return + MOV.W &\RESLO, r13 ; Upper 16-bits result ready for return .endm -.macro mult32_hw OP1_LO OP1_HI OP2_LO OP2_HI RESULT_LO RESULT_HI +.macro mult32_hw OP1_LO OP1_HI OP2_LO OP2_HI RESLO RESHI ;* * 32-bit hardware multiply with a 32-bit result ;* int32 = int32 * int32 ;* @@ -177,8 +177,8 @@ MOV.W r13, &\OP1_HI ; Load operand 1 High into multiplier MOV.W r14, &\OP2_LO ; Load operand 2 Low into multiplier MOV.W r15, &\OP2_HI ; Load operand 2 High, trigger MPY - MOV.W &\RESULT_LO, r12 ; Ready low 16-bits for return - MOV.W &\RESULT_HI, r13 ; Ready high 16-bits for return + MOV.W &\RESLO, r12 ; Ready low 16-bits for return + MOV.W &\RESHI, r13 ; Ready high 16-bits for return .endm .macro mult3264_hw OP1_LO OP1_HI OP2_LO OP2_HI RES0 RES1 RES2 RES3 @@ -264,105 +264,141 @@ ;; Multiply unsigned long by unsigned long; result is unsigned long long. Uses hardware MPY16 ;; uint64 __mspabi_mpyull_hw32(uint32 x, uint32 y) ;; Multiply unsigned long by unsigned long; result is unsigned long long. Uses hardware MPY32 (F4xx devices). -;; uint64 _ _mspabi_mpyull_f5hw(uint32 x, uint32 y) +;; uint64 __mspabi_mpyull_f5hw(uint32 x, uint32 y) ;; Multiply unsigned long by unsigned long; result is unsigned long long. Uses hardware MPY32 (F5xx devices and up) - - -.set MPY_OP1, 0x0130 -.set MPY_OP1_S, 0x0132 -.set MAC_OP1, 0x0134 -.set MPY_OP2, 0x0138 -.set MAC_OP2, 0x0138 -.set RESULT_LO, 0x013A -.set RESULT_HI, 0x013C +;;;; The register names below are the standardised versions used across TI +;;;; literature. + +;; Hardware multiply register addresses for devices with 16-bit hardware +;; multiply. +.set MPY, 0x0130 +.set MPYS, 0x0132 +.set MAC, 0x0134 +.set OP2, 0x0138 +.set RESLO, 0x013A +.set RESHI, 0x013C +;; Hardware multiply register addresses for devices with 32-bit (non-f5) +;; hardware multiply. +.set MPY32L, 0x0140 +.set MPY32H, 0x0142 +.set MPYS32L, 0x0144 +.set MPYS32H, 0x0146 +.set OP2L, 0x0150 +.set OP2H, 0x0152 +.set RES0, 0x0154 +.set RES1, 0x0156 +.set RES2, 0x0158 +.set RES3, 0x015A +;; Hardware multiply register addresses for devices with f5series hardware +;; multiply. +;; The F5xxx series of MCUs support the same 16-bit and 32-bit multiply +;; as the second generation hardware, but they are accessed from different +;; memory registers. +;; These names AREN'T standard. We've appended _F5 to the standard names. +.set MPY_F5, 0x04C0 +.set MPYS_F5, 0x04C2 +.set MAC_F5, 0x04C4 +.set OP2_F5, 0x04C8 +.set RESLO_F5, 0x04CA +.set RESHI_F5, 0x04CC +.set MPY32L_F5, 0x04D0 +.set MPY32H_F5, 0x04D2 +.set MPYS32L_F5, 0x04D4 +.set MPYS32H_F5, 0x04D6 +.set OP2L_F5, 0x04E0 +.set OP2H_F5, 0x04E2 +.set RES0_F5, 0x04E4 +.set RES1_F5, 0x04E6 +.set RES2_F5, 0x04E8 +.set RES3_F5, 0x04EA #if defined MUL_16 ;; First generation MSP430 hardware multiplies ... start_func __mulhi2 __mspabi_mpyi __mspabi_mpyi_hw - mult16 MPY_OP1, MPY_OP2, RESULT_LO + mult16 MPY, OP2, RESLO end_func __mulhi2 - start_func __mulsihi2 __mspabi_mpysl __mspabi_mpysl_hw - mult1632 MPY_OP1_S, MPY_OP2, RESULT_LO, RESULT_HI - end_func __mulsihi2 + start_func __mulhisi2 __mspabi_mpysl __mspabi_mpysl_hw + mult1632 MPYS, OP2, RESLO, RESHI + end_func __mulhisi2 - start_func __umulsihi2 __mspabi_mpyul _mspabi_mpyul_hw - mult1632 MPY_OP1, MPY_OP2, RESULT_LO, RESULT_HI - end_func __umulsihi2 + start_func __umulhisi2 __mspabi_mpyul __mspabi_mpyul_hw + mult1632 MPY, OP2, RESLO, RESHI + end_func __umulhisi2 start_func __mulsi2 __mspabi_mpyl __mspabi_mpyl_hw - mult32 MPY_OP1, MPY_OP2, MAC_OP1, MAC_OP2, RESULT_LO, RESULT_HI + mult32 MPY, OP2, MAC, OP2, RESLO, RESHI end_func __mulsi2 ;; FIXME: We do not have hardware implementations of these ;; routines, so just jump to the software versions instead. - fake_func __muldisi2 __mspabi_mpysll __mspabi_mpysll_hw - fake_func __umuldisi2 __mspabi_mpyull __mspabi_mpyull_hw - fake_func __muldi3 __mspabi_mpyll __mspabi_mpyll_hw + fake_func __mulsidi2 __mspabi_mpysll __mspabi_mpysll_hw + fake_func __umulsidi2 __mspabi_mpyull __mspabi_mpyull_hw + fake_func __muldi3 __mspabi_mpyll __mspabi_mpyll_hw #elif defined MUL_32 ;; Second generation MSP430 hardware multiplies ... start_func __mulhi2 __mspabi_mpyi __mspabi_mpyi_hw - mult16 MPY_OP1, MPY_OP2, RESULT_LO + mult16 MPY, OP2, RESLO end_func __mulhi2 - start_func __mulsihi2 __mspabi_mpysl __mspabi_mpysl_hw - mult1632 MPY_OP1_S, MPY_OP2, RESULT_LO, RESULT_HI - end_func __mulsihi2 + start_func __mulhisi2 __mspabi_mpysl __mspabi_mpysl_hw + mult1632 MPYS, OP2, RESLO, RESHI + end_func __mulhisi2 - start_func __umulsihi2 __mspabi_mpyul _mspabi_mpyul_hw - mult1632 MPY_OP1, MPY_OP2, RESULT_LO, RESULT_HI - end_func __umulsihi2 + start_func __umulhisi2 __mspabi_mpyul __mspabi_mpyul_hw + mult1632 MPY, OP2, RESLO, RESHI + end_func __umulhisi2 start_func __mulsi2_hw32 __mspabi_mpyl __mspabi_mpyl_hw32 - mult32_hw 0x0140, 0x0142, 0x0150, 0x0152, 0x0154, 0x0156 + mult32_hw MPY32L, MPY32H, OP2L, OP2H, RES0, RES1 end_func __mulsi2_hw32 - start_func __muldisi2 __mspabi_mpysll __mspabi_mpysll_hw32 - mult3264_hw 0x0144, 0x146, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158, 0x015A - end_func __muldisi2 + start_func __mulsidi2 __mspabi_mpysll __mspabi_mpysll_hw32 + mult3264_hw MPYS32L, MPYS32H, OP2L, OP2H, RES0, RES1, RES2, RES3 + end_func __mulsidi2 - start_func __umuldisi2 __mspabi_mpyull __mspabi_mpyull_hw32 - mult3264_hw 0x0140, 0x142, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158, 0x015A - end_func __umuldisi2 + start_func __umulsidi2 __mspabi_mpyull __mspabi_mpyull_hw32 + mult3264_hw MPY32L, MPY32H, OP2L, OP2H, RES0, RES1, RES2, RES3 + end_func __umulsidi2 ;; FIXME: Add a hardware version of this function. - fake_func __muldi3 __mspabi_mpyll __mspabi_mpyll_hw32 - + fake_func __muldi3 __mspabi_mpyll __mspabi_mpyll_hw32 + #elif defined MUL_F5 /* The F5xxx series of MCUs support the same 16-bit and 32-bit multiply as the second generation hardware, but they are accessed from different memory registers. */ start_func __mulhi2_f5 __mspabi_mpyi __mspabi_mpyi_f5hw - mult16 0x04C0, 0x04C8, 0x04CA + mult16 MPY_F5, OP2_F5, RESLO_F5 end_func __mulhi2_f5 - start_func __mulsihi2 __mspabi_mpysl __mspabi_mpysl_f5hw - mult1632 0x04C2, 0x04C8, 0x04CA, 0x04CC - end_func __mulsihi2 - - start_func __umulsihi2 __mspabi_mpyul _mspabi_mpyul_f5hw - mult1632 0x04C0, 0x04C8, 0x04CA, 0x04CC - end_func __umulsihi2 + start_func __mulhisi2 __mspabi_mpysl __mspabi_mpysl_f5hw + mult1632 MPYS_F5, OP2_F5, RESLO_F5, RESHI_F5 + end_func __mulhisi2 + + start_func __umulhisi2 __mspabi_mpyul __mspabi_mpyul_f5hw + mult1632 MPY_F5, OP2_F5, RESLO_F5, RESHI_F5 + end_func __umulhisi2 start_func __mulsi2_f5 __mspabi_mpyl __mspabi_mpyl_f5hw - mult32_hw 0x04D0, 0x04D2, 0x04E0, 0x04E2, 0x04E4, 0x04E6 + mult32_hw MPY32L_F5, MPY32H_F5, OP2L_F5, OP2H_F5, RES0_F5, RES1_F5 end_func __mulsi2_f5 - - start_func __muldisi2 __mspabi_mpysll __mspabi_mpysll_f5hw - mult3264_hw 0x04D4, 0x04D6, 0x04E0, 0x04E2, 0x04E4, 0x04E6, 0x04E8, 0x04EA - end_func __muldisi2 - - start_func __umuldisi2 __mspabi_mpyull __mspabi_mpyull_f5hw - mult3264_hw 0x04D0, 0x04D2, 0x04E0, 0x04E2, 0x04E4, 0x04E6, 0x04E8, 0x04EA - end_func __umuldisi2 + + start_func __mulsidi2 __mspabi_mpysll __mspabi_mpysll_f5hw + mult3264_hw MPYS32L_F5, MPYS32H_F5, OP2L_F5, OP2H_F5, RES0_F5, RES1_F5, RES2_F5, RES3_F5 + end_func __mulsidi2 + + start_func __umulsidi2 __mspabi_mpyull __mspabi_mpyull_f5hw + mult3264_hw MPY32L_F5, MPY32H_F5, OP2L_F5, OP2H_F5, RES0_F5, RES1_F5, RES2_F5, RES3_F5 + end_func __umulsidi2 ;; FIXME: Add a hardware version of this function. - fake_func __muldi3 __mspabi_mpyll __mspabi_mpyll_f5hw + fake_func __muldi3 __mspabi_mpyll __mspabi_mpyll_f5hw #else #error MUL type not defined diff --git a/libgcc/config/msp430/lib2mul.c b/libgcc/config/msp430/lib2mul.c index 4ceb147..95a2f1a 100644 --- a/libgcc/config/msp430/lib2mul.c +++ b/libgcc/config/msp430/lib2mul.c @@ -46,6 +46,9 @@ typedef unsigned int uint08_type __attribute__ ((mode (QI))); #elif defined MUL_16 +/* The 16-bit multiply library needs a software version of SI->DI widening + multiplication. */ + signed long long __mspabi_mpysll (signed long a, signed long b) { diff --git a/libgcc/config/pa/fptr.c b/libgcc/config/pa/fptr.c index 6cca747..9d2bb73 100644 --- a/libgcc/config/pa/fptr.c +++ b/libgcc/config/pa/fptr.c @@ -53,7 +53,7 @@ typedef int (*fixup_t) (struct link_map *, unsigned int); extern unsigned int _GLOBAL_OFFSET_TABLE_; static inline int -_dl_read_access_allowed (unsigned int *addr) +_dl_read_access_allowed (unsigned int addr) { int result; @@ -79,7 +79,8 @@ __canonicalize_funcptr_for_compare (fptr_t fptr) { static unsigned int fixup_plabel[2] __attribute__((used)); fixup_t fixup; - unsigned int *got, *iptr, *plabel; + volatile unsigned int *plabel; + unsigned int *got, *iptr, reloc_offset; int i; /* -1 and page 0 are special. -1 is used in crtend to mark the end of @@ -94,17 +95,20 @@ __canonicalize_funcptr_for_compare (fptr_t fptr) to the entry of the PLT stub just before the global offset table. The second word in the plabel contains the relocation offset for the function. */ - plabel = (unsigned int *) ((unsigned int) fptr & ~3); - if (!_dl_read_access_allowed (plabel)) + plabel = (volatile unsigned int *) ((unsigned int) fptr & ~3); + if (!_dl_read_access_allowed ((unsigned int)plabel)) return (unsigned int) fptr; /* Load first word of candidate descriptor. It should be a pointer with word alignment and point to memory that can be read. */ got = (unsigned int *) plabel[0]; if (((unsigned int) got & 3) != 0 - || !_dl_read_access_allowed (got)) + || !_dl_read_access_allowed ((unsigned int)got)) return (unsigned int) fptr; + /* We need to load the relocation offset before the function address. */ + reloc_offset = plabel[1]; + __sync_synchronize(); got = (unsigned int *) (plabel[0] + GOT_FROM_PLT_STUB); /* Return the address of the function if the plabel has been resolved. */ @@ -140,7 +144,7 @@ __canonicalize_funcptr_for_compare (fptr_t fptr) /* Call fixup to resolve the function address. got[1] contains the link_map pointer and plabel[1] the relocation offset. */ - fixup ((struct link_map *) got[1], plabel[1]); + fixup ((struct link_map *) got[1], reloc_offset); return plabel[0]; } diff --git a/libgcc/config/pa/lib2funcs.S b/libgcc/config/pa/lib2funcs.S index b401b61..a2db5b3 100644 --- a/libgcc/config/pa/lib2funcs.S +++ b/libgcc/config/pa/lib2funcs.S @@ -55,13 +55,13 @@ __gcc_plt_call ; An inline version of dyncall so we don't have to worry ; about long calls to millicode, PIC and other complexities. bb,>=,n %r22,30,L$foo - depi 0,31,2,%r22 - ldw 4(%r22),%r19 - ldw 0(%r22),%r22 + depi 0,31,2,%r22 + ldw 0(%r22),%r21 + ldw 4(%r22),%r19 L$foo - ldsid (%r22),%r1 - mtsp %r1,%sr0 - ble 0(%sr0,%r22) + ldsid (%r21),%r1 + mtsp %r1,%sr0 + ble 0(%sr0,%r21) copy %r31,%r2 ldw -8(%r30),%r2 diff --git a/libgcc/config/pa/milli64.S b/libgcc/config/pa/milli64.S index 1e46f50..36040e9 100644 --- a/libgcc/config/pa/milli64.S +++ b/libgcc/config/pa/milli64.S @@ -222,19 +222,26 @@ GSYM($$dyncall) .proc .callinfo millicode .entry - bb,>=,n %r22,30,LREF(1) ; branch if not plabel address - depi 0,31,2,%r22 ; clear the two least significant bits - ldw 4(%r22),%r19 ; load new LTP value - ldw 0(%r22),%r22 ; load address of target -LSYM(1) #ifdef LINUX - bv %r0(%r22) ; branch to the real target + extru,<> %r22,30,1,%r0 ; nullify if plabel bit set + bv,n %r0(%r22) ; branch to target + ldw -2(%r22),%r21 ; load address of target + bv %r0(%r21) ; branch to the real target + ldw 2(%r22),%r19 ; load new LTP value #else + bb,>=,n %r22,30,LREF(1) ; branch if not plabel address + ldw -2(%r22),%r21 ; load address of target to r21 + ldsid (%sr0,%r21),%r1 ; get the "space ident" selected by r21 + ldw 2(%r22),%r19 ; load new LTP value + mtsp %r1,%sr0 ; move that space identifier into sr0 + be 0(%sr0,%r21) ; branch to the real target + stw %r2,-24(%r30) ; save return address into frame marker +LSYM(1) ldsid (%sr0,%r22),%r1 ; get the "space ident" selected by r22 mtsp %r1,%sr0 ; move that space identifier into sr0 - be 0(%sr0,%r22) ; branch to the real target -#endif + be 0(%sr0,%r22) ; branch to the target stw %r2,-24(%r30) ; save return address into frame marker +#endif .exit .procend #endif |