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. */
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)
{
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)
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
{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 */
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 \
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