From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25598 invoked by alias); 31 Oct 2003 13:49:04 -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 25583 invoked from network); 31 Oct 2003 13:49:00 -0000 Received: from unknown (HELO smtp.uk.superh.com) (193.128.105.170) by sources.redhat.com with SMTP; 31 Oct 2003 13:49:00 -0000 Received: from linsvr3.uk.superh.com (linsvr3 [192.168.16.52]) by smtp.uk.superh.com (8.12.10/8.12.9) with ESMTP id h9VDcXn5024749; Fri, 31 Oct 2003 13:38:33 GMT Received: (from renneckej@localhost) by linsvr3.uk.superh.com (8.11.6/8.11.6) id h9VDmdW06515; Fri, 31 Oct 2003 13:48:39 GMT From: Joern Rennecke Message-Id: <200310311348.h9VDmdW06515@linsvr3.uk.superh.com> Subject: RFA: add fsrra and fsca instructions to SH simulator (resend) To: gdb-patches@sources.redhat.com Date: Fri, 31 Oct 2003 13:49:00 -0000 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.37 X-SW-Source: 2003-10/txt/msg00869.txt.bz2 2003-10-24 J"orn Rennecke * interp.c (fsca_s, fsrra_s): New functions. * gencode.c (tab): Add entries for fsca and fsrra. (expand_opcode): Allow variable length n / m fields. Index: gencode.c =================================================================== RCS file: /cvs/src/src/sim/sh/gencode.c,v retrieving revision 1.20 diff -p -r1.20 gencode.c *** gencode.c 11 Aug 2003 19:28:05 -0000 1.20 --- gencode.c 24 Oct 2003 20:00:47 -0000 *************** op tab[] = *** 449,454 **** --- 449,465 ---- }, /* sh4 */ + { "", "", "fsca", "1111nnn011111101", + "if (FPSCR_PR)", + " RAISE_EXCEPTION (SIGILL);", + "else", + " {", + " SET_FR (n, fsca_s (FPUL, &sin));", + " SET_FR (n+1, fsca_s (FPUL, &cos));", + " }", + }, + + /* sh4 */ { "", "", "fschg", "1111001111111101", "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);", }, *************** op tab[] = *** 458,463 **** --- 469,482 ---- "FP_UNARY(n, sqrt);", }, + /* sh4 */ + { "", "", "fsrra", "1111nnnn01111101", + "if (FPSCR_PR)", + " RAISE_EXCEPTION (SIGILL);", + "else", + " SET_FR (n, fsrra_s (FR (n)));", + }, + /* sh2e */ { "", "", "fsub ,", "1111nnnnmmmm0001", "FP_OP(n, -, m);", *************** expand_opcode (shift, val, i, s) *** 1979,1984 **** --- 1998,2005 ---- { int m, mv; + if (s[1] - '0' > 1U || !s[2] || ! s[3]) + expand_opcode (shift - 1, val + s[0] - '0', i, s + 1); val |= bton (s) << shift; if (s[2] == '0' || s[2] == '1') expand_opcode (shift - 4, val, i, s + 4); *************** expand_opcode (shift, val, i, s) *** 2003,2014 **** } case 'n': case 'm': ! for (j = 0; j < 16; j++) ! { ! expand_opcode (shift - 4, val | (j << shift), i, s + 4); ! ! } ! break; case 'M': /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */ for (j = 5; j < 16; j++) --- 2024,2040 ---- } case 'n': case 'm': ! { ! int digits = 1; ! while (s[digits] == s[0]) ! digits++; ! for (j = 0; j < (1 << digits); j++) ! { ! expand_opcode (shift - digits, val | (j << shift), i, ! s + digits); ! } ! break; ! } case 'M': /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */ for (j = 5; j < 16; j++) Index: interp.c =================================================================== RCS file: /cvs/src/src/sim/sh/interp.c,v retrieving revision 1.11 diff -p -r1.11 interp.c *** interp.c 15 Oct 2003 12:30:47 -0000 1.11 --- interp.c 24 Oct 2003 20:00:47 -0000 *************** macl (regs, memory, n, m) *** 1411,1416 **** --- 1411,1465 ---- MACH = mach; } + float + fsca_s (int in, double (*f) (double)) + { + double rad = ldexp ((in & 0xffff), -15) * 3.141592653589793238462643383; + double result = (*f) (rad); + double error, upper, lower, frac; + int exp; + + /* Search the value with the maximum error that is still within the + architectural spec. */ + error = ldexp (1., -21); + /* compensate for calculation inaccuracy by reducing error. */ + error = error - ldexp (1., -50); + upper = result + error; + frac = frexp (upper, &exp); + upper = ldexp (floor (ldexp (frac, 24)), exp - 24); + lower = result - error; + frac = frexp (lower, &exp); + lower = ldexp (ceil (ldexp (frac, 24)), exp - 24); + return abs (upper - result) >= abs (lower - result) ? upper : lower; + } + + float + fsrra_s (float in) + { + double result = 1. / sqrt (in); + int exp; + double frac, upper, lower, error, eps; + + /* refine result */ + result = result - (result * result * in - 1) * 0.5 * result; + /* Search the value with the maximum error that is still within the + architectural spec. */ + frac = frexp (result, &exp); + frac = ldexp (frac, 24); + error = 4.; /* 1 << 24-1-21 */ + /* use eps to compensate for possible 1 ulp error in our 'exact' result. */ + eps = ldexp (1., -29); + upper = floor (frac + error - eps); + if (upper > 16777216.) + upper = floor ((frac + error - eps) * 0.5) * 2.; + lower = ceil ((frac - error + eps) * 2) * .5; + if (lower > 8388608.) + lower = ceil (frac - error + eps); + upper = ldexp (upper, exp - 24); + lower = ldexp (lower, exp - 24); + return upper - result >= result - lower ? upper : lower; + } + static struct loop_bounds get_loop_bounds (rs, re, memory, mem_end, maskw, endianw) int rs, re;