From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1685 invoked by alias); 17 Jul 2002 09:06:04 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 1662 invoked by uid 71); 17 Jul 2002 09:06:03 -0000 Date: Wed, 17 Jul 2002 02:06:00 -0000 Message-ID: <20020717090603.1661.qmail@sources.redhat.com> To: amodra@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, From: Alan Modra Subject: Re: other/7114: ICE building strcoll.op from glibc-2.2.5 Reply-To: Alan Modra X-SW-Source: 2002-07/txt/msg00503.txt.bz2 List-Id: The following reply was made to PR other/7114; it has been noted by GNATS. From: Alan Modra To: Geoff Keating Cc: d.mueller@elsoft.ch, gcc-gnats@gcc.gnu.org, gcc-patches@gcc.gnu.org, dje@watson.ibm.com Subject: Re: other/7114: ICE building strcoll.op from glibc-2.2.5 Date: Wed, 17 Jul 2002 18:30:49 +0930 On Wed, Jul 17, 2002 at 12:07:11AM -0700, Geoff Keating wrote: > So, why don't we go back to the push/pop implementation, but this time > do it properly? We'd only need to push/pop in the (rare) > nested-function case. I wasn't aware that powerpc used that scheme previously, and therefore was worried that some mcount implementation might peek at the stack. Here we go. * config/rs6000/r6000.c (first_reg_to_save): Remove bogus adjustments to first_reg for profiling case. (output_function_profiler): Correct lr save slot for ABI_AIX_NODESC. Disable profiling for 64 bit code on both ABI_V4 and ABI_AIX_NODESC. Save static chain reg to sp + 12 on ABI_AIX_NODESC. * config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Define. (ASM_OUTPUT_REG_POP): Define. * config/rs6000/linux64.h (ASM_OUTPUT_REG_PUSH): Undef. (ASM_OUTPUT_REG_POP): Undef. Rationale: * config/rs6000/r6000.c (first_reg_to_save): Remove bogus adjustments to first_reg for profiling case. first_reg_to_save doesn't need to do anything special for any of these registers as profiling is done via PROFILE_HOOK when ABI_AIX or ABI_DARWIN. The normal register allocation code will set up regs_ever_live for us. We're also not trying to use a reg when ABI_V4. (output_function_profiler): Correct lr save slot for ABI_AIX_NODESC. ABI_AIX_NODESC saves lr to sp + 8. This change is perhaps a little contentious as existing mcount implementations may take into account the current ABI breakage. Disable profiling for 64 bit code on both ABI_V4 and ABI_AIX_NODESC. The instructions emitted here are 32 bit ones. Fix this with a later patch. Save static chain reg to sp + 12 on ABI_AIX_NODESC. We need to save it somewhere. This seems a likely spot. * config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Define. (ASM_OUTPUT_REG_POP): Define. Code resurrected from prior to Mon Mar 15 22:45:25 1999 delta, but with DEFAULT_ABI == ABI_V4 test added. powerpc-linux bootstrap on mainline seems to be broken at the moment. internal compiler error: Internal compiler error in tree_low_cst, at tree.c:3312 so I'm in the process of bootstrapping this one on the 3.1 branch. -- Alan Modra IBM OzLabs - Linux Technology Centre Index: gcc/config/rs6000/rs6000.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v retrieving revision 1.344 diff -u -p -r1.344 rs6000.c --- gcc/config/rs6000/rs6000.c 16 Jul 2002 20:59:03 -0000 1.344 +++ gcc/config/rs6000/rs6000.c 17 Jul 2002 08:19:35 -0000 @@ -7356,53 +7356,6 @@ first_reg_to_save () || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))) break; - if (current_function_profile) - { - /* AIX must save/restore every register that contains a parameter - before/after the .__mcount call plus an additional register - for the static chain, if needed; use registers from 30 down to 22 - to do this. */ - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) - { - int last_parm_reg, profile_first_reg; - - /* Figure out last used parameter register. The proper thing - to do is to walk incoming args of the function. A function - might have live parameter registers even if it has no - incoming args. */ - for (last_parm_reg = 10; - last_parm_reg > 2 && ! regs_ever_live [last_parm_reg]; - last_parm_reg--) - ; - - /* Calculate first reg for saving parameter registers - and static chain. - Skip reg 31 which may contain the frame pointer. */ - profile_first_reg = (33 - last_parm_reg - - (current_function_needs_context ? 1 : 0)); -#if TARGET_MACHO - /* Need to skip another reg to account for R31 being PICBASE - (when flag_pic is set) or R30 being used as the frame - pointer (when flag_pic is not set). */ - --profile_first_reg; -#endif - /* Do not save frame pointer if no parameters needs to be saved. */ - if (profile_first_reg == 31) - profile_first_reg = 32; - - if (first_reg > profile_first_reg) - first_reg = profile_first_reg; - } - - /* SVR4 may need one register to preserve the static chain. */ - else if (current_function_needs_context) - { - /* Skip reg 31 which may contain the frame pointer. */ - if (first_reg > 30) - first_reg = 30; - } - } - #if TARGET_MACHO if (flag_pic && current_function_uses_pic_offset_table && (first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)) @@ -10429,6 +10382,7 @@ output_function_profiler (file, labelno) int labelno; { char buf[100]; + int save_lr = 8; ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); switch (DEFAULT_ABI) @@ -10437,13 +10391,21 @@ output_function_profiler (file, labelno) abort (); case ABI_V4: + save_lr = 4; + /* Fall through. */ + case ABI_AIX_NODESC: + if (!TARGET_32BIT) + { + warning ("no profiling of 64-bit code for this ABI"); + return; + } fprintf (file, "\tmflr %s\n", reg_names[0]); if (flag_pic == 1) { fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); - asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", - reg_names[0], reg_names[1]); + asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", + reg_names[0], save_lr, reg_names[1]); asm_fprintf (file, "\tmflr %s\n", reg_names[12]); asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]); assemble_name (file, buf); @@ -10451,8 +10413,8 @@ output_function_profiler (file, labelno) } else if (flag_pic > 1) { - asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", - reg_names[0], reg_names[1]); + asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", + reg_names[0], save_lr, reg_names[1]); /* Now, we need to get the address of the label. */ fputs ("\tbl 1f\n\t.long ", file); assemble_name (file, buf); @@ -10468,27 +10430,32 @@ output_function_profiler (file, labelno) asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]); assemble_name (file, buf); fputs ("@ha\n", file); - asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", - reg_names[0], reg_names[1]); + asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", + reg_names[0], save_lr, reg_names[1]); asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]); assemble_name (file, buf); asm_fprintf (file, "@l(%s)\n", reg_names[12]); } - if (current_function_needs_context) - asm_fprintf (file, "\tmr %s,%s\n", - reg_names[30], reg_names[STATIC_CHAIN_REGNUM]); - fprintf (file, "\tbl %s\n", RS6000_MCOUNT); - if (current_function_needs_context) - asm_fprintf (file, "\tmr %s,%s\n", - reg_names[STATIC_CHAIN_REGNUM], reg_names[30]); + if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC) + { + asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", + reg_names[STATIC_CHAIN_REGNUM], + 12, reg_names[1]); + fprintf (file, "\tbl %s\n", RS6000_MCOUNT); + asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n", + reg_names[STATIC_CHAIN_REGNUM], + 12, reg_names[1]); + } + else + /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */ + fprintf (file, "\tbl %s\n", RS6000_MCOUNT); break; case ABI_AIX: case ABI_DARWIN: /* Don't do anything, done in output_profile_hook (). */ break; - } } Index: gcc/config/rs6000/sysv4.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/rs6000/sysv4.h,v retrieving revision 1.98 diff -u -p -r1.98 sysv4.h --- gcc/config/rs6000/sysv4.h 10 Jul 2002 00:33:51 -0000 1.98 +++ gcc/config/rs6000/sysv4.h 17 Jul 2002 08:19:36 -0000 @@ -736,6 +736,38 @@ do { \ ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \ } while (0) +/* This is how to output code to push a register on the stack. + It need not be very fast code. + + On the rs6000, we must keep the backchain up to date. In order + to simplify things, always allocate 16 bytes for a push (System V + wants to keep stack aligned to a 16 byte boundary). */ + +#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \ +do { \ + if (DEFAULT_ABI == ABI_V4) \ + asm_fprintf (FILE, \ + (TARGET_32BIT \ + ? "\t{stu|stwu} %s,-16(%s)\n\t{st|stw} %s,12(%s)\n" \ + : "\tstdu %s,-32(%s)\n\tstd %s,24(%s)\n"), \ + reg_names[1], reg_names[1], reg_names[REGNO], \ + reg_names[1]); \ +} while (0) + +/* This is how to output an insn to pop a register from the stack. + It need not be very fast code. */ + +#define ASM_OUTPUT_REG_POP(FILE, REGNO) \ +do { \ + if (DEFAULT_ABI == ABI_V4) \ + asm_fprintf (FILE, \ + (TARGET_32BIT \ + ? "\t{l|lwz} %s,12(%s)\n\t{ai|addic} %s,%s,16\n" \ + : "\tld %s,24(%s)\n\t{ai|addic} %s,%s,32\n"), \ + reg_names[REGNO], reg_names[1], reg_names[1], \ + reg_names[1]); \ +} while (0) + /* Switch Recognition by gcc.c. Add -G xx support. */ /* Override svr4.h definition. */ Index: gcc/config/rs6000/linux64.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v retrieving revision 1.21 diff -u -p -r1.21 linux64.h --- gcc/config/rs6000/linux64.h 11 Jul 2002 00:23:16 -0000 1.21 +++ gcc/config/rs6000/linux64.h 17 Jul 2002 08:19:25 -0000 @@ -329,3 +329,7 @@ do \ sym_lineno += 1; \ } \ while (0) + +/* Override sysv4.h as these are ABI_V4 only. */ +#undef ASM_OUTPUT_REG_PUSH +#undef ASM_OUTPUT_REG_POP