/* Parameters for execution on any Hewlett-Packard PA-RISC machine.
- Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1995
Free Software Foundation, Inc.
Contributed by the Center for Software Science at the
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* Forward declarations of some types we use in prototypes */
+
+#ifdef __STDC__
+struct frame_info;
+struct frame_saved_regs;
+struct value;
+struct type;
+struct inferior_status;
+#endif
+
/* Target system byte order. */
#define TARGET_BYTE_ORDER BIG_ENDIAN
+/* By default assume we don't have to worry about software floating point. */
+#ifndef SOFT_FLOAT
+#define SOFT_FLOAT 0
+#endif
+
/* Get at various relevent fields of an instruction word. */
#define MASK_5 0x1f
/* This macro gets bit fields using HP's numbering (MSB = 0) */
#define GET_FIELD(X, FROM, TO) \
- ((X) >> 31 - (TO) & (1 << ((TO) - (FROM) + 1)) - 1)
+ ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
/* Watch out for NaNs */
#define REG_STRUCT_HAS_ADDR(gcc_p,type) \
(TYPE_LENGTH (type) > 8)
+#define USE_STRUCT_CONVENTION(gcc_p,type) (TYPE_LENGTH (type) > 8)
+
/* Offset from address of function to start of its code.
Zero on most machines. */
to reach some "real" code. */
#define SKIP_PROLOGUE(pc) pc = skip_prologue (pc)
+extern CORE_ADDR skip_prologue PARAMS ((CORE_ADDR));
/* If PC is in some function-call trampoline code, return the PC
where the function itself actually starts. If not, return NULL. */
#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
in_solib_call_trampoline (pc, name)
+extern int in_solib_call_trampoline PARAMS ((CORE_ADDR, char *));
#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) \
in_solib_return_trampoline (pc, name)
-
-/* For some stupid reason find_pc_partial_function wants to treat
- trampoline symbols differently.
-
- In a nutshell, find_pc_partial_fucntion sets the low address for
- the function to the PC value that was passed in if the PC value
- passed in is a mst_trampoline symbol.
-
- This causes wait_for_inferior to execute code for stepping over
- or around a function (stop_pc == stop_func_start). This is
- extremely bad when we're stepping through a return from a shared
- library back to user code (which on the PA uses trampolines). */
-#define INHIBIT_SUNSOLIB_TRANSFER_TABLE_HACK
+extern int in_solib_return_trampoline PARAMS ((CORE_ADDR, char *));
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
#undef SAVED_PC_AFTER_CALL
#define SAVED_PC_AFTER_CALL(frame) saved_pc_after_call (frame)
+extern CORE_ADDR saved_pc_after_call PARAMS ((struct frame_info *));
/* Stack grows upward */
of register dumps. */
#define DO_REGISTERS_INFO(_regnum, fp) pa_do_registers_info (_regnum, fp)
+extern void pa_do_registers_info PARAMS ((int, int));
/* PA specific macro to see if the current instruction is nullified. */
#ifndef INSTRUCTION_NULLIFIED
/* Extract from an array REGBUF containing the (raw) register state
a function return value of type TYPE, and copy that, in virtual format,
- into VALBUF. */
+ into VALBUF.
+
+ FIXME: Not sure what to do for soft float here. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
{ \
- if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
+ if (TYPE_CODE (TYPE) == TYPE_CODE_FLT && !SOFT_FLOAT) \
memcpy ((VALBUF), \
- ((int *)(REGBUF)) + REGISTER_BYTE (FP4_REGNUM), \
+ ((char *)(REGBUF)) + REGISTER_BYTE (FP4_REGNUM), \
TYPE_LENGTH (TYPE)); \
else \
memcpy ((VALBUF), \
}
/* Write into appropriate registers a function return value
- of type TYPE, given in virtual format. */
+ of type TYPE, given in virtual format.
+
+ For software floating point the return value goes into the integer
+ registers. But we don't have any flag to key this on, so we always
+ store the value into the integer registers, and if it's a float value,
+ then we put it in the float registers too. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
- write_register_bytes ((TYPE_LENGTH(TYPE) > 4 \
- ? REGISTER_BYTE (FP4_REGNUM) \
- : REGISTER_BYTE (28)), \
- (VALBUF), TYPE_LENGTH (TYPE))
+ write_register_bytes (REGISTER_BYTE (28),(VALBUF), TYPE_LENGTH (TYPE)) ; \
+ if (!SOFT_FLOAT) \
+ write_register_bytes ((TYPE_CODE(TYPE) == TYPE_CODE_FLT \
+ ? REGISTER_BYTE (FP4_REGNUM) \
+ : REGISTER_BYTE (28)), \
+ (VALBUF), TYPE_LENGTH (TYPE))
/* Extract from an array REGBUF containing the (raw) register state
the address in which a function should return its structure value,
((regno) > IPSW_REGNUM && (regno) < FP4_REGNUM)
#define INIT_EXTRA_FRAME_INFO(fromleaf, frame) init_extra_frame_info (fromleaf, frame)
+extern void init_extra_frame_info PARAMS ((int, struct frame_info *));
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
address (previous FP). */
#define FRAME_CHAIN(thisframe) frame_chain (thisframe)
+extern CORE_ADDR frame_chain PARAMS ((struct frame_info *));
#define FRAME_CHAIN_VALID(chain, thisframe) \
frame_chain_valid (chain, thisframe)
+extern int frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
does not, FRAMELESS is set to 1, else 0. */
#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
(FRAMELESS) = frameless_function_invocation(FI)
+extern int frameless_function_invocation PARAMS ((struct frame_info *));
#define FRAME_SAVED_PC(FRAME) frame_saved_pc (FRAME)
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
hppa_frame_find_saved_regs (frame_info, &frame_saved_regs)
+extern void
+hppa_frame_find_saved_regs PARAMS ((struct frame_info *,
+ struct frame_saved_regs *));
\f
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
#define PUSH_DUMMY_FRAME push_dummy_frame (&inf_status)
+extern void push_dummy_frame PARAMS ((struct inferior_status *));
/* Discard from the stack the innermost frame,
restoring all saved registers. */
#define POP_FRAME hppa_pop_frame ()
+extern void hppa_pop_frame PARAMS ((void));
#define INSTRUCTION_SIZE 4
#define FIX_CALL_DUMMY hppa_fix_call_dummy
-CORE_ADDR hppa_fix_call_dummy();
+extern CORE_ADDR
+hppa_fix_call_dummy PARAMS ((char *, CORE_ADDR, CORE_ADDR, int,
+ struct value **, struct type *, int));
#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
sp = hppa_push_arguments(nargs, args, sp, struct_return, struct_addr)
+extern CORE_ADDR
+hppa_push_arguments PARAMS ((int, struct value **, CORE_ADDR, int,
+ CORE_ADDR));
\f
/* The low two bits of the PC on the PA contain the privilege level. Some
genius implementing a (non-GCC) compiler apparently decided this means
#define HPREAD_ADJUST_STACK_ADDRESS(ADDR) hpread_adjust_stack_address(ADDR)
extern int hpread_adjust_stack_address PARAMS ((CORE_ADDR));
+
+/* If the current gcc for for this target does not produce correct debugging
+ information for float parameters, both prototyped and unprototyped, then
+ define this macro. This forces gdb to always assume that floats are
+ passed as doubles and then converted in the callee.
+
+ For the pa, it appears that the debug info marks the parameters as
+ floats regardless of whether the function is prototyped, but the actual
+ values are passed as doubles for the non-prototyped case and floats for
+ the prototyped case. Thus we choose to make the non-prototyped case work
+ for C and break the prototyped case, since the non-prototyped case is
+ probably much more common. (FIXME). */
+
+#define COERCE_FLOAT_TO_DOUBLE (current_language -> la_language == language_c)
+
+#define STACK_ALIGN(ADDR) (((ADDR) + 7) & -8)