From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 62869 invoked by alias); 3 Dec 2018 19:18:35 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 62841 invoked by uid 89); 3 Dec 2018 19:18:34 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.6 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_COUK,KAM_LAZY_DOMAIN_SECURITY,KAM_STOCKGEN autolearn=ham version=3.3.2 spammy=retired, sk:IDENTIF X-HELO: smtp2.wavenetuk.net Received: from smtp2.wavenetuk.net (HELO smtp2.wavenetuk.net) (195.26.37.10) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 03 Dec 2018 19:18:25 +0000 Received: from euterpe-sie.home (host81-138-1-83.in-addr.btopenworld.com [81.138.1.83]) by smtp2.wavenetuk.net (Postfix) with ESMTPA id 5B5DA600106; Mon, 3 Dec 2018 19:18:23 +0000 (GMT) From: Iain Sandoe Message-Id: <3F06E9FC-D02C-47D4-B223-523FA2EDEF4A@sandoe.co.uk> Content-Type: multipart/mixed; boundary="Apple-Mail=_ECB4F749-F248-46F2-9160-E4E1E86E4236" Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: Re: [Patch, ppc/darwin 2/2] Make Darwin's call handling follow the style of AIX/ELFv2/sysv. Date: Mon, 03 Dec 2018 19:18:00 -0000 In-Reply-To: <717C1E4D-2D29-4278-BD07-9E97512F3A7E@sandoe.co.uk> Cc: Segher Boessenkool , Alan Modra To: GCC-patches References: <717C1E4D-2D29-4278-BD07-9E97512F3A7E@sandoe.co.uk> X-SW-Source: 2018-12/txt/msg00115.txt.bz2 --Apple-Mail=_ECB4F749-F248-46F2-9160-E4E1E86E4236 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Content-length: 15743 > On 3 Dec 2018, at 01:28, Iain Sandoe wrote: > The second patch normalises Darwin=E2=80=99s call handling to follow the = same pattern that Alan introduced recently. revised version, on top of the revised patch 1 attached. I=E2=80=99ve take= n the opportunity to reduce the number of TARGET_MACHO conditionals in rs60= 00.md (handle in rs6000.c instead) Iain > Hopefully it makes it clearer where there are differences (actually quite= small in this case, but enough to make it better to separate the lowering)= . It isn=E2=80=99t needed to fix bootstrap, but it was a good time to figu= re it out when dealing with this. >=20 > OK for trunk / next stage #1 / comments? > Iain >=20 > gcc/ >=20 > * config/rs6000/rs6000-protos.h (rs6000_call_darwin, rs6000_sibcall_darw= in): New. > (macho_call_template): remove. > * config/rs6000/rs6000.c (get_prev_label): Forward declaration.=20 > (rs6000_call_template_1): Handle Darwin. (macho_call_template): Remove. > (rs6000_call_sysv): Remove handling for Darwin, save cookie value. > (rs6000_call_darwin_1, rs6000_call_darwin, rs6000_sibcall_darwin): New. > * config/rs6000/rs6000.md (define_expand =E2=80=9Ccall=E2=80=9D): Handle= Darwin with its own > expander. (define_expand =E2=80=9Ccall_value=E2=80=9D): Likewise. (defin= e_expand =E2=80=9Csibcall=E2=80=9D): Likewise. > (define_expand =E2=80=9Csibcall_value=E2=80=9D): Likewise. (call_nonloc= al_sysv): Remove=20 > Darwin special-casing. (call_value_nonlocal_sysv): Likewise. >=20 > From cf45459dc7f317bcf5f415219884e6b846fe01a1 Mon Sep 17 00:00:00 2001 > From: Iain Sandoe > Date: Sat, 1 Dec 2018 16:23:20 +0000 > Subject: [PATCH] [darwin,ppc] Update call expansions to follow the new sc= heme. >=20 > This also makes it a bit more apparent what we can remove when the > mlongcall optimisation is removed. > --- > gcc/config/rs6000/rs6000-protos.h | 8 +- > gcc/config/rs6000/rs6000.c | 195 +++++++++++++++++++++--------- > gcc/config/rs6000/rs6000.md | 47 +++++-- > 3 files changed, 180 insertions(+), 70 deletions(-) >=20 > diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000= -protos.h > index dfee1f28aa..6d2b7ed917 100644 > --- a/gcc/config/rs6000/rs6000-protos.h > +++ b/gcc/config/rs6000/rs6000-protos.h > @@ -199,6 +199,10 @@ extern void rs6000_call_aix (rtx, rtx, rtx, rtx); > extern void rs6000_sibcall_aix (rtx, rtx, rtx, rtx); > extern void rs6000_call_sysv (rtx, rtx, rtx, rtx); > extern void rs6000_sibcall_sysv (rtx, rtx, rtx, rtx); > +#if TARGET_MACHO > +extern void rs6000_call_darwin (rtx, rtx, rtx, rtx); > +extern void rs6000_sibcall_darwin (rtx, rtx, rtx, rtx); > +#endif > extern void rs6000_aix_asm_output_dwarf_table_ref (char *); > extern void get_ppc476_thunk_name (char name[32]); > extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins); > @@ -226,10 +230,6 @@ extern void (*rs6000_target_modify_macros_ptr) (bool= , HOST_WIDE_INT, > /* Declare functions in rs6000-d.c */ > extern void rs6000_d_target_versions (void); >=20 > -#if TARGET_MACHO > -char *macho_call_template (rtx_insn *, rtx *, int, int); > -#endif > - > #ifdef NO_DOLLAR_IN_LABEL > const char * rs6000_xcoff_strip_dollar (const char *); > #endif > diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c > index bce968516c..5fef3fa036 100644 > --- a/gcc/config/rs6000/rs6000.c > +++ b/gcc/config/rs6000/rs6000.c > @@ -1364,6 +1364,7 @@ static rtx rs6000_darwin64_record_arg (CUMULATIVE_A= RGS *, const_tree, > bool, bool); > #if TARGET_MACHO > static void macho_branch_islands (void); > +static tree get_prev_label (tree); > #endif > static rtx rs6000_legitimize_reload_address (rtx, machine_mode, int, int, > int, int *); > @@ -21513,13 +21514,39 @@ rs6000_call_template_1 (rtx *operands, unsigned= int funop, bool sibcall) > ? "+32768" : "")); >=20 > static char str[32]; /* 2 spare */ > - if (DEFAULT_ABI =3D=3D ABI_AIX || DEFAULT_ABI =3D=3D ABI_ELFv2 > - || DEFAULT_ABI =3D=3D ABI_DARWIN) > + if (DEFAULT_ABI =3D=3D ABI_AIX || DEFAULT_ABI =3D=3D ABI_ELFv2) > sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg, > sibcall ? "" : "\n\tnop"); > else if (DEFAULT_ABI =3D=3D ABI_V4) > sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg, > flag_pic ? "@plt" : ""); > +#if TARGET_MACHO > + /* If/when we remove the mlongcall opt, we can share the AIX/ELFv2 cas= e. */ > + else if (DEFAULT_ABI =3D=3D ABI_DARWIN) > + { > + /* The cookie is in operand func+2. */ > + gcc_checking_assert (GET_CODE (operands[funop + 2]) =3D=3D CONST_I= NT); > + int cookie =3D INTVAL (operands[funop + 2]); > + if (cookie & CALL_LONG) > + { > + tree funname =3D get_identifier (XSTR (operands[funop], 0)); > + tree labelname =3D get_prev_label (funname); > + gcc_checking_assert (labelname && !sibcall); > + > + /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl' > + instruction will reach 'foo', otherwise link as 'bl L42'". > + "L42" should be a 'branch island', that will do a far jump to > + 'foo'. Branch islands are generated in > + macho_branch_islands(). */ > + sprintf (str, "jbsr %%z%u,%.10s", funop, > + IDENTIFIER_POINTER (labelname)); > + } > + else > + /* Same as AIX or ELFv2, except to keep backwards compat, no nop > + after the call. */ > + sprintf (str, "b%s %s%s", sibcall ? "" : "l", z, arg); > + } > +#endif > else > gcc_unreachable (); > return str; > @@ -33167,49 +33194,6 @@ get_prev_label (tree function_name) > return NULL_TREE; > } >=20 > -/* INSN is either a function call or a millicode call. It may have an > - unconditional jump in its delay slot. > - > - CALL_DEST is the routine we are calling. */ > - > -char * > -macho_call_template (rtx_insn *insn, rtx *operands, int dest_operand_num= ber, > - int cookie_operand_number) > -{ > - static char buf[256]; > - if (darwin_emit_branch_islands > - && GET_CODE (operands[dest_operand_number]) =3D=3D SYMBOL_REF > - && (INTVAL (operands[cookie_operand_number]) & CALL_LONG)) > - { > - tree labelname; > - tree funname =3D get_identifier (XSTR (operands[dest_operand_numbe= r], 0)); > - > - if (no_previous_def (funname)) > - { > - rtx label_rtx =3D gen_label_rtx (); > - char *label_buf, temp_buf[256]; > - ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L", > - CODE_LABEL_NUMBER (label_rtx)); > - label_buf =3D temp_buf[0] =3D=3D '*' ? temp_buf + 1 : temp_buf; > - labelname =3D get_identifier (label_buf); > - add_compiler_branch_island (labelname, funname, insn_line (insn)); > - } > - else > - labelname =3D get_prev_label (funname); > - > - /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl' > - instruction will reach 'foo', otherwise link as 'bl L42'". > - "L42" should be a 'branch island', that will do a far jump to > - 'foo'. Branch islands are generated in > - macho_branch_islands(). */ > - sprintf (buf, "jbsr %%z%d,%.246s", > - dest_operand_number, IDENTIFIER_POINTER (labelname)); > - } > - else > - sprintf (buf, "bl %%z%d", dest_operand_number); > - return buf; > -} > - > /* Generate PIC and indirect symbol stubs. */ >=20 > void > @@ -37932,13 +37916,13 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx= tlsarg, rtx cookie) > rtx call[3]; > rtx insn; > rtx abi_reg =3D NULL_RTX; > + int cookie_val =3D INTVAL (cookie); >=20 > if (global_tlsarg) > tlsarg =3D global_tlsarg; >=20 > /* Handle longcall attributes. */ > - if ((INTVAL (cookie) & CALL_LONG) !=3D 0 > - && DEFAULT_ABI !=3D ABI_DARWIN /* Darwin does it's own thing. */ > + if ((cookie_val & CALL_LONG) !=3D 0 > && GET_CODE (func_desc) =3D=3D SYMBOL_REF) > { > func =3D rs6000_longcall_ref (func_desc, tlsarg); > @@ -37979,14 +37963,8 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx = tlsarg, rtx cookie) > if (value !=3D NULL_RTX) > call[0] =3D gen_rtx_SET (value, call[0]); >=20 > - if (DEFAULT_ABI =3D=3D ABI_DARWIN && TARGET_32BIT) > - call[1] =3D gen_rtx_USE (VOIDmode, GEN_INT (INTVAL (cookie))); > - else > - { > - unsigned int mask =3D CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS; > - call[1] =3D gen_rtx_USE (VOIDmode, GEN_INT (INTVAL (cookie) & mask= )); > - } > - > + unsigned int mask =3D CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS; > + call[1] =3D gen_rtx_USE (VOIDmode, GEN_INT (cookie_val & mask)); > call[2] =3D gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO)); >=20 > insn =3D gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call)); > @@ -38060,6 +38038,113 @@ rs6000_sibcall_sysv (rtx value, rtx func_desc, = rtx tlsarg, rtx cookie) > use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg); > } >=20 > +#if TARGET_MACHO > + > +/* Expand code to perform a call under the Darwin ABI. > + Modulo handling of mlongcall, this is much the same as sysv. > + if/when the longcall optimisation is removed, we could drop this > + code and use the sysv case (taking care to avoid the tls stuff). > + > + We can use this for sibcalls too, if needed. */ > + > +void > +rs6000_call_darwin_1 (rtx value, rtx func_desc, rtx tlsarg, > + rtx cookie, bool sibcall) > +{ > + rtx func =3D func_desc; > + rtx func_addr; > + rtx call[3]; > + rtx insn; > + int cookie_val =3D INTVAL (cookie); > + bool make_island =3D false; > + > + /* Handle longcall attributes, there are two cases for Darwin: > + 1) Newer linkers are capable of synthesising any branch islands nee= ded. > + 2) We need a helper branch island synthesised by the compiler. > + The second case has mostly been retired and we don't use it for m64. > + In fact, it's is an optimisation, we could just indirect as sysv do= es.. > + ... however, backwards compatibility for now. > + If we're going to use this, then we need to keep the CALL_LONG bit = set, > + so that we can pick up the special insn form later. */ > + if ((cookie_val & CALL_LONG) !=3D 0 > + && GET_CODE (func_desc) =3D=3D SYMBOL_REF) > + { > + if (darwin_emit_branch_islands && TARGET_32BIT) > + make_island =3D true; /* Do nothing yet, retain the CALL_LONG flag. */ > + else > + { > + /* The linker is capable of doing this, but the user explicitly > + asked for -mlongcall, so we'll do the 'normal' version. */ > + func =3D rs6000_longcall_ref (func_desc, NULL_RTX); > + cookie_val &=3D ~CALL_LONG; /* Handled, zap it. */ > + } > + } > + > + /* Handle indirect calls. */ > + if (GET_CODE (func) !=3D SYMBOL_REF) > + { > + func =3D force_reg (Pmode, func); > + > + /* Indirect calls via CTR are strongly preferred over indirect > + calls via LR, and are required for indirect sibcalls, so move > + the address there. */ > + func_addr =3D gen_rtx_REG (Pmode, CTR_REGNO); > + emit_move_insn (func_addr, func); > + } > + else > + func_addr =3D func; > + > + /* Create the call. */ > + call[0] =3D gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), t= lsarg); > + if (value !=3D NULL_RTX) > + call[0] =3D gen_rtx_SET (value, call[0]); > + > + call[1] =3D gen_rtx_USE (VOIDmode, GEN_INT (cookie_val)); > + > + if (sibcall) > + call[2] =3D simple_return_rtx; > + else > + call[2] =3D gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO)= ); > + > + insn =3D gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call)); > + insn =3D emit_call_insn (insn); > + /* Now we have the debug info in the insn, we can set up the branch is= land > + if we're using one. */ > + if (make_island) > + { > + tree funname =3D get_identifier (XSTR (func_desc, 0)); > + > + if (no_previous_def (funname)) > + { > + rtx label_rtx =3D gen_label_rtx (); > + char *label_buf, temp_buf[256]; > + ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L", > + CODE_LABEL_NUMBER (label_rtx)); > + label_buf =3D temp_buf[0] =3D=3D '*' ? temp_buf + 1 : temp_buf; > + tree labelname =3D get_identifier (label_buf); > + add_compiler_branch_island (labelname, funname, > + insn_line ((const rtx_insn*)insn)); > + } > + } > +} > + > +void > +rs6000_call_darwin (rtx value, rtx func_desc, > + rtx tlsarg ATTRIBUTE_UNUSED, rtx cookie) > +{ > + rs6000_call_darwin_1 (value, func_desc, tlsarg, cookie, false); > +} > + > + > +void > +rs6000_sibcall_darwin (rtx value, rtx func_desc, > + rtx tlsarg ATTRIBUTE_UNUSED, rtx cookie) > +{ > + rs6000_call_darwin_1 (value, func_desc, tlsarg, cookie, true); > +} > + > +#endif > + > /* Return whether we need to always update the saved TOC pointer when we = update > the stack pointer. */ >=20 > diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md > index d684bed3ae..e4a71439ef 100644 > --- a/gcc/config/rs6000/rs6000.md > +++ b/gcc/config/rs6000/rs6000.md > @@ -10289,12 +10289,20 @@ > DONE; > } >=20 > - if (DEFAULT_ABI =3D=3D ABI_V4 || DEFAULT_ABI =3D=3D ABI_DARWIN) > + if (DEFAULT_ABI =3D=3D ABI_V4) > { > rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]); > DONE; > } >=20 > +#if TARGET_MACHO > + if (DEFAULT_ABI =3D=3D ABI_DARWIN) > + { > + rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2= ]); > + DONE; > + } > +#endif > + > if (GET_CODE (operands[0]) !=3D SYMBOL_REF) > operands[0] =3D force_reg (Pmode, operands[0]); > }) > @@ -10322,12 +10330,20 @@ > DONE; > } >=20 > - if (DEFAULT_ABI =3D=3D ABI_V4 || DEFAULT_ABI =3D=3D ABI_DARWIN) > + if (DEFAULT_ABI =3D=3D ABI_V4) > { > rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3= ]); > DONE; > } >=20 > +#if TARGET_MACHO > + if (DEFAULT_ABI =3D=3D ABI_DARWIN) > + { > + rs6000_call_darwin (operands[0], operands[1], operands[2], operand= s[3]); > + DONE; > + } > +#endif > + > if (GET_CODE (operands[1]) !=3D SYMBOL_REF) > operands[1] =3D force_reg (Pmode, operands[1]); > }) > @@ -10463,11 +10479,7 @@ > else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) > output_asm_insn ("creqv 6,6,6", operands); >=20 > -#if TARGET_MACHO > - return macho_call_template (insn, operands, 0, 2); > -#else > return rs6000_call_template (operands, 0); > -#endif > } > "DEFAULT_ABI =3D=3D ABI_V4 > && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) > @@ -10549,11 +10561,7 @@ > else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) > output_asm_insn ("creqv 6,6,6", operands); >=20 > -#if TARGET_MACHO > - return macho_call_template (insn, operands, 1, 3); > -#else > return rs6000_call_template (operands, 1); > -#endif > } > "DEFAULT_ABI =3D=3D ABI_V4 > && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) > @@ -10771,6 +10779,14 @@ > rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2= ]); > DONE; > } > + > +#if TARGET_MACHO > + if (DEFAULT_ABI =3D=3D ABI_DARWIN) > + { > + rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operand= s[2]); > + DONE; > + } > +#endif > }) >=20 > (define_expand "sibcall_value" > @@ -10797,11 +10813,20 @@ > DONE; > } >=20 > - if (DEFAULT_ABI =3D=3D ABI_V4 || DEFAULT_ABI =3D=3D ABI_DARWIN) > + if (DEFAULT_ABI =3D=3D ABI_V4) > { > rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operand= s[3]); > DONE; > } > + > +#if TARGET_MACHO > + if (DEFAULT_ABI =3D=3D ABI_DARWIN) > + { > + rs6000_sibcall_darwin (operands[0], operands[1], > + operands[2], operands[3]); > + DONE; > + } > +#endif > }) >=20 > (define_insn "*sibcall_local32" > --=20 > 2.17.1 --Apple-Mail=_ECB4F749-F248-46F2-9160-E4E1E86E4236 Content-Disposition: attachment; filename=darwin-ppc-calls-2-of-2-v2.txt Content-Type: text/plain; x-unix-mode=0644; name="darwin-ppc-calls-2-of-2-v2.txt" Content-Transfer-Encoding: quoted-printable Content-length: 13680 =46rom 82ac030d49fd2ae78b75a350c5efc59375df42a6 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sat, 1 Dec 2018 16:23:20 +0000 Subject: [PATCH] [darwin,ppc] Update call expansions to follow the new sche= me. This also makes it a bit more apparent what we can remove when the mlongcall optimisation is removed. --- gcc/config/rs6000/rs6000-protos.h | 6 +- gcc/config/rs6000/rs6000.c | 205 ++++++++++++++++++++++-------- gcc/config/rs6000/rs6000.md | 24 ++-- 3 files changed, 163 insertions(+), 72 deletions(-) diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-p= rotos.h index dfee1f28aa..5ac864e83e 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -199,6 +199,8 @@ extern void rs6000_call_aix (rtx, rtx, rtx, rtx); extern void rs6000_sibcall_aix (rtx, rtx, rtx, rtx); extern void rs6000_call_sysv (rtx, rtx, rtx, rtx); extern void rs6000_sibcall_sysv (rtx, rtx, rtx, rtx); +extern void rs6000_call_darwin (rtx, rtx, rtx, rtx); +extern void rs6000_sibcall_darwin (rtx, rtx, rtx, rtx); extern void rs6000_aix_asm_output_dwarf_table_ref (char *); extern void get_ppc476_thunk_name (char name[32]); extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins); @@ -226,10 +228,6 @@ extern void (*rs6000_target_modify_macros_ptr) (bool, = HOST_WIDE_INT, /* Declare functions in rs6000-d.c */ extern void rs6000_d_target_versions (void); =20 -#if TARGET_MACHO -char *macho_call_template (rtx_insn *, rtx *, int, int); -#endif - #ifdef NO_DOLLAR_IN_LABEL const char * rs6000_xcoff_strip_dollar (const char *); #endif diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index bce968516c..a036a3cb50 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1364,6 +1364,7 @@ static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARG= S *, const_tree, bool, bool); #if TARGET_MACHO static void macho_branch_islands (void); +static tree get_prev_label (tree); #endif static rtx rs6000_legitimize_reload_address (rtx, machine_mode, int, int, int, int *); @@ -21513,13 +21514,39 @@ rs6000_call_template_1 (rtx *operands, unsigned i= nt funop, bool sibcall) ? "+32768" : "")); =20 static char str[32]; /* 2 spare */ - if (DEFAULT_ABI =3D=3D ABI_AIX || DEFAULT_ABI =3D=3D ABI_ELFv2 - || DEFAULT_ABI =3D=3D ABI_DARWIN) + if (DEFAULT_ABI =3D=3D ABI_AIX || DEFAULT_ABI =3D=3D ABI_ELFv2) sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg, sibcall ? "" : "\n\tnop"); else if (DEFAULT_ABI =3D=3D ABI_V4) sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg, flag_pic ? "@plt" : ""); +#if TARGET_MACHO + /* If/when we remove the mlongcall opt, we can share the AIX/ELGv2 case.= */ + else if (DEFAULT_ABI =3D=3D ABI_DARWIN) + { + /* The cookie is in operand func+2. */ + gcc_checking_assert (GET_CODE (operands[funop + 2]) =3D=3D CONST_INT= ); + int cookie =3D INTVAL (operands[funop + 2]); + if (cookie & CALL_LONG) + { + tree funname =3D get_identifier (XSTR (operands[funop], 0)); + tree labelname =3D get_prev_label (funname); + gcc_checking_assert (labelname && !sibcall); + + /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl' + instruction will reach 'foo', otherwise link as 'bl L42'". + "L42" should be a 'branch island', that will do a far jump to + 'foo'. Branch islands are generated in + macho_branch_islands(). */ + sprintf (str, "jbsr %%z%u,%.10s", funop, + IDENTIFIER_POINTER (labelname)); + } + else + /* Same as AIX or ELFv2, except to keep backwards compat, no nop + after the call. */ + sprintf (str, "b%s %s%s", sibcall ? "" : "l", z, arg); + } +#endif else gcc_unreachable (); return str; @@ -33122,7 +33149,7 @@ macho_branch_islands (void) } else { - strcat (tmp_buf, ":\nlis r12,hi16("); + strcat (tmp_buf, ":\n\tlis r12,hi16("); strcat (tmp_buf, name_buf); strcat (tmp_buf, ")\n\tori r12,r12,lo16("); strcat (tmp_buf, name_buf); @@ -33167,49 +33194,6 @@ get_prev_label (tree function_name) return NULL_TREE; } =20 -/* INSN is either a function call or a millicode call. It may have an - unconditional jump in its delay slot. - - CALL_DEST is the routine we are calling. */ - -char * -macho_call_template (rtx_insn *insn, rtx *operands, int dest_operand_numbe= r, - int cookie_operand_number) -{ - static char buf[256]; - if (darwin_emit_branch_islands - && GET_CODE (operands[dest_operand_number]) =3D=3D SYMBOL_REF - && (INTVAL (operands[cookie_operand_number]) & CALL_LONG)) - { - tree labelname; - tree funname =3D get_identifier (XSTR (operands[dest_operand_number]= , 0)); - - if (no_previous_def (funname)) - { - rtx label_rtx =3D gen_label_rtx (); - char *label_buf, temp_buf[256]; - ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L", - CODE_LABEL_NUMBER (label_rtx)); - label_buf =3D temp_buf[0] =3D=3D '*' ? temp_buf + 1 : temp_buf; - labelname =3D get_identifier (label_buf); - add_compiler_branch_island (labelname, funname, insn_line (insn)); - } - else - labelname =3D get_prev_label (funname); - - /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl' - instruction will reach 'foo', otherwise link as 'bl L42'". - "L42" should be a 'branch island', that will do a far jump to - 'foo'. Branch islands are generated in - macho_branch_islands(). */ - sprintf (buf, "jbsr %%z%d,%.246s", - dest_operand_number, IDENTIFIER_POINTER (labelname)); - } - else - sprintf (buf, "bl %%z%d", dest_operand_number); - return buf; -} - /* Generate PIC and indirect symbol stubs. */ =20 void @@ -37932,13 +37916,13 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx t= lsarg, rtx cookie) rtx call[3]; rtx insn; rtx abi_reg =3D NULL_RTX; + int cookie_val =3D INTVAL (cookie); =20 if (global_tlsarg) tlsarg =3D global_tlsarg; =20 /* Handle longcall attributes. */ - if ((INTVAL (cookie) & CALL_LONG) !=3D 0 - && DEFAULT_ABI !=3D ABI_DARWIN /* Darwin does it's own thing. */ + if ((cookie_val & CALL_LONG) !=3D 0 && GET_CODE (func_desc) =3D=3D SYMBOL_REF) { func =3D rs6000_longcall_ref (func_desc, tlsarg); @@ -37979,14 +37963,8 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tl= sarg, rtx cookie) if (value !=3D NULL_RTX) call[0] =3D gen_rtx_SET (value, call[0]); =20 - if (DEFAULT_ABI =3D=3D ABI_DARWIN && TARGET_32BIT) - call[1] =3D gen_rtx_USE (VOIDmode, GEN_INT (INTVAL (cookie))); - else - { - unsigned int mask =3D CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS; - call[1] =3D gen_rtx_USE (VOIDmode, GEN_INT (INTVAL (cookie) & mask)); - } - + unsigned int mask =3D CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS; + call[1] =3D gen_rtx_USE (VOIDmode, GEN_INT (cookie_val & mask)); call[2] =3D gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO)); =20 insn =3D gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call)); @@ -38060,6 +38038,121 @@ rs6000_sibcall_sysv (rtx value, rtx func_desc, rt= x tlsarg, rtx cookie) use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg); } =20 +#if TARGET_MACHO + +/* Expand code to perform a call under the Darwin ABI. + Modulo handling of mlongcall, this is much the same as sysv. + if/when the longcall optimisation is removed, we could drop this + code and use the sysv case (taking care to avoid the tls stuff). + + We can use this for sibcalls too, if needed. */ + +void +rs6000_call_darwin_1 (rtx value, rtx func_desc, rtx tlsarg, + rtx cookie, bool sibcall) +{ + rtx func =3D func_desc; + rtx func_addr; + rtx call[3]; + rtx insn; + int cookie_val =3D INTVAL (cookie); + bool make_island =3D false; + + /* Handle longcall attributes, there are two cases for Darwin: + 1) Newer linkers are capable of synthesising any branch islands neede= d. + 2) We need a helper branch island synthesised by the compiler. + The second case has mostly been retired and we don't use it for m64. + In fact, it's is an optimisation, we could just indirect as sysv does= .. + ... however, backwards compatibility for now. + If we're going to use this, then we need to keep the CALL_LONG bit se= t, + so that we can pick up the special insn form later. */ + if ((cookie_val & CALL_LONG) !=3D 0 + && GET_CODE (func_desc) =3D=3D SYMBOL_REF) + { + if (darwin_emit_branch_islands && TARGET_32BIT) + make_island =3D true; /* Do nothing yet, retain the CALL_LONG flag. */ + else + { + /* The linker is capable of doing this, but the user explicitly + asked for -mlongcall, so we'll do the 'normal' version. */ + func =3D rs6000_longcall_ref (func_desc, NULL_RTX); + cookie_val &=3D ~CALL_LONG; /* Handled, zap it. */ + } + } + + /* Handle indirect calls. */ + if (GET_CODE (func) !=3D SYMBOL_REF) + { + func =3D force_reg (Pmode, func); + + /* Indirect calls via CTR are strongly preferred over indirect + calls via LR, and are required for indirect sibcalls, so move + the address there. */ + func_addr =3D gen_rtx_REG (Pmode, CTR_REGNO); + emit_move_insn (func_addr, func); + } + else + func_addr =3D func; + + /* Create the call. */ + call[0] =3D gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), tls= arg); + if (value !=3D NULL_RTX) + call[0] =3D gen_rtx_SET (value, call[0]); + + call[1] =3D gen_rtx_USE (VOIDmode, GEN_INT (cookie_val)); + + if (sibcall) + call[2] =3D simple_return_rtx; + else + call[2] =3D gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO)); + + insn =3D gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call)); + insn =3D emit_call_insn (insn); + /* Now we have the debug info in the insn, we can set up the branch isla= nd + if we're using one. */ + if (make_island) + { + tree funname =3D get_identifier (XSTR (func_desc, 0)); + + if (no_previous_def (funname)) + { + rtx label_rtx =3D gen_label_rtx (); + char *label_buf, temp_buf[256]; + ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L", + CODE_LABEL_NUMBER (label_rtx)); + label_buf =3D temp_buf[0] =3D=3D '*' ? temp_buf + 1 : temp_buf; + tree labelname =3D get_identifier (label_buf); + add_compiler_branch_island (labelname, funname, + insn_line ((const rtx_insn*)insn)); + } + } +} +#endif + +void +rs6000_call_darwin (rtx value ATTRIBUTE_UNUSED, rtx func_desc ATTRIBUTE_UN= USED, + rtx tlsarg ATTRIBUTE_UNUSED, rtx cookie ATTRIBUTE_UNUSED) +{ +#if TARGET_MACHO + rs6000_call_darwin_1 (value, func_desc, tlsarg, cookie, false); +#else + gcc_unreachable(); +#endif +} + + +void +rs6000_sibcall_darwin (rtx value ATTRIBUTE_UNUSED, rtx func_desc ATTRIBUTE= _UNUSED, + rtx tlsarg ATTRIBUTE_UNUSED, rtx cookie ATTRIBUTE_UNUSED) +{ +#if TARGET_MACHO + rs6000_call_darwin_1 (value, func_desc, tlsarg, cookie, true); +#else + gcc_unreachable(); +#endif +} + + /* Return whether we need to always update the saved TOC pointer when we u= pdate the stack pointer. */ =20 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index f84b09b35a..6e6c984a51 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10285,8 +10285,10 @@ =20 if (DEFAULT_ABI =3D=3D ABI_AIX || DEFAULT_ABI =3D=3D ABI_ELFv2) rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]); - else + else if (DEFAULT_ABI =3D=3D ABI_V4) rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]); + else + rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]); =20 DONE; }) @@ -10310,8 +10312,10 @@ =20 if (DEFAULT_ABI =3D=3D ABI_AIX || DEFAULT_ABI =3D=3D ABI_ELFv2) rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]); - else + else if (DEFAULT_ABI =3D=3D ABI_V4) rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]); + else + rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]= ); =20 DONE; }) @@ -10447,11 +10451,7 @@ else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); =20 -#if TARGET_MACHO - return macho_call_template (insn, operands, 0, 2); -#else return rs6000_call_template (operands, 0); -#endif } "DEFAULT_ABI =3D=3D ABI_V4 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) @@ -10533,11 +10533,7 @@ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); =20 -#if TARGET_MACHO - return macho_call_template (insn, operands, 1, 3); -#else return rs6000_call_template (operands, 1); -#endif } "DEFAULT_ABI =3D=3D ABI_V4 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) @@ -10746,8 +10742,10 @@ =20 if (DEFAULT_ABI =3D=3D ABI_AIX || DEFAULT_ABI =3D=3D ABI_ELFv2) rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); - else + else if (DEFAULT_ABI =3D=3D ABI_V4) rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]); + else + rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]= ); =20 DONE; }) @@ -10772,8 +10770,10 @@ =20 if (DEFAULT_ABI =3D=3D ABI_AIX || DEFAULT_ABI =3D=3D ABI_ELFv2) rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]= ); - else + else if (DEFAULT_ABI =3D=3D ABI_V4) rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3= ]); + else + rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands= [3]); =20 DONE; }) --=20 2.17.1 --Apple-Mail=_ECB4F749-F248-46F2-9160-E4E1E86E4236 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii Content-length: 5 > --Apple-Mail=_ECB4F749-F248-46F2-9160-E4E1E86E4236--