aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1993-03-29 14:32:08 -0800
committerJim Wilson <wilson@gcc.gnu.org>1993-03-29 14:32:08 -0800
commit7a24dbcfa909b974ee368dacb4dca8486745908b (patch)
treef958f415c5bd1b0ab9d056e58a6e59f0aa8a14d4 /gcc
parent77545d45a37ae31d6749dd80ed71362081579697 (diff)
downloadgcc-7a24dbcfa909b974ee368dacb4dca8486745908b.zip
gcc-7a24dbcfa909b974ee368dacb4dca8486745908b.tar.gz
gcc-7a24dbcfa909b974ee368dacb4dca8486745908b.tar.bz2
(i960_function_prologue): When profiling, don't use those registers clobbered around an mcount call.
(i960_function_prologue): When profiling, don't use those registers clobbered around an mcount call. (output_function_profiler): New function. From-SVN: r3916
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i960/i960.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c
index f98f1a7..8373b80 100644
--- a/gcc/config/i960/i960.c
+++ b/gcc/config/i960/i960.c
@@ -999,6 +999,18 @@ i960_function_prologue (file, size)
epilogue_string[0] = '\0';
+ if (profile_flag || profile_block_flag)
+ {
+ /* When profiling, we may use registers 20 to 27 to save arguments, so
+ they can't be used here for saving globals. J is the number of
+ argument registers the mcount call will save. */
+ for (j = 7; j >= 0 && ! regs_ever_live[j]; j--)
+ ;
+
+ for (i = 20; i <= j + 20; i++)
+ regs[i] = -1;
+ }
+
/* First look for local registers to save globals in. */
for (i = 0; i < 16; i++)
{
@@ -1134,6 +1146,83 @@ i960_function_prologue (file, size)
fprintf (file, "\t#End Prologue#\n");
}
+/* Output code for the function profiler. */
+
+void
+output_function_profiler (file, labelno)
+ FILE *file;
+ int labelno;
+{
+ /* The last used parameter register. */
+ int last_parm_reg;
+ int i, j, increment;
+
+ /* Figure out the 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. Note that we
+ don't have to save parameter registers g8 to g11 because they are
+ call preserved. */
+
+ /* See also output_function_prologue, which tries to use local registers
+ for preserved call-saved global registers. */
+
+ for (last_parm_reg = 7;
+ last_parm_reg >= 0 && ! regs_ever_live[last_parm_reg];
+ last_parm_reg--)
+ ;
+
+ /* Save parameter registers in regs r4 (20) to r11 (27). */
+
+ for (i = 0, j = 4; i <= last_parm_reg; i += increment, j += increment)
+ {
+ if (i % 4 == 0 && (last_parm_reg - i) >= 3)
+ increment = 4;
+ else if (i % 4 == 0 && (last_parm_reg - i) >= 2)
+ increment = 3;
+ else if (i % 2 == 0 && (last_parm_reg - i) >= 1)
+ increment = 2;
+ else
+ increment = 1;
+
+ fprintf (file, "\tmov%s g%d,r%d\n",
+ (increment == 4 ? "q" : increment == 3 ? "t"
+ : increment == 2 ? "l": ""), i, j);
+ }
+
+ /* If this function uses the arg pointer, then save it in r3 and then
+ set it to zero. */
+
+ if (current_function_args_size != 0)
+ fprintf (file, "\tmov g14,r3\n\tmov 0,g14");
+
+ /* Load location address into g0 and call mcount. */
+
+ fprintf (file, "\tlda\tLP%d,g0\n\tcallx\tmcount\n", labelno);
+
+ /* If this function uses the arg pointer, restore it. */
+
+ if (current_function_args_size != 0)
+ fprintf (file, "\tmov r3,g14");
+
+ /* Restore parameter registers. */
+
+ for (i = 0, j = 4; i <= last_parm_reg; i += increment, j += increment)
+ {
+ if (i % 4 == 0 && (last_parm_reg - i) >= 3)
+ increment = 4;
+ else if (i % 4 == 0 && (last_parm_reg - i) >= 2)
+ increment = 3;
+ else if (i % 2 == 0 && (last_parm_reg - i) >= 1)
+ increment = 2;
+ else
+ increment = 1;
+
+ fprintf (file, "\tmov%s r%d,g%d\n",
+ (increment == 4 ? "q" : increment == 3 ? "t"
+ : increment == 2 ? "l": ""), j, i);
+ }
+}
+
/* Output code for the function epilogue. */
void