aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1992-06-04 21:32:44 +0000
committerRichard Stallman <rms@gnu.org>1992-06-04 21:32:44 +0000
commita9d91d6f8515e5327a22147aeff313e45840e7c9 (patch)
treed574b6b733da30c36c5c8f60249f266b15b3beba /gcc
parente38e5ba82f13ad9dac93a5f25e8e98275425c5eb (diff)
downloadgcc-a9d91d6f8515e5327a22147aeff313e45840e7c9.zip
gcc-a9d91d6f8515e5327a22147aeff313e45840e7c9.tar.gz
gcc-a9d91d6f8515e5327a22147aeff313e45840e7c9.tar.bz2
*** empty log message ***
From-SVN: r1160
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/pa/pa.c60
-rw-r--r--gcc/config/pa/pa.h45
2 files changed, 62 insertions, 43 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 33759dc..653edd2 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -1398,31 +1398,10 @@ output_function_prologue (file, size, leaf_function)
fprintf (file, ",NO_CALLS\n");
fprintf (file, "\t.ENTRY\n");
- /* Instead of taking one argument, the counter label, as most normal
- mcounts do, _mcount appears to behave differently on the HPPA. It
- takes the return address of the caller, the address of this
- routine, and the address of the label. Also, it isn't magic, so
- caller saves have to be preserved. We get around this by calling
- our own gcc_mcount, which takes arguments on the stack and saves
- argument registers. */
-
- if (profile_flag)
- {
- fprintf (file,"\tstw 2,-20(30)\n\tldo 48(30),30\n\
-\taddil L'LP$%04d-$global$,27\n\tldo R'LP$%04d-$global$(1),1\n\
-\tbl __gcc_mcount,2\n\tstw 1,-16(30)\n\tldo -48(30),30\n\tldw -20(30),2\n",
- hp_profile_labelno, hp_profile_labelno);
- }
/* Some registers have places to go in the current stack
structure. */
-#if 0
- /* However, according to the hp docs, there's no need to save the
- sp. */
- fprintf (file, "\tstw 30,-4(30)\n");
-#endif
-
- if (regs_ever_live[2])
+ if (regs_ever_live[2] || profile_flag)
fprintf (file, "\tstw 2,-20(0,30)\n");
/* Reserve space for local variables. */
@@ -1447,7 +1426,36 @@ output_function_prologue (file, size, leaf_function)
fprintf (file, "\taddil L'%d,30\n\tldo R'%d(1),30\n",
actual_fsize, actual_fsize);
}
-
+ /* Instead of taking one argument, the counter label, as most normal
+ mcounts do, _mcount appears to behave differently on the HPPA. It
+ takes the return address of the caller, the address of this
+ routine, and the address of the label. Also, it isn't magic, so
+ argument registers have to be preserved. */
+
+ if (profile_flag)
+ {
+ unsigned int pc_offset =
+ (4 + (frame_pointer_needed
+ ? (VAL_14_BITS_P (actual_fsize) ? 12 : 20)
+ : (VAL_14_BITS_P (actual_fsize) ? 4 : 8)));
+ int i, arg_offset;
+
+ for (i = 26, arg_offset = -36; i >= 23; i--, arg_offset -= 4)
+ if (regs_ever_live[i])
+ {
+ print_stw (file, i, arg_offset, 4);
+ pc_offset += 4;
+ }
+ fprintf (file,
+ "\tcopy %%r2,%%r26\n\taddil L'LP$%04d-$global$,%%r27\n\
+\tldo R'LP$%04d-$global$(%%r1),%%r24\n\tbl _mcount,%%r2\n\
+\tldo %d(%%r2),%%r25\n",
+ hp_profile_labelno, hp_profile_labelno, -pc_offset - 12 - 8);
+ for (i = 26, arg_offset = -36; i >= 23; i--, arg_offset -= 4)
+ if (regs_ever_live[i])
+ print_ldw (file, i, arg_offset, 4);
+ }
+
/* Normal register save. */
if (frame_pointer_needed)
{
@@ -2192,7 +2200,11 @@ output_arg_descriptor (insn)
arg_mode = GET_MODE (XEXP (PATTERN (prev_insn), 0));
regno = REGNO (XEXP (PATTERN (prev_insn), 0));
if (regno >= 23 && regno <= 26)
- arg_regs[26 - regno] = "GR";
+ {
+ arg_regs[26 - regno] = "GR";
+ if (arg_mode == DImode)
+ arg_regs[25 - regno] = "GR";
+ }
else if (!TARGET_SNAKE) /* fp args */
{
if (arg_mode == SFmode)
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 50d4818..d3a1357 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -441,16 +441,18 @@ extern int leaf_function;
1.1 fp regs, and the high 1.1 fp regs, to which the operands of
fmpyadd and fmpysub are restricted. */
-enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, HI_SNAKE_FP_REGS,
- SNAKE_FP_REGS, FP_OR_SNAKE_FP_REGS, SHIFT_REGS, ALL_REGS, LIM_REG_CLASSES};
+enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
+ HI_SNAKE_FP_REGS, SNAKE_FP_REGS, GENERAL_OR_SNAKE_FP_REGS,
+ SHIFT_REGS, ALL_REGS, LIM_REG_CLASSES};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
- { "NO_REGS", "R1_REGS", "GENERAL_REGS", "FP_REGS", "HI_SNAKE_FP_REGS",\
- "SNAKE_FP_REGS", "FP_OR_SNAKE_FP_REGS", "SHIFT_REGS", "ALL_REGS"}
+ { "NO_REGS", "R1_REGS", "GENERAL_REGS", "FP_REGS", "GENERAL_OR_FP_REGS",\
+ "HI_SNAKE_FP_REGS", "SNAKE_FP_REGS", "GENERAL_OR_SNAKE_FP_REGS",\
+ "SHIFT_REGS", "ALL_REGS"}
/* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET
@@ -462,9 +464,10 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, HI_SNAKE_FP_REGS,
{0x2, 0, 0, 0}, /* R1_REGS */ \
{-2, 0, 0, 0}, /* GENERAL_REGS */ \
{0, 0xffff, 0, 0}, /* FP_REGS */ \
+ {-2, 0xffff, 0, 0}, /* GENERAL_OR_FP_REGS */\
{0, 0, 0xffff0000, 0xffff}, /* HI_SNAKE_FP_REGS */ \
{0, 0xffff0000, ~0, 0xffff}, /* SNAKE_FP_REGS */ \
- {0, ~0, ~0, 0xffff}, /* FP_OR_SNAKE_FP_REGS */\
+ {-2, 0xffff0000, ~0, 0xffff}, /* GENERAL_OR_SNAKE_FP_REGS */\
{0, 0, 0, 0x10000}, /* SHIFT_REGS */ \
{-2, ~0, ~0, 0x1ffff}} /* ALL_REGS */
@@ -774,23 +777,31 @@ extern enum cmp_type hppa_branch_type;
fputs ("\t.EXPORT ", FILE); assemble_name (FILE, NAME); \
fputs (",PRIV_LEV=3", FILE); \
for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4; \
- parm = TREE_CHAIN (parm), i++) \
+ parm = TREE_CHAIN (parm)) \
{ \
if (TYPE_MODE (DECL_ARG_TYPE (parm)) == SFmode) \
- fprintf (FILE, ",ARGW%d=FR", i); \
+ fprintf (FILE, ",ARGW%d=FR", i++); \
else if (TYPE_MODE (DECL_ARG_TYPE (parm)) == DFmode) \
{ \
- if (i == 0 || i == 2) \
- { \
- ASM_DOUBLE_ARG_DESCRIPTORS (FILE, i++, i); \
- } \
- else if (i == 1) \
+ if (i == 1) i++; \
+ ASM_DOUBLE_ARG_DESCRIPTORS (FILE, i++, i++); \
+ } \
+ else \
+ { \
+ int arg_size = \
+ FUNCTION_ARG_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)),\
+ DECL_ARG_TYPE (parm)); \
+ if (arg_size == 2 && i <= 2) \
{ \
- ASM_DOUBLE_ARG_DESCRIPTORS (FILE, ++i, ++i); \
+ if (i == 1) i++; \
+ fprintf (FILE, ",ARGW%d=GR", i++); \
+ fprintf (FILE, ",ARGW%d=GR", i++); \
} \
+ else if (arg_size == 1) \
+ fprintf (FILE, ",ARGW%d=GR", i++); \
+ else \
+ i += arg_size; \
} \
- else \
- fprintf (FILE, ",ARGW%d=GR", i); \
} \
/* anonymous args */ \
if (TYPE_ARG_TYPES (tree_type) != 0 \
@@ -840,13 +851,9 @@ extern int apparent_fsize;
profiling code in function_prologue. This just stores LABELNO for
that. */
-#ifdef hp800 /* Don't have the proper libraries yet */
-#define FUNCTION_PROFILER(FILE, LABELNO) {}
-#else
#define PROFILE_BEFORE_PROLOGUE
#define FUNCTION_PROFILER(FILE, LABELNO) \
{ extern int hp_profile_labelno; hp_profile_labelno = (LABELNO);}
-#endif
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
the stack pointer does not matter. The value is tested only in