From patchwork Thu Jul 5 06:50:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chung-Lin Tang X-Patchwork-Id: 169071 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 1A91C2C01FA for ; Thu, 5 Jul 2012 16:50:52 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1342075853; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject: References:In-Reply-To:Content-Type:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=zz4s6G1hPPfn0P60+ddywn1VRJQ=; b=FSN2dKTZFzhgCdr KSWy/FswikKI5FdgykTL7jzf+i+DNEpSn64w0S5oH9CZeZlqw4nK1XWYkoPW+GTq WcasQ0/fCZzIwKiTb/ERRMm8rL06xWB07ZWINu01f87Ys6UHqhGqCDX2hHyu+nNc Hpk9e5GR/Qh5oxxDeaCKRBMpFzTQ= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:References:In-Reply-To:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=m7sapGO70hANe1IFUhNoAXhzcX2TiOBnBmeixS5DTaXY4baWmR9dDCTJHKDuER 4bQzvtqed0emrNODDdYVmmscMhO3wz62mGhxfQIa11puv30kkZZNfrKKuok/pSFA sV1SN1dolGKZG3aoCnumhMISp5v3ek4DG634hPLwevq+8=; Received: (qmail 7797 invoked by alias); 5 Jul 2012 06:50:47 -0000 Received: (qmail 7780 invoked by uid 22791); 5 Jul 2012 06:50:44 -0000 X-SWARE-Spam-Status: No, hits=-3.5 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 05 Jul 2012 06:50:29 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1SmftU-0000ly-De from ChungLin_Tang@mentor.com ; Wed, 04 Jul 2012 23:50:28 -0700 Received: from SVR-ORW-FEM-02.mgc.mentorg.com ([147.34.96.206]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Wed, 4 Jul 2012 23:49:38 -0700 Received: from [0.0.0.0] (147.34.91.1) by svr-orw-fem-02.mgc.mentorg.com (147.34.96.168) with Microsoft SMTP Server id 14.1.289.1; Wed, 4 Jul 2012 23:50:26 -0700 Message-ID: <4FF53934.5000408@codesourcery.com> Date: Thu, 5 Jul 2012 14:50:28 +0800 From: Chung-Lin Tang User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20120614 Thunderbird/13.0.1 MIME-Version: 1.0 To: gcc-patches , "Maciej W. Rozycki" , Subject: Re: [PATCH] MIPS16 TLS support for GCC References: <4F0709B3.8060202@codesourcery.com> <87r4zaxwx6.fsf@firetop.home> <4F2BB0C1.4010605@codesourcery.com> In-Reply-To: X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi Richard, picking up a yet uncommitted part of the MIPS16 changes, see below: On 2012/2/3 11:28 PM, Richard Sandiford wrote: > Chung-Lin Tang writes: >>> (2) is interesting if there is also a way to build those MIPS16 libraries >>> out of the box. I'd like such a mechanism to be added at the same time, >>> so that the new support is easy to test. This is still a 4.7 candidate >>> if it can be done in time, although it's probably a little tight. >> >> I assume you mean the libgomp patch? That's mostly a potential bug fix; > > That, plus the CRT_CALL_STATIC_FUNCTION and crtfastmath.c changes. > >> as for MIP16 multilib additions, so far I haven't added any to the >> default mips*-linux* configs, as I guess this should be vendor-stuff >> (though the current additions should clear away any obstacles) > > Vendor stuff would be fine. But to be clear, (2) isn't OK without > some way of getting MIPS16 multilibs out of the box, since it would > otherwise be dead code. > >>> You've given the built-in function the generic name __builtin_thread_pointer. >>> I agree that's a good idea, but I think we should also _treat_ it as a generic >>> function, and make it available on all targets. The actual implementation >>> can be delegated to a target hook. That makes (3) 4.8 material. >> >> Actually, I named and added __builtin_thread_pointer() only because it >> was needed for building glibc (to avoid using 32-bit asm in MIPS16 >> mode), and because some other targets also have it (I'm sure ARM also >> has it, and at least one other) > > All the more reason to make it target-independent. :-) > >>> (Incidentally, I don't think it's correct to define the builtin if TLS >>> isn't available, so if we did keep it as a MIPS-specific function, >>> d->avail would need to be nonnull. There would need to be some other >>> way of indicating that MIPS16 was OK.) >> >> The function is essentially a wrapper for mips_get_tp(), which I don't >> see any guarding for the no TLS case? FWIW, TARGET_HAVE_TLS is just >> defined as HAVE_AS_TLS for MIPS... > > This stuff is inherently guarded by TARGET_HAVE_TLS. > >>>> 5) The libgomp MIPS futex.h header has been adjusted; sys_futex0() has >>>> been modified to be static, non-inlined, nomips16 under MIPS16 mode (for >>>> sake of using 'syscall'). The inline assembly has also been fixed, as >>>> Maciej noticed a possible violation of the MIPS syscall restart >>>> convention; the 'li $2, #syscall_number' must be right before the >>>> syscall insn. >>> >>> This change is OK as part of (2). >> >> Okay thanks, I commit this part soon. > > Please don't! I was unnecessarily confusing here, sorry. I was trying > to say earlier that (2) isn't OK as-is because people have no way of > testing it without changing the sources locally. We need to add some > way of configuring MIPS16 multilibs at the same time. The libgomp > change is OK as part of that patch, but not on its own. I've worked to resolve the issues raised above, notes on the patch: (1) targetm.have_tls is now used to guard the __builtin_thread_pointer() builtin. This adds a handwritten builtin availability predicate, and a new BUILTIN_AVAIL_TLS code in mips.c. I believe this looks conforming to the builtin infrastructure. As for the issue of making __builtin_thread_pointer() target-independent, while it's possible, it seems that most such builtins are functionality that lends to a machine-independent implementation when no target-hooks are provided. A thread pointer builtin does not seem to be one of those. (2) I have included changes in config/mips/t-linux64 to build a MIPS16 libgcc. MULTILIB_OSDIRNAMES has been modified to use the mapping style, to make '-mabi=32 -mips16' a properly linking set of options. This should create the appropriate conditions for committing the MIPS16 libgcc, libgomp changes. (3) Also related to libraries, I edited CRT_CALL_STATIC_FUNCTION to emit a 32-bit code sequence under both MIPS/MIPS16 mode (under O32). As you can see in the original Feb. patch, I had changes to emit a MIPS16 version of these static calls, but with the changes in (2) above, they will not work with the usual situation of a 32-bit MIPS built /lib (.init/.fini will have 32/16-bit code improperly concatenated). The CodeSourcery builds use an independent mips16 sysroot for this, so a MIPS16 CRT_CALL_STATIC_FUNCTION works there. For the usual case, I think making it 32-bit is the compatible choice. Thanks, Chung-Lin 2012-07-05 Chung-Lin Tang libgcc/ * config/mips/crtfastmath.c (set_fast_math): Add 'nomips16' attribute. libgomp/ * config/linux/mips/futex.h (sys_futex0): Change to static function with noinline, nomips16 attributes under MIPS16. Adjust asm statement to place 'li v0,SYS_futex' immediately before syscall insn. gcc/ * config/mips/mips-ftypes.def: Add (0, (POINTER)) entry. * config/mips/mips.c (MIPS_FTYPE_NAME0): New. (mips_builtin_type): Add MIPS_BUILTIN_THREAD_POINTER. (mips_get_tp): Add 'target' parameter for generating to specific reg. (mips_legitimize_tls_address): Update calls to mips_get_tp(). (BUILTIN_AVAIL_TLS): New built-in avail code. (mips_builtin_avail_tls): New built-in availability predicate function. (THREAD_POINTER_BUILTIN): New. (mips_builtins): Add __builtin_mips_thread_pointer and __builtin_thread_pointer using THREAD_POINTER_BUILTIN(). (MIPS_FTYPE_ATYPES0): New. (mips_expand_builtin): Add code to handle built-in avail codes. Add MIPS_BUILTIN_THREAD_POINTER expand case. * config/mips/mips.h (CRT_CALL_STATIC_FUNCTION): Allow O32 version for MIPS16, add nomips16 asm directives. Add error case for MIPS16 under non-O32. * config/mips/t-linux64 (MULTILIB_OSDIRNAMES): Change to use mapping style. (MULTILIB_OPTIONS,MULTILIB_DIRNAMES): Add mips16. (MULTILIB_EXCLUSIONS): Exclude mips16 when not -mabi=32. Index: libgcc/config/mips/crtfastmath.c =================================================================== --- libgcc/config/mips/crtfastmath.c (revision 189224) +++ libgcc/config/mips/crtfastmath.c (working copy) @@ -39,7 +39,7 @@ #define _FPU_GETCW(cw) __asm__ ("cfc1 %0,$31" : "=r" (cw)) #define _FPU_SETCW(cw) __asm__ ("ctc1 %0,$31" : : "r" (cw)) -static void __attribute__((constructor)) +static void __attribute__((constructor,nomips16)) set_fast_math (void) { unsigned int fcr; Index: libgomp/config/linux/mips/futex.h =================================================================== --- libgomp/config/linux/mips/futex.h (revision 189224) +++ libgomp/config/linux/mips/futex.h (working copy) @@ -28,20 +28,26 @@ #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 +#ifdef __mips16 +static void __attribute__((noinline,nomips16)) +#else static inline void +#endif sys_futex0 (int *addr, int op, int val) { - register unsigned long __v0 asm("$2") = (unsigned long) SYS_futex; + register unsigned long __v0 asm("$2"); register unsigned long __a0 asm("$4") = (unsigned long) addr; register unsigned long __a1 asm("$5") = (unsigned long) op; register unsigned long __a2 asm("$6") = (unsigned long) val; register unsigned long __a3 asm("$7") = 0; - __asm volatile ("syscall" + __asm volatile ("li $2, %6\n\t" + "syscall" /* returns $a3 (errno), $v0 (return value) */ : "=r" (__v0), "=r" (__a3) - /* arguments in v0 (syscall) a0-a3 */ - : "r" (__v0), "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a3) + /* arguments in a0-a3, and syscall number */ + : "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a3), + "IK" (SYS_futex) /* clobbers at, v1, t0-t9, memory */ : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "memory"); Index: gcc/config/mips/mips-ftypes.def =================================================================== --- gcc/config/mips/mips-ftypes.def (revision 189224) +++ gcc/config/mips/mips-ftypes.def (working copy) @@ -46,6 +46,8 @@ DEF_MIPS_FTYPE (3, (DI, DI, V4QI, V4QI)) DEF_MIPS_FTYPE (2, (DI, SI, SI)) DEF_MIPS_FTYPE (2, (DI, USI, USI)) +DEF_MIPS_FTYPE (0, (POINTER)) + DEF_MIPS_FTYPE (2, (INT, DF, DF)) DEF_MIPS_FTYPE (2, (INT, SF, SF)) DEF_MIPS_FTYPE (2, (INT, V2SF, V2SF)) Index: gcc/config/mips/t-linux64 =================================================================== --- gcc/config/mips/t-linux64 (revision 189224) +++ gcc/config/mips/t-linux64 (working copy) @@ -18,4 +18,11 @@ MULTILIB_OPTIONS = mabi=n32/mabi=32/mabi=64 MULTILIB_DIRNAMES = n32 32 64 -MULTILIB_OSDIRNAMES = ../lib32 ../lib ../lib64 +MULTILIB_OSDIRNAMES = mabi.n32=../lib32 +MULTILIB_OSDIRNAMES += mabi.32=../lib +MULTILIB_OSDIRNAMES += mabi.64=../lib64 + +# MIPS16 is currently only supported under O32 +MULTILIB_OPTIONS += mips16 +MULTILIB_DIRNAMES += mips16 +MULTILIB_EXCLUSIONS = !mabi=32/mips16 Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c (revision 189224) +++ gcc/config/mips/mips.c (working copy) @@ -181,6 +181,7 @@ enum mips_address_type { }; /* Macros to create an enumeration identifier for a function prototype. */ +#define MIPS_FTYPE_NAME0(A) MIPS_##A##_FTYPE_VOID #define MIPS_FTYPE_NAME1(A, B) MIPS_##A##_FTYPE_##B #define MIPS_FTYPE_NAME2(A, B, C) MIPS_##A##_FTYPE_##B##_##C #define MIPS_FTYPE_NAME3(A, B, C, D) MIPS_##A##_FTYPE_##B##_##C##_##D @@ -231,7 +232,10 @@ enum mips_builtin_type { MIPS_BUILTIN_CMP_SINGLE, /* For generating bposge32 branch instructions in MIPS32 DSP ASE. */ - MIPS_BUILTIN_BPOSGE32 + MIPS_BUILTIN_BPOSGE32, + + /* For generating accesses to the TLS thread pointer. */ + MIPS_BUILTIN_THREAD_POINTER }; /* Invoke MACRO (COND) for each C.cond.fmt condition. */ @@ -2851,11 +2855,12 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_ /* Return a pseudo register that contains the current thread pointer. */ static rtx -mips_get_tp (void) +mips_get_tp (rtx target) { - rtx tp, fn; + rtx fn; + rtx tp = (target != NULL_RTX && REG_P (target) + ? target : gen_reg_rtx (Pmode)); - tp = gen_reg_rtx (Pmode); if (TARGET_MIPS16) { mips_need_mips16_rdhwr_p = true; @@ -2919,7 +2924,7 @@ mips_legitimize_tls_address (rtx loc) break; case TLS_MODEL_INITIAL_EXEC: - tp = mips_get_tp (); + tp = mips_get_tp (NULL_RTX); tmp1 = gen_reg_rtx (Pmode); tmp2 = mips_unspec_address (loc, SYMBOL_GOTTPREL); if (Pmode == DImode) @@ -2931,7 +2936,7 @@ mips_legitimize_tls_address (rtx loc) break; case TLS_MODEL_LOCAL_EXEC: - tmp1 = mips_get_tp (); + tmp1 = mips_get_tp (NULL_RTX); offset = mips_unspec_address (loc, SYMBOL_TPREL); if (mips_split_p[SYMBOL_TPREL]) { @@ -13002,8 +13007,13 @@ mips_prefetch_cookie (rtx write, rtx locality) BUILTIN_AVAIL_NON_MIPS16 The function is available on the current target, but only - in non-MIPS16 mode. */ + in non-MIPS16 mode. + + BUILTIN_AVAIL_TLS + The function is available when the current target supports TLS. +*/ #define BUILTIN_AVAIL_NON_MIPS16 1 +#define BUILTIN_AVAIL_TLS 2 /* Declare an availability predicate for built-in functions that require non-MIPS16 mode and also require COND to be true. @@ -13015,6 +13025,14 @@ mips_prefetch_cookie (rtx write, rtx locality) return (COND) ? BUILTIN_AVAIL_NON_MIPS16 : 0; \ } +/* Declare availability predicate for built-in functions that are + available when the target has TLS. */ +static unsigned int +mips_builtin_avail_tls (void) +{ + return BUILTIN_AVAIL_TLS; +} + /* This structure describes a single built-in function. */ struct mips_builtin_description { /* The code of the main .md file instruction. See mips_builtin_type @@ -13203,6 +13221,13 @@ AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN) #define CODE_FOR_loongson_psubush CODE_FOR_ussubv4hi3 #define CODE_FOR_loongson_psubusb CODE_FOR_ussubv8qi3 +/* Define a MIPS_BUILTIN_THREAD_POINTER builtin. The parameters are fixed, + but we allow both __builtin* and __builtin_mips* prefixes below. */ +#define THREAD_POINTER_BUILTIN(NAME) \ + { CODE_FOR_nothing, MIPS_FP_COND_f, #NAME, \ + MIPS_BUILTIN_THREAD_POINTER, MIPS_POINTER_FTYPE_VOID, \ + mips_builtin_avail_tls } + static const struct mips_builtin_description mips_builtins[] = { DIRECT_BUILTIN (pll_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, paired_single), DIRECT_BUILTIN (pul_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, paired_single), @@ -13486,7 +13511,11 @@ static const struct mips_builtin_description mips_ LOONGSON_BUILTIN_SUFFIX (punpcklwd, s, MIPS_V2SI_FTYPE_V2SI_V2SI), /* Sundry other built-in functions. */ - DIRECT_NO_TARGET_BUILTIN (cache, MIPS_VOID_FTYPE_SI_CVPOINTER, cache) + DIRECT_NO_TARGET_BUILTIN (cache, MIPS_VOID_FTYPE_SI_CVPOINTER, cache), + + /* TLS thread pointer built-in functions. */ + THREAD_POINTER_BUILTIN (__builtin_mips_thread_pointer), + THREAD_POINTER_BUILTIN (__builtin_thread_pointer) }; /* Index I is the function declaration for mips_builtins[I], or null if the @@ -13557,6 +13586,8 @@ mips_build_cvpointer_type (void) /* MIPS_FTYPE_ATYPESN takes N MIPS_FTYPES-like type codes and lists their associated MIPS_ATYPEs. */ +#define MIPS_FTYPE_ATYPES0(A) MIPS_ATYPE_##A + #define MIPS_FTYPE_ATYPES1(A, B) \ MIPS_ATYPE_##A, MIPS_ATYPE_##B @@ -13851,13 +13882,30 @@ mips_expand_builtin (tree exp, rtx target, rtx sub gcc_assert (fcode < ARRAY_SIZE (mips_builtins)); d = &mips_builtins[fcode]; avail = d->avail (); - gcc_assert (avail != 0); - if (TARGET_MIPS16) + switch (avail) { - error ("built-in function %qE not supported for MIPS16", - DECL_NAME (fndecl)); - return ignore ? const0_rtx : CONST0_RTX (mode); + case BUILTIN_AVAIL_NON_MIPS16: + if (TARGET_MIPS16) + { + error ("built-in function %qE not supported for MIPS16", + DECL_NAME (fndecl)); + return ignore ? const0_rtx : CONST0_RTX (mode); + } + break; + + case BUILTIN_AVAIL_TLS: + if (!targetm.have_tls) + { + error ("built-in function %qE not supported when TLS is not available", + DECL_NAME (fndecl)); + return ignore ? const0_rtx : CONST0_RTX (mode); + } + break; + + default: + gcc_unreachable (); } + switch (d->builtin_type) { case MIPS_BUILTIN_DIRECT: @@ -13881,6 +13929,9 @@ mips_expand_builtin (tree exp, rtx target, rtx sub case MIPS_BUILTIN_BPOSGE32: return mips_expand_builtin_bposge (d->builtin_type, target); + + case MIPS_BUILTIN_THREAD_POINTER: + return mips_get_tp (target); } gcc_unreachable (); } Index: gcc/config/mips/mips.h =================================================================== --- gcc/config/mips/mips.h (revision 189224) +++ gcc/config/mips/mips.h (working copy) @@ -2781,7 +2781,6 @@ while (0) #define STORE_BY_PIECES_P(SIZE, ALIGN) \ mips_store_by_pieces_p (SIZE, ALIGN) -#ifndef __mips16 /* Since the bits of the _init and _fini function is spread across many object files, each potentially with its own GP, we must assume we need to load our GP. We don't preserve $gp or $ra, since each @@ -2790,16 +2789,22 @@ while (0) #if (defined _ABIO32 && _MIPS_SIM == _ABIO32) #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ asm (SECTION_OP "\n\ + .set push\n\ + .set nomips16\n\ .set noreorder\n\ bal 1f\n\ nop\n\ 1: .cpload $31\n\ .set reorder\n\ jal " USER_LABEL_PREFIX #FUNC "\n\ + .set pop\n\ " TEXT_SECTION_ASM_OP); #endif /* Switch to #elif when we're no longer limited by K&R C. */ #if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \ || (defined _ABI64 && _MIPS_SIM == _ABI64) +#ifdef __mips16 +#error "MIPS16 support for non O32 ABIs not implemented" +#endif #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ asm (SECTION_OP "\n\ .set noreorder\n\ @@ -2810,7 +2815,6 @@ while (0) jal " USER_LABEL_PREFIX #FUNC "\n\ " TEXT_SECTION_ASM_OP); #endif -#endif #ifndef HAVE_AS_TLS #define HAVE_AS_TLS 0