From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5312 invoked by alias); 18 Dec 2014 01:07:59 -0000 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 Received: (qmail 5145 invoked by uid 89); 18 Dec 2014 01:07:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 18 Dec 2014 01:07:54 +0000 Received: from svr-orw-fem-02x.mgc.mentorg.com ([147.34.96.206] helo=SVR-ORW-FEM-02.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1Y1PZG-0002lJ-TM from Yao_Qi@mentor.com ; Wed, 17 Dec 2014 17:07:50 -0800 Received: from GreenOnly (147.34.91.1) by svr-orw-fem-02.mgc.mentorg.com (147.34.96.168) with Microsoft SMTP Server id 14.3.181.6; Wed, 17 Dec 2014 17:07:50 -0800 From: Yao Qi To: Pedro Alves CC: Subject: Re: [PATCH 3/3] MIPS: Provide FPU info and decode FCSR in `info float' References: <1418798765-23198-1-git-send-email-yao@codesourcery.com> <1418798765-23198-4-git-send-email-yao@codesourcery.com> <5491609E.1080204@redhat.com> <87oar2sb5h.fsf@codesourcery.com> Date: Thu, 18 Dec 2014 01:07:00 -0000 In-Reply-To: <87oar2sb5h.fsf@codesourcery.com> (Yao Qi's message of "Wed, 17 Dec 2014 20:39:38 +0800") Message-ID: <87bnn1sr3b.fsf@codesourcery.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2014-12/txt/msg00509.txt.bz2 Yao Qi writes: > } elseif [istarget "mips*-*-*"] then { > - gdb_test "info float" "f0:.*flt:.*dbl:.*" "info float" > + gdb_test_multiple "info float" "info float" { > + -re "fpu type: none*" { > + pass "info float (without FPU)" > + } > + -re "fpu type:.*cause.*mask.*flags.*round.*flush.*" { > + pass "info float (with FPU)" > + } > + } The updated patch adds the "$gdb_prompt $" at the end of those patterns and restrict the restrict the patterns. --=20 Yao (=E9=BD=90=E5=B0=A7) Subject: [PATCH] MIPS: Provide FPU info and decode FCSR in `info float' This patch is the V2. V1 can be found in https://sourceware.org/ml/gdb-patches/2012-05/msg00938.html V2 is to address Joel's comment about keeping dumping floating point registers. Additionally, command 'info float' prints bits on nan2008 and abs2008. ------------------------------------------------------------------ The change below provides a MIPS-specific handler for the: (gdb) info float command. It provides information about the FPU type available (if any), the FPU register width, and decodes the CP1 Floating Point Control and Status Register (FCSR): (gdb) print /x $fsr $1 =3D 0xff83ffff (gdb) info float fpu type: double-precision reg size: 32 bits cond : 0 1 2 3 4 5 6 7 cause : inexact uflow oflow div0 inval unimp mask : inexact uflow oflow div0 inval flags : inexact uflow oflow div0 inval rounding: -inf flush : zero One point to note about CP1.FCSR are the non-standard Flush-to-Nearest and Flush-Override bits. They are not a part of the MIPS architecture and take two positions reserved for an implementation-dependent use in the architecture. They are present in all the FPU implementations made by MIPS Technologies since the spin-off from SGI. I haven't been able to track down a single other MIPS FPU implementation that would make any use of these bits and they are required to be hardwired to zero by the architecture specification if unimplemented. Therefore I think it makes sense to report them in the current way. GDB has no guaranteed access to the CP0 Processor Identification (PRId) register to validate this feature properly and the ID information stored in the CP1 Floating Point Implementation Register (FIR) is from my experience not reliable enough (there's no Company ID available there for once unlike in CP0.PRId and Processor ID is not guaranteed to be unique). As a side note we should probably dump CP1.FIR information as well, as there's useful stuff indicating some FPU features there. That's material for another change however. gdb/ 2014-12-17 Nigel Stephens Maciej W. Rozycki * mips-tdep.c (print_fpu_flags): New function. (mips_print_float_info): Likewise. (mips_gdbarch_init): Install mips_print_float_info as gdbarch print_float_info routine. gdb/testsuite/ 2014-12-17 Nigel Stephens Maciej W. Rozycki * gdb.base/float.exp: Handle the new output from "info float" on MIPS targets. diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index eb99910..60f43ac 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -73,6 +73,9 @@ static int micromips_insn_at_pc_has_delay_slot (struct gd= barch *gdbarch, static int mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr, int mustbe32); =20 +static void mips_print_float_info (struct gdbarch *, struct ui_file *, + struct frame_info *, const char *); + /* 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) @@ -6387,6 +6390,94 @@ mips_print_register (struct ui_file *file, struct fr= ame_info *frame, &opts, 0, file); } =20 +/* Print IEEE exception condition bits in FLAGS. */ + +static void +print_fpu_flags (struct ui_file *file, int flags) +{ + if (flags & (1 << 0)) + fputs_filtered (" inexact", file); + if (flags & (1 << 1)) + fputs_filtered (" uflow", file); + if (flags & (1 << 2)) + fputs_filtered (" oflow", file); + if (flags & (1 << 3)) + fputs_filtered (" div0", file); + if (flags & (1 << 4)) + fputs_filtered (" inval", file); + if (flags & (1 << 5)) + fputs_filtered (" unimp", file); + fputc_filtered ('\n', file); +} + +/* Print interesting information about the floating point processor + (if present) or emulator. */ + +static void +mips_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, const char *args) +{ + int fcsr =3D mips_regnum (gdbarch)->fp_control_status; + enum mips_fpu_type type =3D MIPS_FPU_TYPE (gdbarch); + ULONGEST fcs =3D 0; + int i; + + if (fcsr =3D=3D -1 || !read_frame_register_unsigned (frame, fcsr, &fcs)) + type =3D MIPS_FPU_NONE; + + fprintf_filtered (file, "fpu type: %s\n", + type =3D=3D MIPS_FPU_DOUBLE ? "double-precision" + : type =3D=3D MIPS_FPU_SINGLE ? "single-precision" + : "none / unused"); + + if (type =3D=3D MIPS_FPU_NONE) + return; + + fprintf_filtered (file, "reg size: %d bits\n", + register_size (gdbarch, mips_regnum (gdbarch)->fp0) * 8); + + fputs_filtered ("cond :", file); + if (fcs & (1 << 23)) + fputs_filtered (" 0", file); + for (i =3D 1; i <=3D 7; i++) + if (fcs & (1 << (24 + i))) + fprintf_filtered (file, " %d", i); + fputc_filtered ('\n', file); + + fputs_filtered ("cause :", file); + print_fpu_flags (file, (fcs >> 12) & 0x3f); + fputs ("mask :", stdout); + print_fpu_flags (file, (fcs >> 7) & 0x1f); + fputs ("flags :", stdout); + print_fpu_flags (file, (fcs >> 2) & 0x1f); + + fputs_filtered ("rounding: ", file); + switch (fcs & 3) + { + case 0: fputs_filtered ("nearest\n", file); break; + case 1: fputs_filtered ("zero\n", file); break; + case 2: fputs_filtered ("+inf\n", file); break; + case 3: fputs_filtered ("-inf\n", file); break; + } + + fputs_filtered ("flush :", file); + if (fcs & (1 << 21)) + fputs_filtered (" nearest", file); + if (fcs & (1 << 22)) + fputs_filtered (" override", file); + if (fcs & (1 << 24)) + fputs_filtered (" zero", file); + if ((fcs & (0xb << 21)) =3D=3D 0) + fputs_filtered (" no", file); + fputc_filtered ('\n', file); + + fprintf_filtered (file, "nan2008 : %s\n", fcs & (1 << 18) ? "yes" : "no"= ); + fprintf_filtered (file, "abs2008 : %s\n", fcs & (1 << 19) ? "yes" : "no"= ); + fputc_filtered ('\n', file); + + default_print_float_info (gdbarch, file, frame, args); +} + /* Replacement for generic do_registers_info. Print regs in pretty columns. */ =20 @@ -8737,6 +8828,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct g= dbarch_list *arches) set_gdbarch_push_dummy_code (gdbarch, mips_push_dummy_code); set_gdbarch_frame_align (gdbarch, mips_frame_align); =20 + set_gdbarch_print_float_info (gdbarch, mips_print_float_info); + set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p); set_gdbarch_register_to_value (gdbarch, mips_register_to_value); set_gdbarch_value_to_register (gdbarch, mips_value_to_register); diff --git a/gdb/testsuite/gdb.base/float.exp b/gdb/testsuite/gdb.base/floa= t.exp index 5da9630..fbbd682 100644 --- a/gdb/testsuite/gdb.base/float.exp +++ b/gdb/testsuite/gdb.base/float.exp @@ -68,7 +68,14 @@ if { [istarget "aarch64*-*-*"] } then { } } } elseif [istarget "mips*-*-*"] then { - gdb_test "info float" "f0:.*flt:.*dbl:.*" "info float" + gdb_test_multiple "info float" "info float" { + -re "fpu type: none / unused\r\n$gdb_prompt $" { + pass "info float (without FPU)" + } + -re "fpu type:.*cause.*mask.*flags.*round.*flush.*f0:.*flt:.*dbl:.*$gdb_p= rompt $" { + pass "info float (with FPU)" + } + } } elseif [istarget "powerpc*-*-*"] then { gdb_test_multiple "info float" "info_float" { -re "f0.*f1.*f31.*fpscr.*$gdb_prompt $" {