This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: add fsrra and fsca instructions to SH simulator (resend)


2003-10-24 J"orn Rennecke <joern.rennecke@superh.com>

	* 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.

Is it possible for this code to use the far more portable sim-fpu?


Andrew


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 <FREG_M>,<FREG_N>", "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;






Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]