From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32551 invoked by alias); 30 Oct 2007 19:38:15 -0000 Received: (qmail 32523 invoked by uid 22791); 30 Oct 2007 19:38:10 -0000 X-Spam-Check-By: sourceware.org Received: from NaN.false.org (HELO nan.false.org) (208.75.86.248) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 30 Oct 2007 19:38:00 +0000 Received: from nan.false.org (localhost [127.0.0.1]) by nan.false.org (Postfix) with ESMTP id 23C1E98348; Tue, 30 Oct 2007 19:37:58 +0000 (GMT) Received: from caradoc.them.org (22.svnf5.xdsl.nauticom.net [209.195.183.55]) by nan.false.org (Postfix) with ESMTP id AB913980A5; Tue, 30 Oct 2007 19:37:57 +0000 (GMT) Received: from drow by caradoc.them.org with local (Exim 4.68) (envelope-from ) id 1ImwuS-0002uZ-Jx; Tue, 30 Oct 2007 15:37:56 -0400 Date: Tue, 30 Oct 2007 20:12:00 -0000 From: Daniel Jacobowitz To: Ulrich Weigand , gdb-patches@sourceware.org Subject: Re: [rfc] PowerPC ABI detection and overrides Message-ID: <20071030193756.GA27004@caradoc.them.org> Mail-Followup-To: Ulrich Weigand , gdb-patches@sourceware.org References: <20071021130504.GA10828@caradoc.them.org> <200710211807.l9LI7vCL011126@d12av02.megacenter.de.ibm.com> <20071025195932.GA4791@caradoc.them.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20071025195932.GA4791@caradoc.them.org> User-Agent: Mutt/1.5.15 (2007-04-09) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-10/txt/msg00825.txt.bz2 On Thu, Oct 25, 2007 at 03:59:32PM -0400, Daniel Jacobowitz wrote: > The patch makes GDB look at ABI markings in ELF files for both hard > versus soft floating point and AltiVec versus SPE versus generic > vectors. There are also new commands to force the right behavior > and documentation for them. Here's what I checked in. This skips some of the tests when using ELF without ABI markings, but still runs enough to be useful - the tests fail in a way that's hard to XFAIL, since the generic ABI uses pass by reference so we end up with bad pointers. Tested on powerpc-linux using gdbserver, -maltivec, -mabi=altivec. Checked in. -- Daniel Jacobowitz CodeSourcery 2007-10-30 Daniel Jacobowitz * 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. 2007-10-30 Daniel Jacobowitz * gdb.texinfo (PowerPC): Document "set powerpc vector-abi" and "set powerpc soft-float". 2007-10-30 Daniel Jacobowitz * 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. Index: Makefile.in =================================================================== RCS file: /scratch/gcc/repos/src/src/gdb/Makefile.in,v retrieving revision 1.954 diff -u -p -r1.954 Makefile.in --- Makefile.in 25 Oct 2007 17:52:31 -0000 1.954 +++ Makefile.in 30 Oct 2007 15:06:46 -0000 @@ -604,6 +604,7 @@ elf_bfd_h = $(BFD_SRC)/elf-bfd.h elf_frv_h = $(INCLUDE_DIR)/elf/frv.h $(elf_reloc_macros_h) elf_m32c_h = $(INCLUDE_DIR)/elf/m32c.h $(elf_reloc_macros_h) elf_mep_h = $(INCLUDE_DIR)/elf/mep.h $(elf_reloc_macros_h) +elf_ppc_h = $(INCLUDE_DIR)/elf/ppc.h $(elf_reloc_macros_h) libaout_h = $(BFD_SRC)/libaout.h libiberty_h = $(INCLUDE_DIR)/libiberty.h libbfd_h = $(BFD_SRC)/libbfd.h @@ -2578,7 +2579,7 @@ rs6000-tdep.o: rs6000-tdep.c $(defs_h) $ $(coff_xcoff_h) $(libxcoff_h) $(elf_bfd_h) $(solib_svr4_h) \ $(ppc_tdep_h) $(gdb_assert_h) $(dis_asm_h) $(trad_frame_h) \ $(frame_unwind_h) $(frame_base_h) $(rs6000_tdep_h) $(dwarf2_frame_h) \ - $(target_descriptions) $(user_regs_h) \ + $(target_descriptions) $(user_regs_h) $(elf_ppc_h) \ $(powerpc_32_c) $(powerpc_403_c) $(powerpc_403gc_c) $(powerpc_505_c) \ $(powerpc_601_c) $(powerpc_602_c) $(powerpc_603_c) $(powerpc_604_c) \ $(powerpc_64_c) $(powerpc_7400_c) $(powerpc_750_c) $(powerpc_860_c) \ Index: ppc-sysv-tdep.c =================================================================== RCS file: /scratch/gcc/repos/src/src/gdb/ppc-sysv-tdep.c,v retrieving revision 1.40 diff -u -p -r1.40 ppc-sysv-tdep.c --- ppc-sysv-tdep.c 6 Sep 2007 20:21:16 -0000 1.40 +++ ppc-sysv-tdep.c 30 Oct 2007 15:38:38 -0000 @@ -104,8 +104,8 @@ ppc_sysv_abi_push_dummy_call (struct gdb int len = TYPE_LENGTH (type); const bfd_byte *val = value_contents (arg); - if (TYPE_CODE (type) == TYPE_CODE_FLT - && ppc_floating_point_unit_p (current_gdbarch) && len <= 8) + if (TYPE_CODE (type) == TYPE_CODE_FLT && len <= 8 + && !tdep->soft_float) { /* Floating point value converted to "double" then passed in an FP register, when the registers run out, @@ -141,10 +141,11 @@ ppc_sysv_abi_push_dummy_call (struct gdb argoffset += 8; } } - else if (len == 8 && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */ - || (!ppc_floating_point_unit_p (current_gdbarch) && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */ + else if (len == 8 + && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */ + || TYPE_CODE (type) == TYPE_CODE_FLT)) /* double */ { - /* "long long" or "double" passed in an odd/even + /* "long long" or soft-float "double" passed in an odd/even register pair with the low addressed word in the odd register and the high addressed word in the even register, or when the registers run out an 8 byte @@ -184,7 +185,8 @@ ppc_sysv_abi_push_dummy_call (struct gdb } else if (len == 16 && TYPE_CODE (type) == TYPE_CODE_ARRAY - && TYPE_VECTOR (type) && tdep->ppc_vr0_regnum >= 0) + && TYPE_VECTOR (type) + && tdep->vector_abi == POWERPC_VEC_ALTIVEC) { /* Vector parameter passed in an Altivec register, or when that runs out, 16 byte aligned stack location. */ @@ -205,7 +207,8 @@ ppc_sysv_abi_push_dummy_call (struct gdb } else if (len == 8 && TYPE_CODE (type) == TYPE_CODE_ARRAY - && TYPE_VECTOR (type) && tdep->ppc_ev0_regnum >= 0) + && TYPE_VECTOR (type) + && tdep->vector_abi == POWERPC_VEC_SPE) { /* Vector parameter passed in an e500 register, or when that runs out, 8 byte aligned stack location. Note @@ -239,9 +242,15 @@ ppc_sysv_abi_push_dummy_call (struct gdb || TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION) { - /* Structs and large values are put on an 8 byte - aligned stack ... */ - structoffset = align_up (structoffset, 8); + /* Structs and large values are put in an + aligned stack slot ... */ + if (TYPE_CODE (type) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type) + && len >= 16) + structoffset = align_up (structoffset, 16); + else + structoffset = align_up (structoffset, 8); + if (write_pass) write_memory (sp + structoffset, val, len); /* ... and then a "word" pointing to that address is @@ -337,14 +346,14 @@ ppc_sysv_abi_push_dummy_call (struct gdb static enum return_value_convention do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, - struct regcache *regcache, void *readbuf, - const void *writebuf, int broken_gcc) + struct regcache *regcache, gdb_byte *readbuf, + const gdb_byte *writebuf, int broken_gcc) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); gdb_assert (tdep->wordsize == 4); if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8 - && ppc_floating_point_unit_p (gdbarch)) + && !tdep->soft_float) { if (readbuf) { @@ -374,17 +383,17 @@ do_ppc_sysv_return_value (struct gdbarch { /* A long long, or a double stored in the 32 bit r3/r4. */ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, - (bfd_byte *) readbuf + 0); + readbuf + 0); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, - (bfd_byte *) readbuf + 4); + readbuf + 4); } if (writebuf) { /* A long long, or a double stored in the 32 bit r3/r4. */ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, - (const bfd_byte *) writebuf + 0); + writebuf + 0); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, - (const bfd_byte *) writebuf + 4); + writebuf + 4); } return RETURN_VALUE_REGISTER_CONVENTION; } @@ -417,7 +426,8 @@ do_ppc_sysv_return_value (struct gdbarch } if (TYPE_LENGTH (type) == 16 && TYPE_CODE (type) == TYPE_CODE_ARRAY - && TYPE_VECTOR (type) && tdep->ppc_vr0_regnum >= 0) + && TYPE_VECTOR (type) + && tdep->vector_abi == POWERPC_VEC_ALTIVEC) { if (readbuf) { @@ -431,9 +441,42 @@ do_ppc_sysv_return_value (struct gdbarch } return RETURN_VALUE_REGISTER_CONVENTION; } + if (TYPE_LENGTH (type) == 16 + && TYPE_CODE (type) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type) + && tdep->vector_abi == POWERPC_VEC_GENERIC) + { + /* GCC -maltivec -mabi=no-altivec returns vectors in r3/r4/r5/r6. + GCC without AltiVec returns them in memory, but it warns about + ABI risks in that case; we don't try to support it. */ + if (readbuf) + { + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, + readbuf + 0); + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, + readbuf + 4); + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 5, + readbuf + 8); + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 6, + readbuf + 12); + } + if (writebuf) + { + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, + writebuf + 0); + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, + writebuf + 4); + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 5, + writebuf + 8); + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 6, + writebuf + 12); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } if (TYPE_LENGTH (type) == 8 && TYPE_CODE (type) == TYPE_CODE_ARRAY - && TYPE_VECTOR (type) && tdep->ppc_ev0_regnum >= 0) + && TYPE_VECTOR (type) + && tdep->vector_abi == POWERPC_VEC_SPE) { /* The e500 ABI places return values for the 64-bit DSP types (__ev64_opaque__) in r3. However, in GDB-speak, ev3 @@ -604,6 +647,11 @@ ppc64_sysv_abi_push_dummy_call (struct g the possible values of tdep->wordsize. */ gdb_assert (tdep->wordsize == 8); + /* This function exists to support a calling convention that + requires floating-point registers. It shouldn't be used on + processors that lack them. */ + gdb_assert (ppc_floating_point_unit_p (gdbarch)); + /* By this stage in the proceedings, SP has been decremented by "red zone size" + "struct return size". Fetch the stack-pointer from before this and use that as the BACK_CHAIN. */ @@ -685,8 +733,7 @@ ppc64_sysv_abi_push_dummy_call (struct g memory. */ if (write_pass) { - if (ppc_floating_point_unit_p (current_gdbarch) - && freg <= 13) + if (freg <= 13) { gdb_byte regval[MAX_REGISTER_SIZE]; struct type *regtype @@ -869,7 +916,7 @@ ppc64_sysv_abi_push_dummy_call (struct g } -/* The 64 bit ABI retun value convention. +/* The 64 bit ABI return value convention. Return non-zero if the return-value is stored in a register, return 0 if the return-value is instead stored on the stack (a.k.a., Index: ppc-tdep.h =================================================================== RCS file: /scratch/gcc/repos/src/src/gdb/ppc-tdep.h,v retrieving revision 1.59 diff -u -p -r1.59 ppc-tdep.h --- ppc-tdep.h 29 Oct 2007 20:26:42 -0000 1.59 +++ ppc-tdep.h 30 Oct 2007 15:06:46 -0000 @@ -157,9 +157,24 @@ extern void ppc_collect_vrregset (const /* Private data that this module attaches to struct gdbarch. */ +/* Vector ABI used by the inferior. */ +enum powerpc_vector_abi +{ + POWERPC_VEC_AUTO, + POWERPC_VEC_GENERIC, + POWERPC_VEC_ALTIVEC, + POWERPC_VEC_SPE, + POWERPC_VEC_LAST +}; + struct gdbarch_tdep { - int wordsize; /* size in bytes of fixed-point word */ + int wordsize; /* Size in bytes of fixed-point word. */ + int soft_float; /* Avoid FP registers for arguments? */ + + /* How to pass vector arguments. Never set to AUTO or LAST. */ + enum powerpc_vector_abi vector_abi; + int ppc_gp0_regnum; /* GPR register 0 */ int ppc_toc_regnum; /* TOC register */ int ppc_ps_regnum; /* Processor (or machine) status (%msr) */ Index: rs6000-tdep.c =================================================================== RCS file: /scratch/gcc/repos/src/src/gdb/rs6000-tdep.c,v retrieving revision 1.294 diff -u -p -r1.294 rs6000-tdep.c --- rs6000-tdep.c 29 Oct 2007 20:26:42 -0000 1.294 +++ rs6000-tdep.c 30 Oct 2007 15:06:46 -0000 @@ -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 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 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 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 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 *gdbarc /* 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); } Index: doc/gdb.texinfo =================================================================== RCS file: /scratch/gcc/repos/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.440 diff -u -p -r1.440 gdb.texinfo --- doc/gdb.texinfo 24 Oct 2007 21:05:36 -0000 1.440 +++ doc/gdb.texinfo 30 Oct 2007 15:06:46 -0000 @@ -14937,7 +14937,25 @@ Set suspend trace mode. @node PowerPC @subsection PowerPC +@value{GDBN} provides the following PowerPC-specific commands: + @table @code +@kindex set powerpc +@item set powerpc soft-float +@itemx show powerpc soft-float +Force @value{GDBN} to use (or not use) a software floating point calling +convention. By default, @value{GDBN} selects the calling convention based +on the selected architecture and the provided executable file. + +@item set powerpc vector-abi +@itemx show powerpc vector-abi +Force @value{GDBN} to use the specified calling convention for vector +arguments and return values. The valid options are @samp{auto}; +@samp{generic}, to avoid vector registers even if they are present; +@samp{altivec}, to use AltiVec registers; and @samp{spe} to use SPE +registers. By default, @value{GDBN} selects the calling convention +based on the selected architecture and the provided executable file. + @kindex target dink32 @item target dink32 @var{dev} DINK32 ROM monitor. @@ -14955,7 +14973,7 @@ SDS monitor, running on a PowerPC board @cindex SDS protocol The following commands specific to the SDS protocol are supported -by@value{GDBN}: +by @value{GDBN}: @table @code @item set sdstimeout @var{nsec} Index: testsuite/gdb.arch/altivec-abi.exp =================================================================== RCS file: /scratch/gcc/repos/src/src/gdb/testsuite/gdb.arch/altivec-abi.exp,v retrieving revision 1.12 diff -u -p -r1.12 altivec-abi.exp --- testsuite/gdb.arch/altivec-abi.exp 21 Oct 2007 12:28:00 -0000 1.12 +++ testsuite/gdb.arch/altivec-abi.exp 30 Oct 2007 19:07:28 -0000 @@ -13,9 +13,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -# Please email any bugs, comments, and/or additions to this file to: -# bug-gdb@prep.ai.mit.edu -# # Tests for Powerpc AltiVec ABI @@ -28,9 +25,6 @@ if $tracelevel then { # This file uses altivec-abi.c for input. # -set prms_id 0 -set bug_id 0 - if {![istarget "powerpc*"] || [skip_altivec_tests]} then { verbose "Skipping altivec abi tests." verbose -log "Skipping altivec abi tests." @@ -41,88 +35,124 @@ set testfile "altivec-abi" set binfile ${objdir}/${subdir}/${testfile} set srcfile ${testfile}.c -set compile_flags {debug nowarnings} if [get_compiler_info $binfile] { warning "get_compiler failed" return -1 } +proc altivec_abi_tests { extra_flags force_abi } { + global testfile binfile srcfile srcdir subdir + global gdb_prompt + + set compile_flags "debug nowarnings $extra_flags" + + if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable $compile_flags] != "" } { + untested altivec-abi.exp + return -1 + } + + if { "$force_abi" == "auto" } { + # If the toolchain does not record attributes, skip auto-ABI tests. + set readelf_program [transform readelf] + set result [catch "exec $readelf_program -A $binfile" output] + + if {$result == 0 && ![regexp Tag_GNU_Power_ABI_Vector $output]} { + untested "ABI not marked" + return + } + } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + # Run to `main' where we begin our tests. + if ![runto_main] then { + untested altivec-abi.exp + return -1 + } + + gdb_test "set powerpc vector-abi $force_abi" + + gdb_test "b marker" "Breakpoint 2 at.*file.*altivec-abi.c, line \[0-9\]+." "break marker" + gdb_test "continue" "Breakpoint 2.*marker.*altivec-abi.c.*" "continue to marker" + gdb_test "finish" "Run till exit from .0.*marker.*at.*altivec-abi.c.*main \\(\\) at.*altivec-abi.c.*result = vec_func \\(vshort,.*goes in v2.*" "back to main (1)" + + # now all the arguments of vec_fun are initialized + + set pattern "vec_func .vshort_f=.111, 222, 333, 444, 555, 666, 777, 888., vushort_f=.100, 200, 300, 400, 500, 600, 700, 800., vint_f=.-10, -20, -30, -40., vuint_f=.1111, 2222, 3333, 4444., vchar_f=.abcdefghilmnopqr., vuchar_f=.ABCDEFGHILMNOPQR., vfloat_f=.1.25, 3.75, 5.5, 1.25., x_f=.1, 2, 3, 4, 5, 6, 7, 8., y_f=.12, 22, 32, 42., a_f=.vector of chars.., b_f=.5.5, 4.5, 3.75, 2.25., c_f=.1.25, 3.5, 5.5, 7.75., intv_on_stack_f=.12, 34, 56, 78.." + + set pattern1 $pattern + append pattern1 " at.*altivec-abi.c.*vint_res = vec_add.*vint_f, intv_on_stack_f.;" + + # Now let's call the function. This function has > 12 args, + # the last one will go on the stack. + set msg "call inferior function with vectors (1)" + gdb_test "p vec_func(vshort,vushort,vint,vuint,vchar,vuchar,vfloat,x,y,a,b,c,intv_on_stack)" \ + ".\[0-9\]+ = .2, 2, 2, 2." "call inferior function with vectors (1)" + + # Let's call the function again with dummy arguments. This is to clean + # up the contents of the vector registers before the next call. + gdb_test "p vec_func(vshort_d,vushort_d,vint_d,vuint_d,vchar_d,vuchar_d,vfloat_d,x_d,y_d,a_d,b_d,c_d,intv_on_stack_d)" \ + ".\[0-9\]+ = .0, 0, 0, 0." "call inferior function with vectors (2)" + + # Let's step into the function, to see if the args are printed correctly. + gdb_test "step" \ + $pattern1 \ + "step into vec_fun" + + set pattern2 $pattern + append pattern2 " at.*altivec-abi.c.*main.*result = vec_func .vshort,.*goes in v2.*Value returned is.*= .2, 2, 2, 2." + + # Let's see if the result is returned correctly. + gdb_test "finish" "Run till exit from .0.*$pattern2" \ + "vector value returned correctly" + + # can we print the args correctly for this function? + gdb_test "break struct_of_vector_func" "" "" + + set pattern "struct_of_vector_func .vector_struct=.vshort1 = .1, 2, 3, 4, 5, 6, 7, 8., vshort2 = .11, 12, 13, 14, 15, 16, 17, 18., vshort3 = .21, 22, 23, 24, 25, 26, 27, 28., vshort4 = .31, 32, 33, 34, 35, 36, 37, 38... at.*altivec-abi.c.*" + + gdb_test "continue" \ + "Breakpoint 3, $pattern.*vector_struct.vshort1 = vec_add .vector_struct.vshort1, vector_struct.vshort2.;" \ + "continue to struct_of_vector_func" + + gdb_test "finish" \ + "Run till exit from .0 $pattern\[ \r\n\]+main.*altivec-abi.c.*array_of_vector_func.*" \ + "back to main (2)" + + gdb_test "step" "" "step into array_of_vector_func" + gdb_test "p matrix\[0\]" ".*= .1, 2, 3, 4, 5, 6, 7, 8." "print first vector" + gdb_test "p matrix\[1\]" ".*= .11, 12, 13, 14, 15, 16, 17, 18." "print second vector" + gdb_test "p matrix\[2\]" ".*= .21, 22, 23, 24, 25, 26, 27, 28." "print third vector" + gdb_test "p matrix\[3\]" ".*= .31, 32, 33, 34, 35, 36, 37, 38." "print fourth vector" +} + if [test_compiler_info gcc*] { - set compile_flags "$compile_flags additional_flags=-maltivec additional_flags=-mabi=altivec" + set saved_prefix $pf_prefix + + set pf_prefix "${saved_prefix} default ABI, auto:" + altivec_abi_tests "additional_flags=-maltivec" "auto" + + # On GNU/Linux, we can mix -mabi=no-altivec and -mabi=altivec. + # So test some combinations. + if { [istarget "powerpc*-linux*"] } { + set binfile ${objdir}/${subdir}/${testfile}-ge-ge + set pf_prefix "${saved_prefix} generic ABI, forced:" + altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=no-altivec" "generic" + + set binfile ${objdir}/${subdir}/${testfile}-av-av + set pf_prefix "${saved_prefix} AltiVec ABI, forced:" + altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=altivec" "altivec" + + set binfile ${objdir}/${subdir}/${testfile}-av-auto + set pf_prefix "${saved_prefix} AltiVec ABI, auto:" + altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=altivec" "auto" + } } elseif [test_compiler_info xlc*] { - set compile_flags "$compile_flags additional_flags=-qaltivec" + altivec_abi_tests "additional_flags=-qaltivec" "auto" } else { warning "unknown compiler" return -1 } - -if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable $compile_flags] != "" } { - untested altivec-abi.exp - return -1 -} - -gdb_start -gdb_reinitialize_dir $srcdir/$subdir -gdb_load ${binfile} - -# -# Run to `main' where we begin our tests. -# - -if ![runto_main] then { - gdb_suppress_tests -} - -gdb_test "b marker" "Breakpoint 2 at.*file.*altivec-abi.c, line \[0-9\]+." "break marker" -gdb_test "continue" "Breakpoint 2.*marker.*altivec-abi.c.*" "continue to marker" -gdb_test "finish" "Run till exit from .0.*marker.*at.*altivec-abi.c.*main \\(\\) at.*altivec-abi.c.*result = vec_func \\(vshort,.*goes in v2.*" "back to main (1)" - -# now all the arguments of vec_fun are initialized - -set pattern "vec_func .vshort_f=.111, 222, 333, 444, 555, 666, 777, 888., vushort_f=.100, 200, 300, 400, 500, 600, 700, 800., vint_f=.-10, -20, -30, -40., vuint_f=.1111, 2222, 3333, 4444., vchar_f=.abcdefghilmnopqr., vuchar_f=.ABCDEFGHILMNOPQR., vfloat_f=.1.25, 3.75, 5.5, 1.25., x_f=.1, 2, 3, 4, 5, 6, 7, 8., y_f=.12, 22, 32, 42., a_f=.vector of chars.., b_f=.5.5, 4.5, 3.75, 2.25., c_f=.1.25, 3.5, 5.5, 7.75., intv_on_stack_f=.12, 34, 56, 78.." - -set pattern1 $pattern -append pattern1 " at.*altivec-abi.c.*vint_res = vec_add.*vint_f, intv_on_stack_f.;" - -# Now let's call the function. This function has > 12 args, -# the last one will go on the stack. -gdb_test "p vec_func(vshort,vushort,vint,vuint,vchar,vuchar,vfloat,x,y,a,b,c,intv_on_stack)" \ -".\[0-9\]+ = .2, 2, 2, 2." "call inferior function with vectors (1) " - -# Let's call the function again with dummy arguments. This is to clean -# up the contents of the vector registers before the next call. -gdb_test "p vec_func(vshort_d,vushort_d,vint_d,vuint_d,vchar_d,vuchar_d,vfloat_d,x_d,y_d,a_d,b_d,c_d,intv_on_stack_d)" \ -".\[0-9\]+ = .0, 0, 0, 0." "call inferior function with vectors (2) " - -# Let's step into the function, to see if the args are printed correctly. -gdb_test "step" \ - $pattern1 \ - "step into vec_fun" - -set pattern2 $pattern -append pattern2 " at.*altivec-abi.c.*main.*result = vec_func .vshort,.*goes in v2.*Value returned is.*= .2, 2, 2, 2." - -# Let's see if the result is returned correctly. -gdb_test "finish" \ - "Run till exit from .0.*$pattern2" \ - "vector value returned correctly" - -# can we print the args correctly for this function? -gdb_test "break struct_of_vector_func" "" "" - -set pattern "struct_of_vector_func .vector_struct=.vshort1 = .1, 2, 3, 4, 5, 6, 7, 8., vshort2 = .11, 12, 13, 14, 15, 16, 17, 18., vshort3 = .21, 22, 23, 24, 25, 26, 27, 28., vshort4 = .31, 32, 33, 34, 35, 36, 37, 38... at.*altivec-abi.c.*" - -gdb_test "continue" \ - "Breakpoint 3, $pattern.*vector_struct.vshort1 = vec_add .vector_struct.vshort1, vector_struct.vshort2.;" \ - "continue to struct_of_vector_func" - -gdb_test "finish" \ - "Run till exit from .0 $pattern\[ \r\n\]+main.*altivec-abi.c.*array_of_vector_func.*" \ - "back to main (2)" - -gdb_test "step" "" "step into array_of_vector_func" -gdb_test "p matrix\[0\]" ".*= .1, 2, 3, 4, 5, 6, 7, 8." "print first vector" -gdb_test "p matrix\[1\]" ".*= .11, 12, 13, 14, 15, 16, 17, 18." "print second vector" -gdb_test "p matrix\[2\]" ".*= .21, 22, 23, 24, 25, 26, 27, 28." "print third vector" -gdb_test "p matrix\[3\]" ".*= .31, 32, 33, 34, 35, 36, 37, 38." "print fourth vector" -