From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9844 invoked by alias); 26 Apr 2002 20:45:21 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 9799 invoked from network); 26 Apr 2002 20:45:16 -0000 Received: from unknown (HELO cygnus.com) (205.180.83.203) by sources.redhat.com with SMTP; 26 Apr 2002 20:45:16 -0000 Received: from localhost.redhat.com (remus.sfbay.redhat.com [172.16.27.252]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id NAA10680 for ; Fri, 26 Apr 2002 13:45:15 -0700 (PDT) Received: by localhost.redhat.com (Postfix, from userid 469) id 4E0FA10A8C; Fri, 26 Apr 2002 16:44:44 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15561.48188.141526.557982@localhost.redhat.com> Date: Fri, 26 Apr 2002 13:45:00 -0000 To: gdb-patches@sources.redhat.com Subject: [RFA] Altivec ABI patches X-SW-Source: 2002-04/txt/msg01087.txt.bz2 As promised, this patch adds the last missing bits of Altivec support. It handles the new vector types for passing parameters and returning values. Elena 2002-04-26 Elena Zannoni * rs6000-tdep.c (rs6000_extract_return_value, rs6000_store_return_value): Handle returning vectors. (rs6000_gdbarch_init): Use ppc_sysv_abi_broken_use_struct_convention for native sysv cases. * ppc-linux-tdep.c (ppc_sysv_abi_broken_use_struct_convention): New function. (ppc_sysv_abi_use_struct_convention): Deal with functions returning vectors. (ppc_sysv_abi_push_arguments): Handle vector parameters. * ppc-tdep.h (ppc_sysv_abi_broken_use_struct_convention): Export. Index: rs6000-tdep.c =================================================================== RCS file: /cvs/uberbaum/gdb/rs6000-tdep.c,v retrieving revision 1.60 diff -u -p -r1.60 rs6000-tdep.c --- rs6000-tdep.c 26 Apr 2002 04:31:47 -0000 1.60 +++ rs6000-tdep.c 26 Apr 2002 20:34:10 -0000 @@ -1144,6 +1144,7 @@ static void rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf) { int offset = 0; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); if (TYPE_CODE (valtype) == TYPE_CODE_FLT) { @@ -1165,6 +1166,13 @@ rs6000_extract_return_value (struct type memcpy (valbuf, &ff, sizeof (float)); } } + else if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY + && TYPE_LENGTH (valtype) == 16 + && TYPE_VECTOR (valtype)) + { + memcpy (valbuf, regbuf + REGISTER_BYTE (tdep->ppc_vr0_regnum + 2), + TYPE_LENGTH (valtype)); + } else { /* return value is copied starting from r3. */ @@ -1909,6 +1917,8 @@ rs6000_store_struct_return (CORE_ADDR ad static void rs6000_store_return_value (struct type *type, char *valbuf) { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + if (TYPE_CODE (type) == TYPE_CODE_FLT) /* Floating point values are returned starting from FPR1 and up. @@ -1917,6 +1927,13 @@ rs6000_store_return_value (struct type * write_register_bytes (REGISTER_BYTE (FP0_REGNUM + 1), valbuf, TYPE_LENGTH (type)); + else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + if (TYPE_LENGTH (type) == 16 + && TYPE_VECTOR (type)) + write_register_bytes (REGISTER_BYTE (tdep->ppc_vr0_regnum + 2), + valbuf, TYPE_LENGTH (type)); + } else /* Everything else is returned in GPR3 and up. */ write_register_bytes (REGISTER_BYTE (gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3), @@ -2706,7 +2723,7 @@ rs6000_gdbarch_init (struct gdbarch_info || osabi == ELFOSABI_NETBSD || osabi == ELFOSABI_FREEBSD) set_gdbarch_use_struct_convention (gdbarch, - generic_use_struct_convention); + ppc_sysv_abi_broken_use_struct_convention); else set_gdbarch_use_struct_convention (gdbarch, ppc_sysv_abi_use_struct_convention); Index: ppc-linux-tdep.c =================================================================== RCS file: /cvs/uberbaum/gdb/ppc-linux-tdep.c,v retrieving revision 1.16 diff -u -p -r1.16 ppc-linux-tdep.c --- ppc-linux-tdep.c 24 Apr 2002 16:28:16 -0000 1.16 +++ ppc-linux-tdep.c 26 Apr 2002 20:34:32 -0000 @@ -415,11 +415,29 @@ ppc_linux_frame_chain (struct frame_info it may be used generically by ports which use either the SysV ABI or the EABI */ +/* Until November 2001, gcc was not complying to the SYSV ABI for + returning structures less than or equal to 8 bytes in size. It was + returning everything in memory. When this was corrected, it wasn't + fixed for native platforms. */ +int +ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type) +{ + if (TYPE_LENGTH (value_type) == 16 + && TYPE_VECTOR (value_type)) + return 0; + + return generic_use_struct_convention (gcc_p, value_type); +} + /* Structures 8 bytes or less long are returned in the r3 & r4 registers, according to the SYSV ABI. */ int ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type) { + if (TYPE_LENGTH (value_type) == 16 + && TYPE_VECTOR (value_type)) + return 0; + return (TYPE_LENGTH (value_type) > 8); } @@ -445,7 +463,12 @@ ppc_sysv_abi_push_arguments (int nargs, int struct_return, CORE_ADDR struct_addr) { int argno; - int greg, freg; + /* Next available general register for non-float, non-vector arguments. */ + int greg; + /* Next available floating point register for float arguments. */ + int freg; + /* Next available vector register for vector arguments. */ + int vreg; int argstkspace; int structstkspace; int argoffset; @@ -458,6 +481,7 @@ ppc_sysv_abi_push_arguments (int nargs, greg = struct_return ? 4 : 3; freg = 1; + vreg = 2; argstkspace = 0; structstkspace = 0; @@ -500,21 +524,38 @@ ppc_sysv_abi_push_arguments (int nargs, greg += 2; } } - else - { + else if (!TYPE_VECTOR (type)) + { if (len > 4 || TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION) { /* Rounding to the nearest multiple of 8 may not be necessary, - but it is safe. Particularly since we don't know the - field types of the structure */ + but it is safe. Particularly since we don't know the + field types of the structure */ structstkspace += round2 (len, 8); } if (greg <= 10) greg++; else argstkspace += 4; + } + else + { + if (len == 16 + && TYPE_CODE (type) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type)) + { + if (vreg <= 13) + vreg++; + else + { + /* Vector arguments must be aligned to 16 bytes on + the stack. */ + argstkspace += round2 (argstkspace, 16); + argstkspace += 16; + } + } } } @@ -540,6 +581,7 @@ ppc_sysv_abi_push_arguments (int nargs, structoffset = argoffset + argstkspace; freg = 1; greg = 3; + vreg = 2; /* Fill in r3 with the return structure, if any */ if (struct_return) { @@ -599,7 +641,7 @@ ppc_sysv_abi_push_arguments (int nargs, greg += 2; } } - else + else if (!TYPE_VECTOR (type)) { char val_buf[4]; if (len > 4 @@ -627,6 +669,32 @@ ppc_sysv_abi_push_arguments (int nargs, argoffset += 4; } } + else + { + if (len == 16 + && TYPE_CODE (type) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type)) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + char *v_val_buf = alloca (16); + memset (v_val_buf, 0, 16); + memcpy (v_val_buf, VALUE_CONTENTS (arg), len); + if (vreg <= 13) + { + *(int *) ®isters[REGISTER_BYTE (tdep->ppc_vr0_regnum + + vreg)] = 0; + memcpy (®isters[REGISTER_BYTE (tdep->ppc_vr0_regnum + + vreg)], + v_val_buf, 16); + vreg++; + } + else + { + write_memory (sp + argoffset, v_val_buf, 16); + argoffset += 16; + } + } + } } target_store_registers (-1); Index: ppc-tdep.h =================================================================== RCS file: /cvs/uberbaum/gdb/ppc-tdep.h,v retrieving revision 1.9 diff -u -p -r1.9 ppc-tdep.h --- ppc-tdep.h 12 Apr 2002 19:48:36 -0000 1.9 +++ ppc-tdep.h 26 Apr 2002 20:34:41 -0000 @@ -32,6 +32,7 @@ int ppc_linux_frameless_function_invocat void ppc_linux_frame_init_saved_regs (struct frame_info *); CORE_ADDR ppc_linux_frame_chain (struct frame_info *); int ppc_sysv_abi_use_struct_convention (int, struct type *); +int ppc_sysv_abi_broken_use_struct_convention (int, struct type *); CORE_ADDR ppc_sysv_abi_push_arguments (int, struct value **, CORE_ADDR, int, CORE_ADDR); int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache);