mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 01:07:52 +00:00
* ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call): Check the selected
soft float and vector ABIs. Support the generic vector ABI for AltiVec types. (do_ppc_sysv_return_value): Likewise. Correct argument types and casts. (ppc64_sysv_abi_push_dummy_call): Assert that floating point is supported. * ppc-tdep.h (enum powerpc_vector_abi): New. (struct gdbarch_tdep): Add soft_float and vector_abi. * rs6000-tdep.c (setpowerpccmdlist, showpowerpccmdlist) (powerpc_soft_float_global, powerpc_vector_strings) (powerpc_vector_abi_global, powerpc_vector_abi_string): New. (rs6000_gdbarch_init): Check for soft-float and vector ABI markings. (set_powerpc_command, show_powerpc_command, powerpc_set_soft_float) (powerpc_set_vector_abi): New. (_initialize_rs6000_tdep): Register "set powerpc" and "show powerpc" commands. * Makefile.in (elf_ppc_h): New. (rs6000-tdep.o): Update. * gdb.texinfo (PowerPC): Document "set powerpc vector-abi" and "set powerpc soft-float". * gdb.arch/altivec-abi.exp: Run multiple times for GCC on GNU/Linux. Test "set powerpc vector-abi". Skip auto-detection tests for old toolchains.
This commit is contained in:
@@ -49,6 +49,7 @@
|
||||
#include "libxcoff.h"
|
||||
|
||||
#include "elf-bfd.h"
|
||||
#include "elf/ppc.h"
|
||||
|
||||
#include "solib-svr4.h"
|
||||
#include "ppc-tdep.h"
|
||||
@@ -77,6 +78,27 @@
|
||||
#include "features/rs6000/powerpc-e500.c"
|
||||
#include "features/rs6000/rs6000.c"
|
||||
|
||||
/* The list of available "set powerpc ..." and "show powerpc ..."
|
||||
commands. */
|
||||
static struct cmd_list_element *setpowerpccmdlist = NULL;
|
||||
static struct cmd_list_element *showpowerpccmdlist = NULL;
|
||||
|
||||
static enum auto_boolean powerpc_soft_float_global = AUTO_BOOLEAN_AUTO;
|
||||
|
||||
/* The vector ABI to use. Keep this in sync with powerpc_vector_abi. */
|
||||
static const char *powerpc_vector_strings[] =
|
||||
{
|
||||
"auto",
|
||||
"generic",
|
||||
"altivec",
|
||||
"spe",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* A variable that can be configured by the user. */
|
||||
static enum powerpc_vector_abi powerpc_vector_abi_global = POWERPC_VEC_AUTO;
|
||||
static const char *powerpc_vector_abi_string = "auto";
|
||||
|
||||
/* If the kernel has to deliver a signal, it pushes a sigcontext
|
||||
structure on the stack and then calls the signal handler, passing
|
||||
the address of the sigcontext in an argument register. Usually
|
||||
@@ -3145,6 +3167,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
bfd abfd;
|
||||
int sysv_abi;
|
||||
asection *sect;
|
||||
enum auto_boolean soft_float_flag = powerpc_soft_float_global;
|
||||
int soft_float;
|
||||
enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
|
||||
int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0;
|
||||
int tdesc_wordsize = -1;
|
||||
const struct target_desc *tdesc = info.target_desc;
|
||||
@@ -3417,6 +3442,76 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ELF
|
||||
if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec)
|
||||
{
|
||||
switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
|
||||
Tag_GNU_Power_ABI_FP))
|
||||
{
|
||||
case 1:
|
||||
soft_float_flag = AUTO_BOOLEAN_FALSE;
|
||||
break;
|
||||
case 2:
|
||||
soft_float_flag = AUTO_BOOLEAN_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vector_abi == POWERPC_VEC_AUTO && from_elf_exec)
|
||||
{
|
||||
switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
|
||||
Tag_GNU_Power_ABI_Vector))
|
||||
{
|
||||
case 1:
|
||||
vector_abi = POWERPC_VEC_GENERIC;
|
||||
break;
|
||||
case 2:
|
||||
vector_abi = POWERPC_VEC_ALTIVEC;
|
||||
break;
|
||||
case 3:
|
||||
vector_abi = POWERPC_VEC_SPE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (soft_float_flag == AUTO_BOOLEAN_TRUE)
|
||||
soft_float = 1;
|
||||
else if (soft_float_flag == AUTO_BOOLEAN_FALSE)
|
||||
soft_float = 0;
|
||||
else
|
||||
soft_float = !have_fpu;
|
||||
|
||||
/* If we have a hard float binary or setting but no floating point
|
||||
registers, downgrade to soft float anyway. We're still somewhat
|
||||
useful in this scenario. */
|
||||
if (!soft_float && !have_fpu)
|
||||
soft_float = 1;
|
||||
|
||||
/* Similarly for vector registers. */
|
||||
if (vector_abi == POWERPC_VEC_ALTIVEC && !have_altivec)
|
||||
vector_abi = POWERPC_VEC_GENERIC;
|
||||
|
||||
if (vector_abi == POWERPC_VEC_SPE && !have_spe)
|
||||
vector_abi = POWERPC_VEC_GENERIC;
|
||||
|
||||
if (vector_abi == POWERPC_VEC_AUTO)
|
||||
{
|
||||
if (have_altivec)
|
||||
vector_abi = POWERPC_VEC_ALTIVEC;
|
||||
else if (have_spe)
|
||||
vector_abi = POWERPC_VEC_SPE;
|
||||
else
|
||||
vector_abi = POWERPC_VEC_GENERIC;
|
||||
}
|
||||
|
||||
/* Do not limit the vector ABI based on available hardware, since we
|
||||
do not yet know what hardware we'll decide we have. Yuck! FIXME! */
|
||||
|
||||
/* Find a candidate among extant architectures. */
|
||||
for (arches = gdbarch_list_lookup_by_info (arches, &info);
|
||||
arches != NULL;
|
||||
@@ -3426,6 +3521,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform
|
||||
separate word size check. */
|
||||
tdep = gdbarch_tdep (arches->gdbarch);
|
||||
if (tdep && tdep->soft_float != soft_float)
|
||||
continue;
|
||||
if (tdep && tdep->vector_abi != vector_abi)
|
||||
continue;
|
||||
if (tdep && tdep->wordsize == wordsize)
|
||||
{
|
||||
if (tdesc_data != NULL)
|
||||
@@ -3444,6 +3543,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
|
||||
tdep = XCALLOC (1, struct gdbarch_tdep);
|
||||
tdep->wordsize = wordsize;
|
||||
tdep->soft_float = soft_float;
|
||||
tdep->vector_abi = vector_abi;
|
||||
|
||||
gdbarch = gdbarch_alloc (&info, tdep);
|
||||
|
||||
@@ -3643,6 +3744,61 @@ rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
/* FIXME: Dump gdbarch_tdep. */
|
||||
}
|
||||
|
||||
/* PowerPC-specific commands. */
|
||||
|
||||
static void
|
||||
set_powerpc_command (char *args, int from_tty)
|
||||
{
|
||||
printf_unfiltered (_("\
|
||||
\"set powerpc\" must be followed by an appropriate subcommand.\n"));
|
||||
help_list (setpowerpccmdlist, "set powerpc ", all_commands, gdb_stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
show_powerpc_command (char *args, int from_tty)
|
||||
{
|
||||
cmd_show_list (showpowerpccmdlist, from_tty, "");
|
||||
}
|
||||
|
||||
static void
|
||||
powerpc_set_soft_float (char *args, int from_tty,
|
||||
struct cmd_list_element *c)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
|
||||
/* Update the architecture. */
|
||||
gdbarch_info_init (&info);
|
||||
if (!gdbarch_update_p (info))
|
||||
internal_error (__FILE__, __LINE__, "could not update architecture");
|
||||
}
|
||||
|
||||
static void
|
||||
powerpc_set_vector_abi (char *args, int from_tty,
|
||||
struct cmd_list_element *c)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
enum powerpc_vector_abi vector_abi;
|
||||
|
||||
for (vector_abi = POWERPC_VEC_AUTO;
|
||||
vector_abi != POWERPC_VEC_LAST;
|
||||
vector_abi++)
|
||||
if (strcmp (powerpc_vector_abi_string,
|
||||
powerpc_vector_strings[vector_abi]) == 0)
|
||||
{
|
||||
powerpc_vector_abi_global = vector_abi;
|
||||
break;
|
||||
}
|
||||
|
||||
if (vector_abi == POWERPC_VEC_LAST)
|
||||
internal_error (__FILE__, __LINE__, _("Invalid vector ABI accepted: %s."),
|
||||
powerpc_vector_abi_string);
|
||||
|
||||
/* Update the architecture. */
|
||||
gdbarch_info_init (&info);
|
||||
if (!gdbarch_update_p (info))
|
||||
internal_error (__FILE__, __LINE__, "could not update architecture");
|
||||
}
|
||||
|
||||
/* Initialization code. */
|
||||
|
||||
extern initialize_file_ftype _initialize_rs6000_tdep; /* -Wmissing-prototypes */
|
||||
@@ -3668,4 +3824,30 @@ _initialize_rs6000_tdep (void)
|
||||
initialize_tdesc_powerpc_860 ();
|
||||
initialize_tdesc_powerpc_e500 ();
|
||||
initialize_tdesc_rs6000 ();
|
||||
|
||||
/* Add root prefix command for all "set powerpc"/"show powerpc"
|
||||
commands. */
|
||||
add_prefix_cmd ("powerpc", no_class, set_powerpc_command,
|
||||
_("Various PowerPC-specific commands."),
|
||||
&setpowerpccmdlist, "set powerpc ", 0, &setlist);
|
||||
|
||||
add_prefix_cmd ("powerpc", no_class, show_powerpc_command,
|
||||
_("Various PowerPC-specific commands."),
|
||||
&showpowerpccmdlist, "show powerpc ", 0, &showlist);
|
||||
|
||||
/* Add a command to allow the user to force the ABI. */
|
||||
add_setshow_auto_boolean_cmd ("soft-float", class_support,
|
||||
&powerpc_soft_float_global,
|
||||
_("Set whether to use a soft-float ABI."),
|
||||
_("Show whether to use a soft-float ABI."),
|
||||
NULL,
|
||||
powerpc_set_soft_float, NULL,
|
||||
&setpowerpccmdlist, &showpowerpccmdlist);
|
||||
|
||||
add_setshow_enum_cmd ("vector-abi", class_support, powerpc_vector_strings,
|
||||
&powerpc_vector_abi_string,
|
||||
_("Set the vector ABI."),
|
||||
_("Show the vector ABI."),
|
||||
NULL, powerpc_set_vector_abi, NULL,
|
||||
&setpowerpccmdlist, &showpowerpccmdlist);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user