OSDN Git Service

bit-pattern directly.
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Mar 1999 19:47:42 +0000 (19:47 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Mar 1999 19:47:42 +0000 (19:47 +0000)
        (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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25795 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h

index dd06ea2..e5fba0f 100644 (file)
@@ -1,3 +1,14 @@
+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
index c158fc3..a59425d 100644 (file)
@@ -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;
     }
 }
index f581eb8..ad69576 100644 (file)
@@ -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.)   */