From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31918 invoked by alias); 26 Nov 2002 19:41:47 -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 31911 invoked from network); 26 Nov 2002 19:41:46 -0000 Received: from unknown (HELO localhost.localdomain) (81.6.245.17) by sources.redhat.com with SMTP; 26 Nov 2002 19:41:46 -0000 Received: (from rsandifo@localhost) by localhost.localdomain (8.11.6/8.11.6) id gAQJnpx02339; Tue, 26 Nov 2002 19:49:51 GMT X-Authentication-Warning: localhost.localdomain: rsandifo set sender to rsandifo@redhat.com using -f To: gdb-patches@sources.redhat.com Subject: Simulation of MIPS recip and rsqrt instructions From: Richard Sandiford Date: Tue, 26 Nov 2002 11:41:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-11/txt/msg00658.txt.bz2 The mips simulator uses sim_fpu_inv() as a reciprocal function but all it really does is negate the exponent. So we end up calculating 1 / (x*2^y) as x*2^-y. Test case: #include int main () { double d; float f; asm ("recip.s %0,%1" : "=f" (f) : "f" (20.0f)); printf ("%g\n", f); asm ("recip.d %0,%1" : "=f" (d) : "f" (10.0)); printf ("%g\n", d); asm ("rsqrt.s %0,%1" : "=f" (f) : "f" (0.01f)); printf ("%g\n", f); asm ("rsqrt.d %0,%1" : "=f" (d) : "f" (25.0)); printf ("%g\n", d); return 0; } The simulator says: 0.078125 0.15625 25.6 0.3125 while a vr5500 says: 0.05 0.1 10 0.2 Unfortunately, sim_fpu_inv isn't commented and cp1.c seems to be its only active user. Which should change? FWIW, the patch below fixes the test case. Please install if OK. Richard * cp1.c (inner_sqrt): Use sim_fpu_div instead of sim_fpu_inv. (fpu_inv): New function. (fp_recip): Use it. Index: sim/mips/cp1.c =================================================================== RCS file: /cvs/src/src/sim/mips/cp1.c,v retrieving revision 1.19 diff -u -d -p -F^[(a-zA-Z0-9_^#] -r1.19 cp1.c --- sim/mips/cp1.c 29 Jul 2002 23:17:10 -0000 1.19 +++ sim/mips/cp1.c 26 Nov 2002 19:13:24 -0000 @@ -900,7 +900,7 @@ inner_rsqrt(unsigned64 op1, status |= sim_fpu_sqrt (&ans, &wop1); status |= sim_fpu_round_32 (&ans, status, round); wop1 = ans; - op_status = sim_fpu_inv (&ans, &wop1); + op_status = sim_fpu_div (&ans, &sim_fpu_one, &wop1); op_status |= sim_fpu_round_32 (&ans, round, denorm); sim_fpu_to32 (&res, &ans); temp = res; @@ -914,7 +914,7 @@ inner_rsqrt(unsigned64 op1, status |= sim_fpu_sqrt (&ans, &wop1); status |= sim_fpu_round_64 (&ans, round, denorm); wop1 = ans; - op_status = sim_fpu_inv (&ans, &wop1); + op_status = sim_fpu_div (&ans, &sim_fpu_one, &wop1); op_status |= sim_fpu_round_64 (&ans, round, denorm); sim_fpu_to64 (&res, &ans); temp = res; @@ -1027,13 +1027,19 @@ fp_div(sim_cpu *cpu, return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt); } +static int +fpu_inv(sim_fpu *f, const sim_fpu *l) +{ + return sim_fpu_div (f, &sim_fpu_one, l); +} + unsigned64 fp_recip(sim_cpu *cpu, address_word cia, unsigned64 op, FP_formats fmt) { - return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt); + return fp_unary(cpu, cia, &fpu_inv, op, fmt); } unsigned64