#include "value.h"
#include "parser-defs.h"
#include "osabi.h"
+#include "infcall.h"
#include "libbfd.h" /* for bfd_default_set_arch_mach */
#include "coff/internal.h" /* for libcoff.h */
}
+/* Return true if REGNO is an SPE register, false otherwise. */
+int
+spe_register_p (int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ /* Is it a reference to EV0 -- EV31, and do we have those? */
+ if (tdep->ppc_ev0_regnum >= 0
+ && tdep->ppc_ev31_regnum >= 0
+ && tdep->ppc_ev0_regnum <= regno && regno <= tdep->ppc_ev31_regnum)
+ return 1;
+
+ /* Is it a reference to the 64-bit accumulator, and do we have that? */
+ if (tdep->ppc_acc_regnum >= 0
+ && tdep->ppc_acc_regnum == regno)
+ return 1;
+
+ /* Is it a reference to the SPE floating-point status and control register,
+ and do we have that? */
+ if (tdep->ppc_spefscr_regnum >= 0
+ && tdep->ppc_spefscr_regnum == regno)
+ return 1;
+
+ return 0;
+}
+
+
/* Return non-zero if the architecture described by GDBARCH has
floating-point registers (f0 --- f31 and fpscr). */
int
starting from r4. */
static CORE_ADDR
-rs6000_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct regcache *regcache, CORE_ADDR bp_addr,
int nargs, struct value **args, CORE_ADDR sp,
int struct_return, CORE_ADDR struct_addr)
char tmp_buffer[50];
int f_argno = 0; /* current floating point argno */
int wordsize = gdbarch_tdep (current_gdbarch)->wordsize;
+ CORE_ADDR func_addr = find_function_addr (function, NULL);
struct value *arg = 0;
struct type *type;
there is no way we would run out of them. */
if (len > 8)
- printf_unfiltered (
- "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
+ printf_unfiltered ("Fatal Error: a floating point parameter "
+ "#%d with a size > 8 is found!\n", argno);
memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE
(tdep->ppc_fp0_regnum + 1 + f_argno)],
{
if (len > 8)
- printf_unfiltered (
- "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
+ printf_unfiltered ("Fatal Error: a floating point parameter"
+ " #%d with a size > 8 is found!\n", argno);
memcpy (&(deprecated_registers
[DEPRECATED_REGISTER_BYTE
++f_argno;
}
- write_memory (sp + 24 + (ii * 4), (char *) VALUE_CONTENTS (arg), len);
+ write_memory (sp + 24 + (ii * 4),
+ (char *) VALUE_CONTENTS (arg),
+ len);
ii += ((len + 3) & -4) / 4;
}
}
return reg->name;
}
-/* Index within `registers' of the first byte of the space for
- register N. */
-
-static int
-rs6000_register_byte (int n)
-{
- return gdbarch_tdep (current_gdbarch)->regoff[n];
-}
-
-/* Return the number of bytes of storage in the actual machine representation
- for register N if that register is available, else return 0. */
-
-static int
-rs6000_register_raw_size (int n)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- const struct reg *reg = tdep->regs + n;
- return regsize (reg, tdep->wordsize);
-}
-
/* Return the GDB type object for the "standard" data type
of data in register N. */
static struct type *
-rs6000_register_virtual_type (int n)
+rs6000_register_type (struct gdbarch *gdbarch, int n)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
const struct reg *reg = tdep->regs + n;
if (reg->fpr)
}
}
-/* Return whether register N requires conversion when moving from raw format
- to virtual format.
-
- The register format for RS/6000 floating point registers is always
+/* The register format for RS/6000 floating point registers is always
double, we need a conversion if the memory format is float. */
static int
-rs6000_register_convertible (int n)
+rs6000_convert_register_p (int regnum, struct type *type)
{
- const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + n;
- return reg->fpr;
+ const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum;
+
+ return (reg->fpr
+ && TYPE_CODE (type) == TYPE_CODE_FLT
+ && TYPE_LENGTH (type) != TYPE_LENGTH (builtin_type_double));
}
-/* Convert data from raw format for register N in buffer FROM
- to virtual format with type TYPE in buffer TO. */
-
static void
-rs6000_register_convert_to_virtual (int n, struct type *type,
- char *from, char *to)
+rs6000_register_to_value (struct frame_info *frame,
+ int regnum,
+ struct type *type,
+ void *to)
{
- if (TYPE_LENGTH (type) != DEPRECATED_REGISTER_RAW_SIZE (n))
- {
- double val = deprecated_extract_floating (from, DEPRECATED_REGISTER_RAW_SIZE (n));
- deprecated_store_floating (to, TYPE_LENGTH (type), val);
- }
- else
- memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (n));
-}
+ const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum;
+ char from[MAX_REGISTER_SIZE];
+
+ gdb_assert (reg->fpr);
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
-/* Convert data from virtual format with type TYPE in buffer FROM
- to raw format for register N in buffer TO. */
+ get_frame_register (frame, regnum, from);
+ convert_typed_floating (from, builtin_type_double, to, type);
+}
static void
-rs6000_register_convert_to_raw (struct type *type, int n,
- const char *from, char *to)
+rs6000_value_to_register (struct frame_info *frame,
+ int regnum,
+ struct type *type,
+ const void *from)
{
- if (TYPE_LENGTH (type) != DEPRECATED_REGISTER_RAW_SIZE (n))
- {
- double val = deprecated_extract_floating (from, TYPE_LENGTH (type));
- deprecated_store_floating (to, DEPRECATED_REGISTER_RAW_SIZE (n), val);
- }
- else
- memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (n));
+ const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum;
+ char to[MAX_REGISTER_SIZE];
+
+ gdb_assert (reg->fpr);
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+
+ convert_typed_floating (from, type, to, builtin_type_double);
+ put_frame_register (frame, regnum, to);
}
static void
}
}
-/* Convert a dbx stab or Dwarf 2 register number (from `r'
- declaration) to a gdb REGNUM. */
+/* Convert a DBX STABS register number to a GDB register number. */
static int
-rs6000_dwarf2_stab_reg_to_regnum (int num)
+rs6000_stab_reg_to_regnum (int num)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
specifies registers the architecture doesn't have? Our
callers don't check the value we return. */
return tdep->ppc_fp0_regnum + (num - 32);
+ else if (77 <= num && num <= 108)
+ return tdep->ppc_vr0_regnum + (num - 77);
else if (1200 <= num && num < 1200 + 32)
return tdep->ppc_ev0_regnum + (num - 1200);
else
return tdep->ppc_xer_regnum;
case 109:
return tdep->ppc_vrsave_regnum;
+ case 110:
+ return tdep->ppc_vrsave_regnum - 1; /* vscr */
+ case 111:
+ return tdep->ppc_acc_regnum;
+ case 112:
+ return tdep->ppc_spefscr_regnum;
default:
return num;
}
+}
- /* FIXME: jimb/2004-03-28: Doesn't something need to be done here
- for the Altivec registers, too?
- Looking at GCC, the headers in config/rs6000 never define a
- DBX_REGISTER_NUMBER macro, so the debug info uses the same
- numbers GCC does internally. Then, looking at the REGISTER_NAMES
- macro defined in config/rs6000/rs6000.h, it seems that GCC gives
- v0 -- v31 the numbers 77 -- 108. But we number them 119 -- 150.
+/* Convert a Dwarf 2 register number to a GDB register number. */
+static int
+rs6000_dwarf2_reg_to_regnum (int num)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- I don't have a way to test this ready to hand, but I noticed it
- and thought I should include a note. */
+ if (0 <= num && num <= 31)
+ return tdep->ppc_gp0_regnum + num;
+ else if (32 <= num && num <= 63)
+ /* FIXME: jimb/2004-05-05: What should we do when the debug info
+ specifies registers the architecture doesn't have? Our
+ callers don't check the value we return. */
+ return tdep->ppc_fp0_regnum + (num - 32);
+ else if (1124 <= num && num < 1124 + 32)
+ return tdep->ppc_vr0_regnum + (num - 1124);
+ else if (1200 <= num && num < 1200 + 32)
+ return tdep->ppc_ev0_regnum + (num - 1200);
+ else
+ switch (num)
+ {
+ case 67:
+ return tdep->ppc_vrsave_regnum - 1; /* vscr */
+ case 99:
+ return tdep->ppc_acc_regnum;
+ case 100:
+ return tdep->ppc_mq_regnum;
+ case 101:
+ return tdep->ppc_xer_regnum;
+ case 108:
+ return tdep->ppc_lr_regnum;
+ case 109:
+ return tdep->ppc_ctr_regnum;
+ case 356:
+ return tdep->ppc_vrsave_regnum;
+ case 612:
+ return tdep->ppc_spefscr_regnum;
+ default:
+ return num;
+ }
}
+
static void
-rs6000_store_return_value (struct type *type, char *valbuf)
+rs6000_store_return_value (struct type *type,
+ struct regcache *regcache,
+ const void *valbuf)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int regnum = -1;
/* The calling convention this function implements assumes the
processor has floating-point registers. We shouldn't be using it
on PPC variants that lack them. */
- gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
+ gdb_assert (ppc_floating_point_unit_p (gdbarch));
if (TYPE_CODE (type) == TYPE_CODE_FLT)
-
/* Floating point values are returned starting from FPR1 and up.
Say a double_double_double type could be returned in
FPR1/FPR2/FPR3 triple. */
-
- deprecated_write_register_bytes
- (DEPRECATED_REGISTER_BYTE (tdep->ppc_fp0_regnum + 1),
- valbuf,
- TYPE_LENGTH (type));
+ regnum = tdep->ppc_fp0_regnum + 1;
else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
{
if (TYPE_LENGTH (type) == 16
&& TYPE_VECTOR (type))
- deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
- valbuf, TYPE_LENGTH (type));
+ regnum = tdep->ppc_vr0_regnum + 2;
+ else
+ gdb_assert (0);
}
else
/* Everything else is returned in GPR3 and up. */
- deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3),
- valbuf, TYPE_LENGTH (type));
+ regnum = tdep->ppc_gp0_regnum + 3;
+
+ {
+ size_t bytes_written = 0;
+
+ while (bytes_written < TYPE_LENGTH (type))
+ {
+ /* How much of this value can we write to this register? */
+ size_t bytes_to_write = min (TYPE_LENGTH (type) - bytes_written,
+ register_size (gdbarch, regnum));
+ regcache_cooked_write_part (regcache, regnum,
+ 0, bytes_to_write,
+ (char *) valbuf + bytes_written);
+ regnum++;
+ bytes_written += bytes_to_write;
+ }
+ }
}
+
/* Extract from an array REGBUF containing the (raw) register state
the address in which a function should return its structure value,
as a CORE_ADDR (or an expression that can be used as one). */
tdep->ppc_vrsave_regnum = -1;
tdep->ppc_ev0_regnum = -1;
tdep->ppc_ev31_regnum = -1;
+ tdep->ppc_acc_regnum = -1;
+ tdep->ppc_spefscr_regnum = -1;
set_gdbarch_pc_regnum (gdbarch, 64);
set_gdbarch_sp_regnum (gdbarch, 1);
else
{
set_gdbarch_deprecated_extract_return_value (gdbarch, rs6000_extract_return_value);
- set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value);
+ set_gdbarch_store_return_value (gdbarch, rs6000_store_return_value);
}
/* Set lr_frame_offset. */
else
tdep->lr_frame_offset = 8;
- /* Calculate byte offsets in raw register array. */
- tdep->regoff = xmalloc (v->num_tot_regs * sizeof (int));
- for (i = off = 0; i < v->num_tot_regs; i++)
- {
- tdep->regoff[i] = off;
- off += regsize (v->regs + i, wordsize);
- }
-
if (v->arch == bfd_arch_powerpc)
switch (v->mach)
{
tdep->ppc_ev31_regnum = 38;
tdep->ppc_fp0_regnum = -1;
tdep->ppc_fpscr_regnum = -1;
+ tdep->ppc_acc_regnum = 39;
+ tdep->ppc_spefscr_regnum = 40;
set_gdbarch_pc_regnum (gdbarch, 0);
set_gdbarch_sp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1);
set_gdbarch_deprecated_fp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1);
set_gdbarch_num_regs (gdbarch, v->nregs);
set_gdbarch_num_pseudo_regs (gdbarch, v->npregs);
set_gdbarch_register_name (gdbarch, rs6000_register_name);
- set_gdbarch_deprecated_register_size (gdbarch, wordsize);
- set_gdbarch_deprecated_register_bytes (gdbarch, off);
- set_gdbarch_deprecated_register_byte (gdbarch, rs6000_register_byte);
- set_gdbarch_deprecated_register_raw_size (gdbarch, rs6000_register_raw_size);
- set_gdbarch_deprecated_register_virtual_type (gdbarch, rs6000_register_virtual_type);
+ set_gdbarch_register_type (gdbarch, rs6000_register_type);
set_gdbarch_ptr_bit (gdbarch, wordsize * TARGET_CHAR_BIT);
set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
224. */
set_gdbarch_frame_red_zone_size (gdbarch, 224);
- set_gdbarch_deprecated_register_convertible (gdbarch, rs6000_register_convertible);
- set_gdbarch_deprecated_register_convert_to_virtual (gdbarch, rs6000_register_convert_to_virtual);
- set_gdbarch_deprecated_register_convert_to_raw (gdbarch, rs6000_register_convert_to_raw);
- set_gdbarch_stab_reg_to_regnum (gdbarch, rs6000_dwarf2_stab_reg_to_regnum);
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, rs6000_dwarf2_stab_reg_to_regnum);
+ set_gdbarch_convert_register_p (gdbarch, rs6000_convert_register_p);
+ set_gdbarch_register_to_value (gdbarch, rs6000_register_to_value);
+ set_gdbarch_value_to_register (gdbarch, rs6000_value_to_register);
+
+ set_gdbarch_stab_reg_to_regnum (gdbarch, rs6000_stab_reg_to_regnum);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, rs6000_dwarf2_reg_to_regnum);
/* Note: kevinb/2002-04-12: I'm not convinced that rs6000_push_arguments()
is correct for the SysV ABI when the wordsize is 8, but I'm also
fairly certain that ppc_sysv_abi_push_arguments() will give even