PR other/7114, target/5967

2002-07-18  Alan Modra  <amodra@bigpond.net.au>
	PR other/7114, target/5967
	* config/rs6000/rs6000.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.

From-SVN: r57093
This commit is contained in:
Alan Modra 2002-09-13 06:53:05 +00:00 committed by Alan Modra
parent 42526a4a8f
commit 04668773ae
4 changed files with 76 additions and 61 deletions

View File

@ -7,6 +7,18 @@
addze and similar (plus (comparison r1 r2) r3) insns. Add
missing scratch reg in one case. Formatting fixes.
2002-07-18 Alan Modra <amodra@bigpond.net.au>
PR other/7114, target/5967
* config/rs6000/rs6000.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.
2002-09-13 Alan Modra <amodra@bigpond.net.au>
* config/rs6000/rs6000.c (rs6000_emit_load_toc_table): Remove "if"

View File

@ -328,6 +328,10 @@ do \
} \
while (0)
/* Override sysv4.h as these are ABI_V4 only. */
#undef ASM_OUTPUT_REG_PUSH
#undef ASM_OUTPUT_REG_POP
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations. */

View File

@ -7346,53 +7346,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))
@ -10413,6 +10366,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)
@ -10421,13 +10375,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);
@ -10435,8 +10397,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);
@ -10452,27 +10414,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;
}
}

View File

@ -770,6 +770,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. */