From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3986 invoked by alias); 1 Mar 2013 17:50:27 -0000 Received: (qmail 3971 invoked by uid 22791); 1 Mar 2013 17:50:25 -0000 X-SWARE-Spam-Status: No, hits=-7.6 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_SPAMHAUS_DROP,KHOP_THREADED,NO_DNS_FOR_FROM,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,TW_CP,TW_EG X-Spam-Check-By: sourceware.org Received: from e8.ny.us.ibm.com (HELO e8.ny.us.ibm.com) (32.97.182.138) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 01 Mar 2013 17:50:19 +0000 Received: from /spool/local by e8.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 1 Mar 2013 12:50:18 -0500 Received: from d01dlp02.pok.ibm.com (9.56.250.167) by e8.ny.us.ibm.com (192.168.1.108) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 1 Mar 2013 12:50:15 -0500 Received: from d01relay01.pok.ibm.com (d01relay01.pok.ibm.com [9.56.227.233]) by d01dlp02.pok.ibm.com (Postfix) with ESMTP id C03AC6E8020 for ; Fri, 1 Mar 2013 12:50:12 -0500 (EST) Received: from d01av05.pok.ibm.com (d01av05.pok.ibm.com [9.56.224.195]) by d01relay01.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r21HoEgu191306 for ; Fri, 1 Mar 2013 12:50:14 -0500 Received: from d01av05.pok.ibm.com (loopback [127.0.0.1]) by d01av05.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id r21HoEZT001460 for ; Fri, 1 Mar 2013 12:50:14 -0500 Received: from igoo.rch.stglabs.ibm.com (igoo.rch.stglabs.ibm.com [9.5.12.222]) by d01av05.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id r21HoDiC001438; Fri, 1 Mar 2013 12:50:14 -0500 Received: by igoo.rch.stglabs.ibm.com (Postfix, from userid 1011) id EFEA2300943; Fri, 1 Mar 2013 11:08:11 -0600 (CST) From: Tiago =?iso-8859-1?Q?St=FCrmer?= Daitx To: Sergio Durigan Junior Cc: gdb-patches@sourceware.org In-Reply-To: Subject: Re: [PATCH] Fix complex argument handling in ppc64 dummy function call Message-Id: <20130301170811.EFEA2300943@igoo.rch.stglabs.ibm.com> Date: Fri, 01 Mar 2013 17:50:00 -0000 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 13030117-9360-0000-0000-000011231237 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: 2013-03/txt/msg00032.txt.bz2 Sergio, many thanks for the thorough review and the tips. There's no better way to get these rules to stick in my head. ^_^ Let me know if there is still something amiss. Cheers, Tiago gdb/ChangeLog 2013-03-01 Tiago Stürmer Daitx * ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function. (ppc64_sysv_abi_push_dummy_call): Handle complex arguments. diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c index 0ffeab9..cb9fe3b 100644 --- a/gdb/ppc-sysv-tdep.c +++ b/gdb/ppc-sysv-tdep.c @@ -1101,6 +1101,83 @@ convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr) return 1; } +/* Push a float in either registers, or in the stack. Using the ppc 64 bit + SysV ABI. + + This implements a dumbed down version of the ABI. It always writes + values to memory, GPR and FPR, even when not necessary. Doing this + greatly simplifies the logic. */ + +static void +ppc64_sysv_abi_push_float (struct gdbarch *gdbarch, struct regcache *regcache, + struct gdbarch_tdep *tdep, struct type *type, + const bfd_byte *val, int freg, int greg, + CORE_ADDR gparam) +{ + gdb_byte regval[MAX_REGISTER_SIZE]; + const gdb_byte *p; + + if (TYPE_LENGTH (type) <= 8) + { + /* Version 1.7 of the 64-bit PowerPC ELF ABI says: + + "Single precision floating point values are mapped to + the first word in a single doubleword." + + And version 1.9 says: + + "Single precision floating point values are mapped to + the second word in a single doubleword." + + GDB then writes single precision floating point values + at both words in a doubleword, to support both ABIs. */ + if (TYPE_LENGTH (type) == 4) + { + memcpy (regval, val, 4); + memcpy (regval + 4, val, 4); + p = regval; + } + else + p = val; + + /* Write value in the stack's parameter save area. */ + write_memory (gparam, p, 8); + + /* Floats and Doubles go in f1 .. f13. They also consume a left aligned + GREG, and can end up in memory. */ + if (freg <= 13) + { + struct type *regtype; + + regtype = register_type (gdbarch, tdep->ppc_fp0_regnum + freg); + convert_typed_floating (val, type, regval, regtype); + regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval); + } + if (greg <= 10) + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval); + } + else + { + /* IBM long double stored in two doublewords of the + parameter save area and corresponding registers. */ + if (!tdep->soft_float && freg <= 13) + { + regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, val); + if (freg <= 12) + regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg + 1, + val + 8); + } + if (greg <= 10) + { + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, val); + if (greg <= 9) + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg + 1, + val + 8); + } + write_memory (gparam, val, TYPE_LENGTH (type)); + } +} + /* Pass the arguments in either registers, or in the stack. Using the ppc 64 bit SysV ABI. @@ -1218,53 +1295,9 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8) { - /* Floats and Doubles go in f1 .. f13. They also - consume a left aligned GREG,, and can end up in - memory. */ if (write_pass) - { - gdb_byte regval[MAX_REGISTER_SIZE]; - const gdb_byte *p; - - /* Version 1.7 of the 64-bit PowerPC ELF ABI says: - - "Single precision floating point values are mapped to - the first word in a single doubleword." - - And version 1.9 says: - - "Single precision floating point values are mapped to - the second word in a single doubleword." - - GDB then writes single precision floating point values - at both words in a doubleword, to support both ABIs. */ - if (TYPE_LENGTH (type) == 4) - { - memcpy (regval, val, 4); - memcpy (regval + 4, val, 4); - p = regval; - } - else - p = val; - - /* Write value in the stack's parameter save area. */ - write_memory (gparam, p, 8); - - if (freg <= 13) - { - struct type *regtype - = register_type (gdbarch, tdep->ppc_fp0_regnum); - - convert_typed_floating (val, type, regval, regtype); - regcache_cooked_write (regcache, - tdep->ppc_fp0_regnum + freg, - regval); - } - if (greg <= 10) - regcache_cooked_write (regcache, - tdep->ppc_gp0_regnum + greg, - regval); - } + ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type, + val, freg, greg, gparam); freg++; greg++; @@ -1276,36 +1309,58 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) { - /* IBM long double stored in two doublewords of the - parameter save area and corresponding registers. */ if (write_pass) - { - if (!tdep->soft_float && freg <= 13) - { - regcache_cooked_write (regcache, - tdep->ppc_fp0_regnum + freg, - val); - if (freg <= 12) - regcache_cooked_write (regcache, - tdep->ppc_fp0_regnum + freg + 1, - val + 8); - } - if (greg <= 10) - { - regcache_cooked_write (regcache, - tdep->ppc_gp0_regnum + greg, - val); - if (greg <= 9) - regcache_cooked_write (regcache, - tdep->ppc_gp0_regnum + greg + 1, - val + 8); - } - write_memory (gparam, val, TYPE_LENGTH (type)); - } + ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type, + val, freg, greg, gparam); freg += 2; greg += 2; gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); } + else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX + && (TYPE_LENGTH (type) == 8 || TYPE_LENGTH (type) == 16)) + { + int i; + + for (i = 0; i < 2; i++) + { + if (write_pass) + { + struct type *target_type; + + target_type = check_typedef (TYPE_TARGET_TYPE (type)); + ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, + target_type, val + i * + TYPE_LENGTH (target_type), + freg, greg, gparam); + } + freg++; + greg++; + /* Always consume parameter stack space. */ + gparam = align_up(gparam + 8, tdep->wordsize); + } + } + else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX + && TYPE_LENGTH (type) == 32 + && (gdbarch_long_double_format (gdbarch) + == floatformats_ibm_long_double)) + { + int i; + for (i = 0; i < 2; i++) + { + struct type *target_type; + + target_type = check_typedef (TYPE_TARGET_TYPE (type)); + if (write_pass) + ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, + target_type, val + i * + TYPE_LENGTH (target_type), + freg, greg, gparam); + freg += 2; + greg += 2; + gparam = align_up (gparam + TYPE_LENGTH (target_type), + tdep->wordsize); + } + } else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && TYPE_LENGTH (type) <= 8) {