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]

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.

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]