From b52538319943075659c249bb1706b296f27f573a Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Mon, 15 Mar 1999 19:47:42 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 11 ++++++ gcc/config/rs6000/rs6000.c | 66 +++++++++++++++++++++++++++------ gcc/config/rs6000/rs6000.h | 76 ++++++-------------------------------- 3 files changed, 77 insertions(+), 76 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd06ea2e226..e5fba0f48ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Mon Mar 15 22:45:25 1999 David Edelsohn + + * 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 * cppinit.c: Instead of one pending list, keep separate lists diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index c158fc3a3b5..a59425dae73 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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; } } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index f581eb8a1ba..ad69576fd64 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -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.) */ -- 2.30.2