From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15708 invoked by alias); 21 Nov 2007 17:40:44 -0000 Received: (qmail 15697 invoked by uid 22791); 21 Nov 2007 17:40:43 -0000 X-Spam-Check-By: sourceware.org Received: from dmz.mips-uk.com (HELO dmz.mips-uk.com) (194.74.144.194) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 21 Nov 2007 17:40:35 +0000 Received: from internal-mx1 ([192.168.192.240] helo=ukservices1.mips.com) by dmz.mips-uk.com with esmtp (Exim 3.35 #1 (Debian)) id 1IutYu-00031R-00; Wed, 21 Nov 2007 17:40:32 +0000 Received: from perivale.mips.com ([192.168.192.200]) by ukservices1.mips.com with esmtp (Exim 3.36 #1 (Debian)) id 1IutYq-0002QT-00; Wed, 21 Nov 2007 17:40:28 +0000 Received: from macro (helo=localhost) by perivale.mips.com with local-esmtp (Exim 4.63) (envelope-from ) id 1IutYq-0004at-LG; Wed, 21 Nov 2007 17:40:28 +0000 Date: Wed, 21 Nov 2007 17:40:00 -0000 From: "Maciej W. Rozycki" To: gdb-patches@sourceware.org cc: Nigel Stephens , David Ung , "Maciej W. Rozycki" Subject: mips-tdep.c: Unification of FPR size detection Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-MIPS-Technologies-UK-MailScanner: Found to be clean X-MIPS-Technologies-UK-MailScanner-From: macro@mips.com 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-11/txt/msg00400.txt.bz2 Hello, This is a set of changes to put code to determine the width of floating point registers into a single place. This is required for the support for MIPS32r2 64-bit FPRs to be added in a sensible way. I think the changes are mostly obvious. If not, then please enquire. Modifications to mips_o32_return_value(), mips_o32_push_dummy_call() and mips_register_type() change the semantics somewhat, but this is correct as for 64-bit processors in the compatibility mode FPRs are seen as 32-bit. The rest just shuffles code for consistency. One note: the mips2_fp_compat() function is meant to detect the size of floating point registers based on the setting of the cp0.Status.FR bit as applicable. However the function currently always returns 0. So I decided to include a change that ifdefs out the entire body. Enabling the body does not trigger any new regressions. I also added a note on a problem with the frame being NULL -- it may have to be dealt with in a better way once this code is reenabled. A possible way is by caching the value of cp0.Status.FR elsewhere. Tested for using the mipsisa32-sde-elf target, with the mips-sim-sde32/-EB, mips-sim-sde32/-EL, mips-sim-sde64/-mips64/-EB and mips-sim-sde64/-mips64/-EL boards with no regressions. 2007-11-21 Nigel Stephens David Ung Maciej W. Rozycki * mips-tdep.c (mips_float_register_p): New function. (mips_float_regsize): Likewise. (mips2_fp_compat): Handle a NULL pointer possibly passed. Ifdef out pointless code. (mips_convert_register_p): Use mips_float_register_p(). (mips_register_type): Likewise. Use mips_float_regsize() instead of mips_isa_regsize() for FP registers. (mips_o32_push_dummy_call): Use mips_float_regsize() instead of register_size() for FP registers. (mips_print_fp_register): Likewise. (mips_print_register): Likewise. (print_gp_register_row): Likewise. (mips_o32_return_value): Use mips_float_regsize() instead of hardcoding the expected width of FP registers. OK to apply? Maciej 14440-2.diff Index: binutils-quilt/src/gdb/mips-tdep.c =================================================================== --- binutils-quilt.orig/src/gdb/mips-tdep.c 2007-11-21 11:37:00.000000000 +0000 +++ binutils-quilt/src/gdb/mips-tdep.c 2007-11-21 11:47:35.000000000 +0000 @@ -62,6 +62,8 @@ static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum); +static int mips2_fp_compat (struct frame_info *frame); + /* A useful bit in the CP0 status register (MIPS_PS_REGNUM). */ /* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip. */ #define ST0_FR (1 << 26) @@ -211,6 +213,24 @@ return mips_regnum (gdbarch)->fp0 + 12; } +static int +mips_float_register_p (struct gdbarch *gdbarch, int regnum) +{ + return ((regnum % gdbarch_num_regs (gdbarch)) + >= mips_regnum (gdbarch)->fp0 + && (regnum % gdbarch_num_regs (gdbarch)) + < mips_regnum (gdbarch)->fp0 + 32); +} + +static int +mips_float_regsize (struct gdbarch *gdbarch, struct frame_info *frame) +{ + if (mips_isa_regsize (gdbarch) == 8 && ! mips2_fp_compat (frame)) + /* 64-bit ISA with 32-bit compatibility mode FPU. */ + return 8; + return 4; +} + #define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \ || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64) @@ -370,13 +390,21 @@ static int mips2_fp_compat (struct frame_info *frame) { - struct gdbarch *gdbarch = get_frame_arch (frame); +#if 0 + struct gdbarch *gdbarch; + + /* FIXME macro 2007-11-15: If we have no frame, then we cannot really + get it or gdbarch_data() will be called recursively (through + data->post_init()). Assume the native size. */ + if (frame == NULL) + return 0; + gdbarch = get_frame_arch (frame); + /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not meaningful. */ if (register_size (gdbarch, mips_regnum (gdbarch)->fp0) == 4) return 0; -#if 0 /* FIXME drow 2002-03-10: This is disabled until we can do it consistently, in all the places we deal with FP registers. PR gdb/413. */ /* Otherwise check the FR bit in the status register - it controls @@ -664,10 +692,7 @@ { return (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG && register_size (gdbarch, regnum) == 4 - && (regnum % gdbarch_num_regs (gdbarch)) - >= mips_regnum (gdbarch)->fp0 - && (regnum % gdbarch_num_regs (gdbarch)) - < mips_regnum (gdbarch)->fp0 + 32 + && mips_float_register_p (gdbarch, regnum) && TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8); } @@ -694,13 +719,11 @@ mips_register_type (struct gdbarch *gdbarch, int regnum) { gdb_assert (regnum >= 0 && regnum < 2 * gdbarch_num_regs (gdbarch)); - if ((regnum % gdbarch_num_regs (gdbarch)) >= mips_regnum (gdbarch)->fp0 - && (regnum % gdbarch_num_regs (gdbarch)) - < mips_regnum (gdbarch)->fp0 + 32) + if (mips_float_register_p (gdbarch, regnum)) { /* The floating-point registers raw, or cooked, always match mips_isa_regsize(), and also map 1:1, byte for byte. */ - if (mips_isa_regsize (gdbarch) == 4) + if (mips_float_regsize (gdbarch, NULL) == 4) return builtin_type_ieee_single; else return builtin_type_ieee_double; @@ -3512,7 +3535,7 @@ if (fp_register_arg_p (typecode, arg_type) && float_argreg <= MIPS_LAST_FP_ARG_REGNUM) { - if (register_size (gdbarch, float_argreg) < 8 && len == 8) + if (mips_float_regsize (gdbarch, NULL) < 8 && len == 8) { int low_offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 4 : 0; @@ -3721,7 +3744,8 @@ || TYPE_CODE (type) == TYPE_CODE_ARRAY) return RETURN_VALUE_STRUCT_CONVENTION; else if (TYPE_CODE (type) == TYPE_CODE_FLT - && TYPE_LENGTH (type) == 4 && tdep->mips_fpu_type != MIPS_FPU_NONE) + && TYPE_LENGTH (type) <= mips_float_regsize (gdbarch, NULL) + && tdep->mips_fpu_type != MIPS_FPU_NONE) { /* A single-precision floating-point value. It fits in the least significant part of FP0. */ @@ -4275,14 +4299,14 @@ double doub, flt1; /* doubles extracted from raw hex data */ int inv1, inv2; - raw_buffer = alloca (2 * register_size (gdbarch, mips_regnum (gdbarch)->fp0)); + raw_buffer = alloca (2 * mips_float_regsize (gdbarch, frame)); fprintf_filtered (file, "%s:", gdbarch_register_name (gdbarch, regnum)); fprintf_filtered (file, "%*s", 4 - (int) strlen (gdbarch_register_name (gdbarch, regnum)), ""); - if (register_size (gdbarch, regnum) == 4 || mips2_fp_compat (frame)) + if (mips_float_regsize (gdbarch, frame) == 4) { /* 4-byte registers: Print hex and floating. Also print even numbered registers as doubles. */ @@ -4346,7 +4370,7 @@ gdb_byte raw_buffer[MAX_REGISTER_SIZE]; int offset; - if (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT) + if (mips_float_register_p (gdbarch, regnum)) { mips_print_fp_register (file, frame, regnum); return; @@ -4417,8 +4441,7 @@ { if (*gdbarch_register_name (gdbarch, regnum) == '\0') continue; /* unused register */ - if (TYPE_CODE (register_type (gdbarch, regnum)) == - TYPE_CODE_FLT) + if (mips_float_register_p (gdbarch, regnum)) break; /* end the row: reached FP register */ /* Large registers are handled separately. */ if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch)) @@ -4457,8 +4480,7 @@ { if (*gdbarch_register_name (gdbarch, regnum) == '\0') continue; /* unused register */ - if (TYPE_CODE (register_type (gdbarch, regnum)) == - TYPE_CODE_FLT) + if (mips_float_register_p (gdbarch, regnum)) break; /* end row: reached FP register */ if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch)) break; /* End row: large register. */ @@ -4513,8 +4535,7 @@ while (regnum < gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch)) { - if (TYPE_CODE (register_type (gdbarch, regnum)) == - TYPE_CODE_FLT) + if (mips_float_register_p (gdbarch, regnum)) { if (all) /* true for "INFO ALL-REGISTERS" command */ regnum = print_fp_register_row (file, frame, regnum);