Commit b5253831 by David Edelsohn Committed by David Edelsohn

bit-pattern directly.

        (ASM_OUTPUT_REG_{PUSH,POP}): Delete.
        * rs6000.c (first_reg_to_save): If profiling and context needed,
        allocate a reg to save static chain for all ABIs.  For AIX
        profiling, calculate parameter registers to save based on need.
        (output_function_profiler): Save and restore static chain around
        profile call for all ABIs.

From-SVN: r25795
parent 9b2bf201
Mon Mar 15 22:45:25 1999 David Edelsohn <edelsohn@mhpcc.edu>
* rs6000.h (ASM_OUTPUT_{DOUBLE,FLOAT}): Always generate IEEE 754
bit-pattern directly.
(ASM_OUTPUT_REG_{PUSH,POP}): Delete.
* rs6000.c (first_reg_to_save): If profiling and context needed,
allocate a reg to save static chain for all ABIs. For AIX
profiling, calculate parameter registers to save based on need.
(output_function_profiler): Save and restore static chain around
profile call for all ABIs.
1999-03-15 21:39 -0500 Zack Weinberg <zack@rabi.columbia.edu>
* cppinit.c: Instead of one pending list, keep separate lists
......
......@@ -3229,14 +3229,46 @@ first_reg_to_save ()
if (regs_ever_live[first_reg])
break;
/* If profiling, then we must save/restore every register that contains
a parameter before/after the .__mcount call. Use registers from 30 down
to 23 to do this. Don't use the frame pointer in reg 31.
if (profile_flag)
{
/* 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)
{
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));
/* 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;
}
For now, save enough room for all of the parameter registers. */
if (DEFAULT_ABI == ABI_AIX && profile_flag)
if (first_reg > 23)
first_reg = 23;
/* 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;
}
}
return first_reg;
}
......@@ -5051,13 +5083,20 @@ 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,4(%s)\n",
reg_names[0], 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]);
break;
case ABI_AIX:
......@@ -5089,11 +5128,13 @@ output_function_profiler (file, labelno)
last_parm_reg--)
;
/* Save parameter registers in regs 23-30. Don't overwrite reg 31, since
it might be set up as the frame pointer. */
/* Save parameter registers in regs 23-30 and static chain in r22.
Don't overwrite reg 31, since it might be set up as the frame pointer. */
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
asm_fprintf (file, "\tmr %d,%d\n", j, i);
if (current_function_needs_context)
asm_fprintf (file, "\tmr %d,%d\n", j, STATIC_CHAIN_REGNUM);
/* Load location address into r3, and call mcount. */
......@@ -5104,10 +5145,13 @@ output_function_profiler (file, labelno)
asm_fprintf (file, "(%s)\n\tbl %s\n\t%s\n",
reg_names[2], RS6000_MCOUNT, RS6000_CALL_GLUE);
/* Restore parameter registers. */
/* Restore parameter registers and static chain. */
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
asm_fprintf (file, "\tmr %d,%d\n", i, j);
if (current_function_needs_context)
asm_fprintf (file, "\tmr %d,%d\n", STATIC_CHAIN_REGNUM, j);
break;
}
}
......
......@@ -3000,43 +3000,21 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
/* This is how to output an assembler line defining a `double' constant. */
#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
{ \
if (REAL_VALUE_ISINF (VALUE) \
|| REAL_VALUE_ISNAN (VALUE) \
|| REAL_VALUE_MINUS_ZERO (VALUE)) \
{ \
long t[2]; \
REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", \
t[0] & 0xffffffff, t[1] & 0xffffffff); \
} \
else \
{ \
char str[30]; \
REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str); \
fprintf (FILE, "\t.double 0d%s\n", str); \
} \
#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
{ \
long t[2]; \
REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", \
t[0] & 0xffffffff, t[1] & 0xffffffff); \
}
/* This is how to output an assembler line defining a `float' constant. */
#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
{ \
if (REAL_VALUE_ISINF (VALUE) \
|| REAL_VALUE_ISNAN (VALUE) \
|| REAL_VALUE_MINUS_ZERO (VALUE)) \
{ \
long t; \
REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \
} \
else \
{ \
char str[30]; \
REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
fprintf (FILE, "\t.float 0d%s\n", str); \
} \
#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
{ \
long t; \
REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \
}
/* This is how to output an assembler line defining an `int' constant. */
......@@ -3085,38 +3063,6 @@ do { \
#define ASM_OUTPUT_ASCII(FILE, P, N) output_ascii ((FILE), (P), (N))
/* 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 { \
extern char *reg_names[]; \
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 { \
extern char *reg_names[]; \
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)
/* This is how to output an element of a case-vector that is absolute.
(RS/6000 does not use such vectors, but we must define this macro
anyway.) */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment