From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23256 invoked by alias); 4 Jun 2004 01:38:09 -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 23245 invoked from network); 4 Jun 2004 01:38:09 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org with SMTP; 4 Jun 2004 01:38:09 -0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i541c8i5011344 for ; Thu, 3 Jun 2004 21:38:08 -0400 Received: from potter.sfbay.redhat.com (potter.sfbay.redhat.com [172.16.27.15]) by int-mx2.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i541c7w26441; Thu, 3 Jun 2004 21:38:07 -0400 Received: from redhat.com (dhcp-172-16-25-160.sfbay.redhat.com [172.16.25.160]) by potter.sfbay.redhat.com (8.11.6/8.11.6) with ESMTP id i541c6P23813; Thu, 3 Jun 2004 18:38:06 -0700 Message-ID: <40BFD27E.6080209@redhat.com> Date: Fri, 04 Jun 2004 01:38:00 -0000 From: Michael Snyder Organization: Red Hat, Inc. User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.4.2) Gecko/20040301 MIME-Version: 1.0 To: Andrew Cagney , gdb-patches@sources.redhat.com, drow@false.org Subject: [RFC/RFA] MIPS extract_return_value Content-Type: multipart/mixed; boundary="------------000609010203020407000600" X-SW-Source: 2004-06/txt/msg00061.txt.bz2 This is a multi-part message in MIME format. --------------000609010203020407000600 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 768 Hey Andrew, Daniel, I encountered another problem with 32/64 bit mips. Don't know if this is the right way to fix it, but it illustrates it (and fixes several hundred failures). The problem is that extract_return_value and store_return_value both call return_value_location, but then one of them uses the raw register and the other uses the cooked register (which are not the same size). So the offset into the register cache, computed by return_value_location, has to be wrong for one of them. The simple-minded approach I've taken below is to add a parameter to return_value_location, telling it whether to use the raw or cooked registers. I've only tested it on one architecture (isa64 with gcc -mips32), so consider it more of a suggestion than a patch. --------------000609010203020407000600 Content-Type: text/plain; name="mips3" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mips3" Content-length: 5629 2004-06-04 Michael Snyder * mips-tdep.c (return_value_location): New parameter specifies whether to use raw registers (for store_return_value), or cooked registers (for extract_return_value). (mips_eabi_extract_return_value): Add new parameter for above. (mips_o64_extract_return_value): Ditto. (mips_eabi_store_return_value): Ditto. (mips_o64_store_return_value): Ditto. Index: mips-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/mips-tdep.c,v retrieving revision 1.294 diff -p -r1.294 mips-tdep.c *** mips-tdep.c 3 May 2004 22:20:18 -0000 1.294 --- mips-tdep.c 4 Jun 2004 01:26:40 -0000 *************** struct return_value_word *** 2638,2647 **** int buf_offset; }; static void return_value_location (struct type *valtype, struct return_value_word *hi, ! struct return_value_word *lo) { int len = TYPE_LENGTH (valtype); struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); --- 2638,2653 ---- int buf_offset; }; + enum { + STORE_RAW, + EXTRACT_COOKED + }; + static void return_value_location (struct type *valtype, struct return_value_word *hi, ! struct return_value_word *lo, ! int storextract) { int len = TYPE_LENGTH (valtype); struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); *************** return_value_location (struct type *valt *** 2663,2668 **** --- 2669,2679 ---- hi->reg_offset = lo->reg_offset; lo->reg = mips_regnum (current_gdbarch)->fp0 + 0; hi->reg = mips_regnum (current_gdbarch)->fp0 + 1; + if (storextract == EXTRACT_COOKED) + { + lo->reg += NUM_REGS; + hi->reg += NUM_REGS; + } lo->len = 4; hi->len = 4; } *************** return_value_location (struct type *valt *** 2676,2681 **** --- 2687,2694 ---- fp0) == 8 && len == 4) ? 4 : 0); lo->reg = mips_regnum (current_gdbarch)->fp0; + if (storextract == EXTRACT_COOKED) + lo->reg += NUM_REGS; lo->len = len; lo->buf_offset = 0; hi->len = 0; *************** return_value_location (struct type *valt *** 2688,2693 **** --- 2701,2709 ---- { /* Locate a result possibly spread across two registers. */ int regnum = 2; + if (storextract == EXTRACT_COOKED) + regnum += NUM_REGS; + lo->reg = regnum + 0; hi->reg = regnum + 1; if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG *************** mips_eabi_extract_return_value (struct t *** 3042,3056 **** { struct return_value_word lo; struct return_value_word hi; ! return_value_location (valtype, &hi, &lo); memcpy (valbuf + lo.buf_offset, ! regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) + lo.reg_offset, lo.len); if (hi.len > 0) memcpy (valbuf + hi.buf_offset, ! regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) + hi.reg_offset, hi.len); } --- 3058,3072 ---- { struct return_value_word lo; struct return_value_word hi; ! return_value_location (valtype, &hi, &lo, EXTRACT_COOKED); memcpy (valbuf + lo.buf_offset, ! regbuf + DEPRECATED_REGISTER_BYTE (lo.reg) + lo.reg_offset, lo.len); if (hi.len > 0) memcpy (valbuf + hi.buf_offset, ! regbuf + DEPRECATED_REGISTER_BYTE (hi.reg) + hi.reg_offset, hi.len); } *************** mips_eabi_store_return_value (struct typ *** 3063,3069 **** char raw_buffer[MAX_REGISTER_SIZE]; struct return_value_word lo; struct return_value_word hi; ! return_value_location (valtype, &hi, &lo); memset (raw_buffer, 0, sizeof (raw_buffer)); memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len); --- 3079,3085 ---- char raw_buffer[MAX_REGISTER_SIZE]; struct return_value_word lo; struct return_value_word hi; ! return_value_location (valtype, &hi, &lo, STORE_RAW); memset (raw_buffer, 0, sizeof (raw_buffer)); memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len); *************** mips_o64_extract_return_value (struct ty *** 4191,4205 **** { struct return_value_word lo; struct return_value_word hi; ! return_value_location (valtype, &hi, &lo); memcpy (valbuf + lo.buf_offset, ! regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) + lo.reg_offset, lo.len); if (hi.len > 0) memcpy (valbuf + hi.buf_offset, ! regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) + hi.reg_offset, hi.len); } --- 4207,4221 ---- { struct return_value_word lo; struct return_value_word hi; ! return_value_location (valtype, &hi, &lo, EXTRACT_COOKED); memcpy (valbuf + lo.buf_offset, ! regbuf + DEPRECATED_REGISTER_BYTE (lo.reg) + lo.reg_offset, lo.len); if (hi.len > 0) memcpy (valbuf + hi.buf_offset, ! regbuf + DEPRECATED_REGISTER_BYTE (hi.reg) + hi.reg_offset, hi.len); } *************** mips_o64_store_return_value (struct type *** 4209,4215 **** char raw_buffer[MAX_REGISTER_SIZE]; struct return_value_word lo; struct return_value_word hi; ! return_value_location (valtype, &hi, &lo); memset (raw_buffer, 0, sizeof (raw_buffer)); memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len); --- 4225,4231 ---- char raw_buffer[MAX_REGISTER_SIZE]; struct return_value_word lo; struct return_value_word hi; ! return_value_location (valtype, &hi, &lo, STORE_RAW); memset (raw_buffer, 0, sizeof (raw_buffer)); memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len); --------------000609010203020407000600--