/* For argument passing to the inferior */
#include "symtab.h"
#include "infcall.h"
+#include "dis-asm.h"
#ifdef USG
#include <sys/types.h>
#include "target.h"
#include "symfile.h"
#include "objfiles.h"
+#include "hppa-tdep.h"
/* Some local constants. */
-static const int hppa_num_regs = 128;
+static const int hppa32_num_regs = 128;
+static const int hppa64_num_regs = 96;
+
+static const int hppa64_call_dummy_breakpoint_offset = 22 * 4;
+
+/* DEPRECATED_CALL_DUMMY_LENGTH is computed based on the size of a
+ word on the target machine, not the size of an instruction. Since
+ a word on this target holds two instructions we have to divide the
+ instruction size by two to get the word size of the dummy. */
+static const int hppa32_call_dummy_length = INSTRUCTION_SIZE * 28;
+static const int hppa64_call_dummy_length = INSTRUCTION_SIZE * 26 / 2;
+
+/* Get at various relevent fields of an instruction word. */
+#define MASK_5 0x1f
+#define MASK_11 0x7ff
+#define MASK_14 0x3fff
+#define MASK_21 0x1fffff
+
+/* Define offsets into the call dummy for the target function address.
+ See comments related to CALL_DUMMY for more info. */
+#define FUNC_LDIL_OFFSET (INSTRUCTION_SIZE * 9)
+#define FUNC_LDO_OFFSET (INSTRUCTION_SIZE * 10)
+
+/* Define offsets into the call dummy for the _sr4export address.
+ See comments related to CALL_DUMMY for more info. */
+#define SR4EXPORT_LDIL_OFFSET (INSTRUCTION_SIZE * 12)
+#define SR4EXPORT_LDO_OFFSET (INSTRUCTION_SIZE * 13)
/* To support detection of the pseudo-initial frame
that threads have. */
#define THREAD_INITIAL_FRAME_SYMBOL "__pthread_exit"
#define THREAD_INITIAL_FRAME_SYM_LEN sizeof(THREAD_INITIAL_FRAME_SYMBOL)
+/* Sizes (in bytes) of the native unwind entries. */
+#define UNWIND_ENTRY_SIZE 16
+#define STUB_UNWIND_ENTRY_SIZE 8
+
+static int get_field (unsigned word, int from, int to);
+
static int extract_5_load (unsigned int);
static unsigned extract_5R_store (unsigned int);
static int hppa_alignof (struct type *);
-/* To support multi-threading and stepping. */
-int hppa_prepare_to_proceed ();
-
static int prologue_inst_adjust_sp (unsigned long);
static int is_branch (unsigned long);
int hppa_in_solib_return_trampoline (CORE_ADDR pc, char *name);
CORE_ADDR hppa_saved_pc_after_call (struct frame_info *frame);
int hppa_inner_than (CORE_ADDR lhs, CORE_ADDR rhs);
-CORE_ADDR hppa_stack_align (CORE_ADDR sp);
+CORE_ADDR hppa32_stack_align (CORE_ADDR sp);
+CORE_ADDR hppa64_stack_align (CORE_ADDR sp);
int hppa_pc_requires_run_before_use (CORE_ADDR pc);
int hppa_instruction_nullified (void);
int hppa_register_raw_size (int reg_nr);
int hppa_register_byte (int reg_nr);
-struct type * hppa_register_virtual_type (int reg_nr);
+struct type * hppa32_register_virtual_type (int reg_nr);
+struct type * hppa64_register_virtual_type (int reg_nr);
void hppa_store_struct_return (CORE_ADDR addr, CORE_ADDR sp);
-void hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf);
-int hppa_use_struct_convention (int gcc_p, struct type *type);
-void hppa_store_return_value (struct type *type, char *valbuf);
+void hppa32_extract_return_value (struct type *type, char *regbuf,
+ char *valbuf);
+void hppa64_extract_return_value (struct type *type, char *regbuf,
+ char *valbuf);
+int hppa32_use_struct_convention (int gcc_p, struct type *type);
+int hppa64_use_struct_convention (int gcc_p, struct type *type);
+void hppa32_store_return_value (struct type *type, char *valbuf);
+void hppa64_store_return_value (struct type *type, char *valbuf);
CORE_ADDR hppa_extract_struct_value_address (char *regbuf);
int hppa_cannot_store_register (int regnum);
void hppa_init_extra_frame_info (int fromleaf, struct frame_info *frame);
int hppa_frameless_function_invocation (struct frame_info *frame);
CORE_ADDR hppa_frame_saved_pc (struct frame_info *frame);
CORE_ADDR hppa_frame_args_address (struct frame_info *fi);
-CORE_ADDR hppa_frame_locals_address (struct frame_info *fi);
int hppa_frame_num_args (struct frame_info *frame);
void hppa_push_dummy_frame (void);
void hppa_pop_frame (void);
/* Should call_function allocate stack space for a struct return? */
int
-hppa_use_struct_convention (int gcc_p, struct type *type)
+hppa32_use_struct_convention (int gcc_p, struct type *type)
{
return (TYPE_LENGTH (type) > 2 * DEPRECATED_REGISTER_SIZE);
}
-\f
+
+/* Same as hppa32_use_struct_convention() for the PA64 ABI. */
+
+int
+hppa64_use_struct_convention (int gcc_p, struct type *type)
+{
+ /* RM: struct upto 128 bits are returned in registers */
+ return TYPE_LENGTH (type) > 16;
+}
/* Routines to extract various sized constants out of hppa
instructions. */
return (int) ((val & 0x1 ? (-1 << (bits - 1)) : 0) | val >> 1);
}
+/* Extract the bits at positions between FROM and TO, using HP's numbering
+ (MSB = 0). */
+
+static int
+get_field (unsigned word, int from, int to)
+{
+ return ((word) >> (31 - (to)) & ((1 << ((to) - (from) + 1)) - 1));
+}
+
/* extract the immediate field from a ld{bhw}s instruction */
static int
word &= MASK_21;
word <<= 11;
- val = GET_FIELD (word, 20, 20);
+ val = get_field (word, 20, 20);
val <<= 11;
- val |= GET_FIELD (word, 9, 19);
+ val |= get_field (word, 9, 19);
val <<= 2;
- val |= GET_FIELD (word, 5, 6);
+ val |= get_field (word, 5, 6);
val <<= 5;
- val |= GET_FIELD (word, 0, 4);
+ val |= get_field (word, 0, 4);
val <<= 2;
- val |= GET_FIELD (word, 7, 8);
+ val |= get_field (word, 7, 8);
return sign_extend (val, 21) << 11;
}
{
unsigned val = 0;
- val |= GET_FIELD (opnd, 11 + 14, 11 + 18);
+ val |= get_field (opnd, 11 + 14, 11 + 18);
val <<= 2;
- val |= GET_FIELD (opnd, 11 + 12, 11 + 13);
+ val |= get_field (opnd, 11 + 12, 11 + 13);
val <<= 2;
- val |= GET_FIELD (opnd, 11 + 19, 11 + 20);
+ val |= get_field (opnd, 11 + 19, 11 + 20);
val <<= 11;
- val |= GET_FIELD (opnd, 11 + 1, 11 + 11);
+ val |= get_field (opnd, 11 + 1, 11 + 11);
val <<= 1;
- val |= GET_FIELD (opnd, 11 + 0, 11 + 0);
+ val |= get_field (opnd, 11 + 0, 11 + 0);
return word | val;
}
static int
extract_17 (unsigned word)
{
- return sign_extend (GET_FIELD (word, 19, 28) |
- GET_FIELD (word, 29, 29) << 10 |
- GET_FIELD (word, 11, 15) << 11 |
+ return sign_extend (get_field (word, 19, 28) |
+ get_field (word, 29, 29) << 10 |
+ get_field (word, 11, 15) << 11 |
(word & 0x1) << 16, 17) << 2;
}
\f
return NULL;
}
+const unsigned char *
+hppa_breakpoint_from_pc (CORE_ADDR *pc, int *len)
+{
+ static const char breakpoint[] = {0x00, 0x01, 0x00, 0x04};
+ (*len) = sizeof (breakpoint);
+ return breakpoint;
+}
+
+/* Return the name of a register. */
+
+const char *
+hppa32_register_name (int i)
+{
+ static char *names[] = {
+ "flags", "r1", "rp", "r3",
+ "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11",
+ "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19",
+ "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "dp",
+ "ret0", "ret1", "sp", "r31",
+ "sar", "pcoqh", "pcsqh", "pcoqt",
+ "pcsqt", "eiem", "iir", "isr",
+ "ior", "ipsw", "goto", "sr4",
+ "sr0", "sr1", "sr2", "sr3",
+ "sr5", "sr6", "sr7", "cr0",
+ "cr8", "cr9", "ccr", "cr12",
+ "cr13", "cr24", "cr25", "cr26",
+ "mpsfu_high","mpsfu_low","mpsfu_ovflo","pad",
+ "fpsr", "fpe1", "fpe2", "fpe3",
+ "fpe4", "fpe5", "fpe6", "fpe7",
+ "fr4", "fr4R", "fr5", "fr5R",
+ "fr6", "fr6R", "fr7", "fr7R",
+ "fr8", "fr8R", "fr9", "fr9R",
+ "fr10", "fr10R", "fr11", "fr11R",
+ "fr12", "fr12R", "fr13", "fr13R",
+ "fr14", "fr14R", "fr15", "fr15R",
+ "fr16", "fr16R", "fr17", "fr17R",
+ "fr18", "fr18R", "fr19", "fr19R",
+ "fr20", "fr20R", "fr21", "fr21R",
+ "fr22", "fr22R", "fr23", "fr23R",
+ "fr24", "fr24R", "fr25", "fr25R",
+ "fr26", "fr26R", "fr27", "fr27R",
+ "fr28", "fr28R", "fr29", "fr29R",
+ "fr30", "fr30R", "fr31", "fr31R"
+ };
+ if (i < 0 || i >= (sizeof (names) / sizeof (*names)))
+ return NULL;
+ else
+ return names[i];
+}
+
+const char *
+hppa64_register_name (int i)
+{
+ static char *names[] = {
+ "flags", "r1", "rp", "r3",
+ "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11",
+ "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19",
+ "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "dp",
+ "ret0", "ret1", "sp", "r31",
+ "sar", "pcoqh", "pcsqh", "pcoqt",
+ "pcsqt", "eiem", "iir", "isr",
+ "ior", "ipsw", "goto", "sr4",
+ "sr0", "sr1", "sr2", "sr3",
+ "sr5", "sr6", "sr7", "cr0",
+ "cr8", "cr9", "ccr", "cr12",
+ "cr13", "cr24", "cr25", "cr26",
+ "mpsfu_high","mpsfu_low","mpsfu_ovflo","pad",
+ "fpsr", "fpe1", "fpe2", "fpe3",
+ "fr4", "fr5", "fr6", "fr7",
+ "fr8", "fr9", "fr10", "fr11",
+ "fr12", "fr13", "fr14", "fr15",
+ "fr16", "fr17", "fr18", "fr19",
+ "fr20", "fr21", "fr22", "fr23",
+ "fr24", "fr25", "fr26", "fr27",
+ "fr28", "fr29", "fr30", "fr31"
+ };
+ if (i < 0 || i >= (sizeof (names) / sizeof (*names)))
+ return NULL;
+ else
+ return names[i];
+}
+
+
+
/* Return the adjustment necessary to make for addresses on the stack
as presented by hpread.c.
args = alloca (sizeof (struct value *) * 8); /* 6 for the arguments and one null one??? */
funcval = find_function_in_inferior ("__d_shl_get");
- get_sym = lookup_symbol ("__d_shl_get", NULL, VAR_NAMESPACE, NULL, NULL);
+ get_sym = lookup_symbol ("__d_shl_get", NULL, VAR_DOMAIN, NULL, NULL);
buff_minsym = lookup_minimal_symbol ("__buffer", NULL, NULL);
msymbol = lookup_minimal_symbol ("__shldp", NULL, NULL);
- symbol2 = lookup_symbol ("__shldp", NULL, VAR_NAMESPACE, NULL, NULL);
+ symbol2 = lookup_symbol ("__shldp", NULL, VAR_DOMAIN, NULL, NULL);
endo_buff_addr = SYMBOL_VALUE_ADDRESS (buff_minsym);
namelen = strlen (DEPRECATED_SYMBOL_NAME (function));
value_return_addr = endo_buff_addr + namelen;
void
pa_do_registers_info (int regnum, int fpregs)
{
- char raw_regs[REGISTER_BYTES];
+ char *raw_regs = alloca (DEPRECATED_REGISTER_BYTES);
int i;
/* Make a copy of gdb's save area (may cause actual
pa_do_strcat_registers_info (int regnum, int fpregs, struct ui_file *stream,
enum precision_type precision)
{
- char raw_regs[REGISTER_BYTES];
+ char *raw_regs = alloca (DEPRECATED_REGISTER_BYTES);
int i;
/* Make a copy of gdb's save area (may cause actual
/* Next look for the catch enable flag provided in end.o */
sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
- VAR_NAMESPACE, 0, (struct symtab **) NULL);
+ VAR_DOMAIN, 0, (struct symtab **) NULL);
if (sym) /* sometimes present in debug info */
{
eh_catch_catch_addr = SYMBOL_VALUE_ADDRESS (sym);
/* Next look for the catch enable flag provided end.o */
sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
- VAR_NAMESPACE, 0, (struct symtab **) NULL);
+ VAR_DOMAIN, 0, (struct symtab **) NULL);
if (sym) /* sometimes present in debug info */
{
eh_catch_throw_addr = SYMBOL_VALUE_ADDRESS (sym);
pin (Total_frame_size);
}
-#ifdef PREPARE_TO_PROCEED
-
-/* If the user has switched threads, and there is a breakpoint
- at the old thread's pc location, then switch to that thread
- and return TRUE, else return FALSE and don't do a thread
- switch (or rather, don't seem to have done a thread switch).
-
- Ptrace-based gdb will always return FALSE to the thread-switch
- query, and thus also to PREPARE_TO_PROCEED.
-
- The important thing is whether there is a BPT instruction,
- not how many user breakpoints there are. So we have to worry
- about things like these:
-
- o Non-bp stop -- NO
-
- o User hits bp, no switch -- NO
-
- o User hits bp, switches threads -- YES
-
- o User hits bp, deletes bp, switches threads -- NO
-
- o User hits bp, deletes one of two or more bps
- at that PC, user switches threads -- YES
-
- o Plus, since we're buffering events, the user may have hit a
- breakpoint, deleted the breakpoint and then gotten another
- hit on that same breakpoint on another thread which
- actually hit before the delete. (FIXME in breakpoint.c
- so that "dead" breakpoints are ignored?) -- NO
-
- For these reasons, we have to violate information hiding and
- call "breakpoint_here_p". If core gdb thinks there is a bpt
- here, that's what counts, as core gdb is the one which is
- putting the BPT instruction in and taking it out.
-
- Note that this implementation is potentially redundant now that
- default_prepare_to_proceed() has been added.
-
- FIXME This may not support switching threads after Ctrl-C
- correctly. The default implementation does support this. */
-int
-hppa_prepare_to_proceed (void)
-{
- pid_t old_thread;
- pid_t current_thread;
-
- old_thread = hppa_switched_threads (PIDGET (inferior_ptid));
- if (old_thread != 0)
- {
- /* Switched over from "old_thread". Try to do
- as little work as possible, 'cause mostly
- we're going to switch back. */
- CORE_ADDR new_pc;
- CORE_ADDR old_pc = read_pc ();
-
- /* Yuk, shouldn't use global to specify current
- thread. But that's how gdb does it. */
- current_thread = PIDGET (inferior_ptid);
- inferior_ptid = pid_to_ptid (old_thread);
-
- new_pc = read_pc ();
- if (new_pc != old_pc /* If at same pc, no need */
- && breakpoint_here_p (new_pc))
- {
- /* User hasn't deleted the BP.
- Return TRUE, finishing switch to "old_thread". */
- flush_cached_frames ();
- registers_changed ();
-#if 0
- printf ("---> PREPARE_TO_PROCEED (was %d, now %d)!\n",
- current_thread, PIDGET (inferior_ptid));
-#endif
-
- return 1;
- }
-
- /* Otherwise switch back to the user-chosen thread. */
- inferior_ptid = pid_to_ptid (current_thread);
- new_pc = read_pc (); /* Re-prime register cache */
- }
-
- return 0;
-}
-#endif /* PREPARE_TO_PROCEED */
-
void
hppa_skip_permanent_breakpoint (void)
{
Called only in the context of the "return" command. */
void
-hppa_store_return_value (struct type *type, char *valbuf)
+hppa32_store_return_value (struct type *type, char *valbuf)
{
/* For software floating point, the return value goes into the
integer registers. But we do not have any flag to key this on,
valbuf, TYPE_LENGTH (type));
}
+/* Same as hppa32_store_return_value(), but for the PA64 ABI. */
+
+void
+hppa64_store_return_value (struct type *type, char *valbuf)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ deprecated_write_register_bytes
+ (REGISTER_BYTE (FP4_REGNUM)
+ + DEPRECATED_REGISTER_SIZE - TYPE_LENGTH (type),
+ valbuf, TYPE_LENGTH (type));
+ else if (is_integral_type(type))
+ deprecated_write_register_bytes
+ (REGISTER_BYTE (28)
+ + DEPRECATED_REGISTER_SIZE - TYPE_LENGTH (type),
+ valbuf, TYPE_LENGTH (type));
+ else if (TYPE_LENGTH (type) <= 8)
+ deprecated_write_register_bytes
+ (REGISTER_BYTE (28),valbuf, TYPE_LENGTH (type));
+ else if (TYPE_LENGTH (type) <= 16)
+ {
+ deprecated_write_register_bytes (REGISTER_BYTE (28),valbuf, 8);
+ deprecated_write_register_bytes
+ (REGISTER_BYTE (29), valbuf + 8, TYPE_LENGTH (type) - 8);
+ }
+}
+
/* Copy the function's return value into VALBUF.
This function is called only in the context of "target function calls",
"return" command. */
void
-hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+hppa32_extract_return_value (struct type *type, char *regbuf, char *valbuf)
{
if (TYPE_CODE (type) == TYPE_CODE_FLT)
- memcpy (valbuf,
- (char *)regbuf + REGISTER_BYTE (FP4_REGNUM),
- TYPE_LENGTH (type));
+ memcpy (valbuf, regbuf + REGISTER_BYTE (FP4_REGNUM), TYPE_LENGTH (type));
else
memcpy (valbuf,
- ((char *)regbuf
+ (regbuf
+ REGISTER_BYTE (28)
+ (TYPE_LENGTH (type) > 4
? (8 - TYPE_LENGTH (type))
TYPE_LENGTH (type));
}
+/* Same as hppa32_extract_return_value but for the PA64 ABI case. */
+
+void
+hppa64_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ /* RM: Floats are returned in FR4R, doubles in FR4.
+ Integral values are in r28, padded on the left.
+ Aggregates less that 65 bits are in r28, right padded.
+ Aggregates upto 128 bits are in r28 and r29, right padded. */
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ memcpy (valbuf,
+ regbuf + REGISTER_BYTE (FP4_REGNUM)
+ + DEPRECATED_REGISTER_SIZE - TYPE_LENGTH (type),
+ TYPE_LENGTH (type));
+ else if (is_integral_type(type))
+ memcpy (valbuf,
+ regbuf + REGISTER_BYTE (28)
+ + DEPRECATED_REGISTER_SIZE - TYPE_LENGTH (type),
+ TYPE_LENGTH (type));
+ else if (TYPE_LENGTH (type) <= 8)
+ memcpy (valbuf, regbuf + REGISTER_BYTE (28), TYPE_LENGTH (type));
+ else if (TYPE_LENGTH (type) <= 16)
+ {
+ memcpy (valbuf, regbuf + REGISTER_BYTE (28), 8);
+ memcpy (valbuf + 8, regbuf + REGISTER_BYTE (29), TYPE_LENGTH (type) - 8);
+ }
+}
+
int
hppa_reg_struct_has_addr (int gcc_p, struct type *type)
{
}
CORE_ADDR
-hppa_stack_align (CORE_ADDR sp)
+hppa32_stack_align (CORE_ADDR sp)
{
/* elz: adjust the quantity to the next highest value which is
64-bit aligned. This is used in valops.c, when the sp is adjusted.
return ((sp % 8) ? (sp + 7) & -8 : sp);
}
+CORE_ADDR
+hppa64_stack_align (CORE_ADDR sp)
+{
+ /* The PA64 ABI mandates a 16 byte stack alignment. */
+ return ((sp % 16) ? (sp + 15) & -16 : sp);
+}
+
int
hppa_pc_requires_run_before_use (CORE_ADDR pc)
{
int
hppa_register_byte (int reg_nr)
{
- return reg_nr * 4;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ return reg_nr * tdep->bytes_per_address;
}
/* Return the GDB type object for the "standard" data type of data
in register N. */
struct type *
-hppa_register_virtual_type (int reg_nr)
+hppa32_register_virtual_type (int reg_nr)
{
if (reg_nr < FP4_REGNUM)
return builtin_type_int;
return builtin_type_float;
}
+/* Return the GDB type object for the "standard" data type of data
+ in register N. hppa64 version. */
+
+struct type *
+hppa64_register_virtual_type (int reg_nr)
+{
+ if (reg_nr < FP4_REGNUM)
+ return builtin_type_unsigned_long_long;
+ else
+ return builtin_type_double;
+}
+
/* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function. */
}
-CORE_ADDR
-hppa_frame_args_address (struct frame_info *fi)
-{
- return get_frame_base (fi);
-}
-
-CORE_ADDR
-hppa_frame_locals_address (struct frame_info *fi)
-{
- return get_frame_base (fi);
-}
-
-int
-hppa_frame_num_args (struct frame_info *frame)
-{
- /* We can't tell how many args there are now that the C compiler delays
- popping them. */
- return -1;
-}
-
CORE_ADDR
hppa_smash_text_address (CORE_ADDR addr)
{
return (addr &= ~0x3);
}
+/* Get the ith function argument for the current function. */
+CORE_ADDR
+hppa_fetch_pointer_argument (struct frame_info *frame, int argi,
+ struct type *type)
+{
+ CORE_ADDR addr;
+ frame_read_register (frame, R0_REGNUM + 26 - argi, &addr);
+ return addr;
+}
+
static struct gdbarch *
hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
+ struct gdbarch_tdep *tdep;
struct gdbarch *gdbarch;
/* Try to determine the ABI of the object we are loading. */
return (arches->gdbarch);
/* If none found, then allocate and initialize one. */
- gdbarch = gdbarch_alloc (&info, NULL);
+ tdep = XMALLOC (struct gdbarch_tdep);
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ /* Determine from the bfd_arch_info structure if we are dealing with
+ a 32 or 64 bits architecture. If the bfd_arch_info is not available,
+ then default to a 32bit machine. */
+ if (info.bfd_arch_info != NULL)
+ tdep->bytes_per_address =
+ info.bfd_arch_info->bits_per_address / info.bfd_arch_info->bits_per_byte;
+ else
+ tdep->bytes_per_address = 4;
- /* Hook in ABI-specific overrides, if they have been registered. */
- gdbarch_init_osabi (info, gdbarch);
+ /* Some parts of the gdbarch vector depend on whether we are running
+ on a 32 bits or 64 bits target. */
+ switch (tdep->bytes_per_address)
+ {
+ case 4:
+ set_gdbarch_num_regs (gdbarch, hppa32_num_regs);
+ set_gdbarch_register_name (gdbarch, hppa32_register_name);
+ set_gdbarch_deprecated_register_virtual_type
+ (gdbarch, hppa32_register_virtual_type);
+ set_gdbarch_deprecated_call_dummy_length
+ (gdbarch, hppa32_call_dummy_length);
+ set_gdbarch_stack_align (gdbarch, hppa32_stack_align);
+ set_gdbarch_reg_struct_has_addr (gdbarch, hppa_reg_struct_has_addr);
+ set_gdbarch_deprecated_extract_return_value
+ (gdbarch, hppa32_extract_return_value);
+ set_gdbarch_use_struct_convention
+ (gdbarch, hppa32_use_struct_convention);
+ set_gdbarch_deprecated_store_return_value
+ (gdbarch, hppa32_store_return_value);
+ break;
+ case 8:
+ set_gdbarch_num_regs (gdbarch, hppa64_num_regs);
+ set_gdbarch_register_name (gdbarch, hppa64_register_name);
+ set_gdbarch_deprecated_register_virtual_type
+ (gdbarch, hppa64_register_virtual_type);
+ set_gdbarch_deprecated_call_dummy_breakpoint_offset
+ (gdbarch, hppa64_call_dummy_breakpoint_offset);
+ set_gdbarch_deprecated_call_dummy_length
+ (gdbarch, hppa64_call_dummy_length);
+ set_gdbarch_stack_align (gdbarch, hppa64_stack_align);
+ set_gdbarch_deprecated_extract_return_value
+ (gdbarch, hppa64_extract_return_value);
+ set_gdbarch_use_struct_convention
+ (gdbarch, hppa64_use_struct_convention);
+ set_gdbarch_deprecated_store_return_value
+ (gdbarch, hppa64_store_return_value);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "Unsupported address size: %d",
+ tdep->bytes_per_address);
+ }
- set_gdbarch_reg_struct_has_addr (gdbarch, hppa_reg_struct_has_addr);
+ /* The following gdbarch vector elements depend on other parts of this
+ vector which have been set above, depending on the ABI. */
+ set_gdbarch_deprecated_register_bytes
+ (gdbarch, gdbarch_num_regs (gdbarch) * tdep->bytes_per_address);
+ set_gdbarch_long_bit (gdbarch, tdep->bytes_per_address * TARGET_CHAR_BIT);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_ptr_bit (gdbarch, tdep->bytes_per_address * TARGET_CHAR_BIT);
+
+ /* The following gdbarch vector elements do not depend on the address
+ size, or in any other gdbarch element previously set. */
set_gdbarch_function_start_offset (gdbarch, 0);
set_gdbarch_skip_prologue (gdbarch, hppa_skip_prologue);
set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
hppa_in_solib_return_trampoline);
set_gdbarch_deprecated_saved_pc_after_call (gdbarch, hppa_saved_pc_after_call);
set_gdbarch_inner_than (gdbarch, hppa_inner_than);
- set_gdbarch_stack_align (gdbarch, hppa_stack_align);
set_gdbarch_decr_pc_after_break (gdbarch, 0);
- set_gdbarch_deprecated_register_size (gdbarch, 4);
- set_gdbarch_num_regs (gdbarch, hppa_num_regs);
+ set_gdbarch_deprecated_register_size (gdbarch, tdep->bytes_per_address);
set_gdbarch_deprecated_fp_regnum (gdbarch, 3);
set_gdbarch_sp_regnum (gdbarch, 30);
set_gdbarch_fp0_regnum (gdbarch, 64);
set_gdbarch_pc_regnum (gdbarch, PCOQ_HEAD_REGNUM);
set_gdbarch_npc_regnum (gdbarch, PCOQ_TAIL_REGNUM);
- set_gdbarch_register_raw_size (gdbarch, hppa_register_raw_size);
- set_gdbarch_register_bytes (gdbarch, hppa_num_regs * 4);
- set_gdbarch_register_byte (gdbarch, hppa_register_byte);
- set_gdbarch_register_virtual_size (gdbarch, hppa_register_raw_size);
- set_gdbarch_deprecated_max_register_raw_size (gdbarch, 4);
+ set_gdbarch_deprecated_register_raw_size (gdbarch, hppa_register_raw_size);
+ set_gdbarch_deprecated_register_byte (gdbarch, hppa_register_byte);
+ set_gdbarch_deprecated_register_virtual_size (gdbarch, hppa_register_raw_size);
+ set_gdbarch_deprecated_max_register_raw_size (gdbarch, tdep->bytes_per_address);
set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 8);
- set_gdbarch_register_virtual_type (gdbarch, hppa_register_virtual_type);
set_gdbarch_deprecated_store_struct_return (gdbarch, hppa_store_struct_return);
- set_gdbarch_deprecated_extract_return_value (gdbarch,
- hppa_extract_return_value);
- set_gdbarch_use_struct_convention (gdbarch, hppa_use_struct_convention);
- set_gdbarch_deprecated_store_return_value (gdbarch, hppa_store_return_value);
set_gdbarch_deprecated_extract_struct_value_address
(gdbarch, hppa_extract_struct_value_address);
set_gdbarch_cannot_store_register (gdbarch, hppa_cannot_store_register);
set_gdbarch_frameless_function_invocation
(gdbarch, hppa_frameless_function_invocation);
set_gdbarch_deprecated_frame_saved_pc (gdbarch, hppa_frame_saved_pc);
- set_gdbarch_frame_args_address (gdbarch, hppa_frame_args_address);
- set_gdbarch_frame_locals_address (gdbarch, hppa_frame_locals_address);
- set_gdbarch_frame_num_args (gdbarch, hppa_frame_num_args);
set_gdbarch_frame_args_skip (gdbarch, 0);
set_gdbarch_deprecated_push_dummy_frame (gdbarch, hppa_push_dummy_frame);
set_gdbarch_deprecated_pop_frame (gdbarch, hppa_pop_frame);
- set_gdbarch_deprecated_call_dummy_length (gdbarch, INSTRUCTION_SIZE * 28);
/* set_gdbarch_deprecated_fix_call_dummy (gdbarch, hppa_fix_call_dummy); */
set_gdbarch_deprecated_push_arguments (gdbarch, hppa_push_arguments);
+ set_gdbarch_addr_bits_remove (gdbarch, hppa_smash_text_address);
set_gdbarch_smash_text_address (gdbarch, hppa_smash_text_address);
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
set_gdbarch_read_pc (gdbarch, hppa_target_read_pc);
set_gdbarch_write_pc (gdbarch, hppa_target_write_pc);
set_gdbarch_deprecated_target_read_fp (gdbarch, hppa_target_read_fp);
+ /* Helper for function argument information. */
+ set_gdbarch_fetch_pointer_argument (gdbarch, hppa_fetch_pointer_argument);
+
+ set_gdbarch_print_insn (gdbarch, print_insn_hppa);
+
+ /* When a hardware watchpoint triggers, we'll move the inferior past
+ it by removing all eventpoints; stepping past the instruction
+ that caused the trigger; reinserting eventpoints; and checking
+ whether any watched location changed. */
+ set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
+
+ /* Hook in ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch);
+
return gdbarch;
}
void break_at_finish_at_depth_command (char *arg, int from_tty);
gdbarch_register (bfd_arch_hppa, hppa_gdbarch_init, hppa_dump_tdep);
- deprecated_tm_print_insn = print_insn_hppa;
add_cmd ("unwind", class_maintenance, unwind_command,
"Print unwind table entry at given address.",