/*> cp1.c <*/
/* MIPS Simulator FPU (CoProcessor 1) support.
   Copyright (C) 2002-2021 Free Software Foundation, Inc.
   Originally created by Cygnus Solutions.  Extensive modifications,
   including paired-single operation support and MIPS-3D support
   contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom
   Corporation (SiByte).

This file is part of GDB, the GNU debugger.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* XXX: The following notice should be removed as soon as is practical:  */
/* Floating Point Support for gdb MIPS simulators

   This file is part of the MIPS sim

		THIS SOFTWARE IS NOT COPYRIGHTED
   (by Cygnus.)

   Cygnus offers the following for use in the public domain.  Cygnus
   makes no warranty with regard to the software or it's performance
   and the user accepts the software "AS IS" with all faults.

   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

   (Originally, this code was in interp.c)
*/

/* This must come before any other includes.  */
#include "defs.h"

#include "sim-main.h"

#include <stdlib.h>

/* Within cp1.c we refer to sim_cpu directly.  */
#define CPU cpu
#define SD CPU_STATE(cpu)

/*-- FPU support routines ---------------------------------------------------*/

/* Numbers are held in normalized form. The SINGLE and DOUBLE binary
   formats conform to ANSI/IEEE Std 754-1985.

   SINGLE precision floating:
      seeeeeeeefffffffffffffffffffffff
        s =  1bit  = sign
        e =  8bits = exponent
        f = 23bits = fraction

   SINGLE precision fixed:
      siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
        s =  1bit  = sign
        i = 31bits = integer

   DOUBLE precision floating:
      seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
        s =  1bit  = sign
        e = 11bits = exponent
        f = 52bits = fraction

   DOUBLE precision fixed:
      siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
        s =  1bit  = sign
        i = 63bits = integer

   PAIRED SINGLE precision floating:
      seeeeeeeefffffffffffffffffffffffseeeeeeeefffffffffffffffffffffff
      |         upper                ||         lower                |
        s =  1bit  = sign
        e =  8bits = exponent
        f = 23bits = fraction
    Note: upper = [63..32], lower = [31..0]
 */

/* Extract packed single values:  */
#define FP_PS_upper(v) (((v) >> 32) & (unsigned)0xFFFFFFFF)
#define FP_PS_lower(v) ((v) & (unsigned)0xFFFFFFFF)
#define FP_PS_cat(u,l) (((unsigned64)((u) & (unsigned)0xFFFFFFFF) << 32) \
                        | (unsigned64)((l) & 0xFFFFFFFF))

/* Explicit QNaN values.  */
#define FPQNaN_SINGLE   (0x7FBFFFFF)
#define FPQNaN_WORD     (0x7FFFFFFF)
#define FPQNaN_DOUBLE   (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
#define FPQNaN_LONG     (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
#define FPQNaN_PS       (FP_PS_cat (FPQNaN_SINGLE, FPQNaN_SINGLE))

static const char *fpu_format_name (FP_formats fmt);
#ifdef DEBUG
static const char *fpu_rounding_mode_name (int rm);
#endif

uword64
value_fpr (sim_cpu *cpu,
	   address_word cia,
	   int fpr,
	   FP_formats fmt)
{
  uword64 value = 0;
  int err = 0;

  /* Treat unused register values, as fixed-point 64bit values.  */
  if (fmt == fmt_unknown)
    {
#if 1
      /* If request to read data as "unknown", then use the current
	 encoding:  */
      fmt = FPR_STATE[fpr];
#else
      fmt = fmt_long;
#endif
    }

  /* For values not yet accessed, set to the desired format.  */
  if (fmt < fmt_uninterpreted) 
    {
      if (FPR_STATE[fpr] == fmt_uninterpreted)
	{
	  FPR_STATE[fpr] = fmt;
#ifdef DEBUG
	  printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
		  fpu_format_name (fmt));
#endif /* DEBUG */
	}
      else if (fmt != FPR_STATE[fpr])
	{
	  sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
			  fpr, fpu_format_name (FPR_STATE[fpr]),
			  fpu_format_name (fmt), pr_addr (cia));
	  FPR_STATE[fpr] = fmt_unknown;
	}
    }

  if (FPR_STATE[fpr] == fmt_unknown)
    {
      /* Set QNaN value:  */
      switch (fmt)
	{
	case fmt_single:  value = FPQNaN_SINGLE;  break;
	case fmt_double:  value = FPQNaN_DOUBLE;  break;
	case fmt_word:    value = FPQNaN_WORD;    break;
	case fmt_long:    value = FPQNaN_LONG;    break;
	case fmt_ps:      value = FPQNaN_PS;      break;
	default:          err = -1;               break;
	}
    }
  else if (SizeFGR () == 64)
    {
      switch (fmt)
	{
	case fmt_uninterpreted_32:
	case fmt_single:
	case fmt_word:
	  value = (FGR[fpr] & 0xFFFFFFFF);
	  break;

	case fmt_uninterpreted_64:
	case fmt_uninterpreted:
	case fmt_double:
	case fmt_long:
	case fmt_ps:
	  value = FGR[fpr];
	  break;

	default:
	  err = -1;
	  break;
	}
    }
  else
    {
      switch (fmt)
	{
	case fmt_uninterpreted_32:
	case fmt_single:
	case fmt_word:
	  value = (FGR[fpr] & 0xFFFFFFFF);
	  break;

	case fmt_uninterpreted_64:
	case fmt_uninterpreted:
	case fmt_double:
	case fmt_long:
	  if ((fpr & 1) == 0)
	    {
	      /* Even register numbers only.  */
#ifdef DEBUG
	      printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
		      fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]),
		      fpr, pr_uword64 ((uword64) FGR[fpr]));
#endif
	      value = ((((uword64) FGR[fpr+1]) << 32)
		       | (FGR[fpr] & 0xFFFFFFFF));
	    }
	  else
	    {
	      SignalException (ReservedInstruction, 0);
	    }
	  break;

	case fmt_ps:
	  SignalException (ReservedInstruction, 0);
	  break;

	default:
	  err = -1;
	  break;
	}
    }

  if (err)
    SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");

#ifdef DEBUG
  printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
	  fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
	  SizeFGR ());
#endif /* DEBUG */

  return (value);
}

void
store_fpr (sim_cpu *cpu,
	   address_word cia,
	   int fpr,
	   FP_formats fmt,
	   uword64 value)
{
  int err = 0;

#ifdef DEBUG
  printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
	  fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
	  SizeFGR ());
#endif /* DEBUG */

  if (SizeFGR () == 64)
    {
      switch (fmt)
	{
	case fmt_uninterpreted_32:
	  fmt = fmt_uninterpreted;
	case fmt_single:
	case fmt_word:
	  if (STATE_VERBOSE_P (SD))
	    sim_io_eprintf (SD,
			    "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
			    pr_addr (cia));
	  FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
	  FPR_STATE[fpr] = fmt;
	  break;

	case fmt_uninterpreted_64:
	  fmt = fmt_uninterpreted;
	case fmt_uninterpreted:
	case fmt_double:
	case fmt_long:
	case fmt_ps:
	  FGR[fpr] = value;
	  FPR_STATE[fpr] = fmt;
	  break;

	default:
	  FPR_STATE[fpr] = fmt_unknown;
	  err = -1;
	  break;
	}
    }
  else
    {
      switch (fmt)
	{
	case fmt_uninterpreted_32:
	  fmt = fmt_uninterpreted;
	case fmt_single:
	case fmt_word:
	  FGR[fpr] = (value & 0xFFFFFFFF);
	  FPR_STATE[fpr] = fmt;
	  break;

	case fmt_uninterpreted_64:
	  fmt = fmt_uninterpreted;
	case fmt_uninterpreted:
	case fmt_double:
	case fmt_long:
	  if ((fpr & 1) == 0)
	    {
	      /* Even register numbers only.  */
	      FGR[fpr+1] = (value >> 32);
	      FGR[fpr] = (value & 0xFFFFFFFF);
	      FPR_STATE[fpr + 1] = fmt;
	      FPR_STATE[fpr] = fmt;
	    }
	  else
	    {
	      FPR_STATE[fpr] = fmt_unknown;
	      FPR_STATE[fpr ^ 1] = fmt_unknown;
	      SignalException (ReservedInstruction, 0);
	    }
	  break;

	case fmt_ps:
	  FPR_STATE[fpr] = fmt_unknown;
	  SignalException (ReservedInstruction, 0);
	  break;

	default:
	  FPR_STATE[fpr] = fmt_unknown;
	  err = -1;
	  break;
	}
    }

  if (err)
    SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");

#ifdef DEBUG
  printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
	  fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
#endif /* DEBUG */

  return;
}


/* CP1 control/status register access functions.  */

void
test_fcsr (sim_cpu *cpu,
	   address_word cia)
{
  unsigned int cause;

  cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;
  if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0
      || (cause & (1 << UO)))
    {
      SignalExceptionFPE();
    }
}

unsigned_word
value_fcr(sim_cpu *cpu,
	  address_word cia,
	  int fcr)
{
  unsigned32 value = 0;

  switch (fcr)
    {
    case 0:  /* FP Implementation and Revision Register.  */
      value = FCR0;
      break;
    case 25:  /* FP Condition Codes Register (derived from FCSR).  */
      value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;
      value = (value & 0x1) | (value >> 1);   /* Close FCC gap.  */
      break;
    case 26:  /* FP Exceptions Register (derived from FCSR).  */
      value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
      break;
    case 28:  /* FP Enables Register (derived from FCSR).  */
      value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
      if ((FCR31 & fcsr_FS) != 0)
	value |= fenr_FS;
      break;
    case 31:  /* FP Control/Status Register (FCSR).  */
      value = FCR31 & ~fcsr_ZERO_mask;
      break;
    }

  return (EXTEND32 (value));
}

void
store_fcr(sim_cpu *cpu,
	  address_word cia,
	  int fcr,
	  unsigned_word value)
{
  unsigned32 v;

  v = VL4_8(value);
  switch (fcr)
    {
    case 25:  /* FP Condition Codes Register (stored into FCSR).  */
      v = (v << 1) | (v & 0x1);             /* Adjust for FCC gap.  */
      FCR31 &= ~fcsr_FCC_mask;
      FCR31 |= ((v << fcsr_FCC_shift) & fcsr_FCC_mask);
      break;
    case 26:  /* FP Exceptions Register (stored into FCSR).  */
      FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
      FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
      test_fcsr(cpu, cia);
      break;
    case 28:  /* FP Enables Register (stored into FCSR).  */
      if ((v & fenr_FS) != 0)
	v |= fcsr_FS;
      else
	v &= ~fcsr_FS;
      FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);
      FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));
      test_fcsr(cpu, cia);
      break;
    case 31:  /* FP Control/Status Register (FCSR).  */
      FCR31 = v & ~fcsr_ZERO_mask;
      test_fcsr(cpu, cia);
      break;
    }
}

static void
update_fcsr (sim_cpu *cpu,
	     address_word cia,
	     sim_fpu_status status)
{
  FCSR &= ~fcsr_CAUSE_mask;

  if (status != 0)
    {
      unsigned int cause = 0;

      /* map between sim_fpu codes and MIPS FCSR */
      if (status & (sim_fpu_status_invalid_snan
		    | sim_fpu_status_invalid_isi
		    | sim_fpu_status_invalid_idi
		    | sim_fpu_status_invalid_zdz
		    | sim_fpu_status_invalid_imz
		    | sim_fpu_status_invalid_cmp
		    | sim_fpu_status_invalid_sqrt
		    | sim_fpu_status_invalid_cvi))
	cause |= (1 << IO);
      if (status & sim_fpu_status_invalid_div0)
	cause |= (1 << DZ);
      if (status & sim_fpu_status_overflow)
	cause |= (1 << OF);
      if (status & sim_fpu_status_underflow)
	cause |= (1 << UF);
      if (status & sim_fpu_status_inexact)
	cause |= (1 << IR);
#if 0 /* Not yet.  */
      /* Implicit clearing of other bits by unimplemented done by callers.  */
      if (status & sim_fpu_status_unimplemented)
	cause |= (1 << UO);
#endif

      FCSR |= (cause << fcsr_CAUSE_shift);
      test_fcsr (cpu, cia);
      FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);
    }
  return;
}

static sim_fpu_round
rounding_mode(int rm)
{
  sim_fpu_round round;

  switch (rm)
    {
    case FP_RM_NEAREST:
      /* Round result to nearest representable value. When two
	 representable values are equally near, round to the value
	 that has a least significant bit of zero (i.e. is even).  */
      round = sim_fpu_round_near;
      break;
    case FP_RM_TOZERO:
      /* Round result to the value closest to, and not greater in
	 magnitude than, the result.  */
      round = sim_fpu_round_zero;
      break;
    case FP_RM_TOPINF:
      /* Round result to the value closest to, and not less than,
	 the result.  */
      round = sim_fpu_round_up;
      break;
    case FP_RM_TOMINF:
      /* Round result to the value closest to, and not greater than,
	 the result.  */
      round = sim_fpu_round_down;
      break;
    default:
      round = 0;
      fprintf (stderr, "Bad switch\n");
      abort ();
    }
  return round;
}

/* When the FS bit is set, MIPS processors return zero for
   denormalized results and optionally replace denormalized inputs
   with zero.  When FS is clear, some implementation trap on input
   and/or output, while other perform the operation in hardware.  */
static sim_fpu_denorm
denorm_mode(sim_cpu *cpu)
{
  sim_fpu_denorm denorm;

  /* XXX: FIXME: Eventually should be CPU model dependent.  */
  if (GETFS())
    denorm = sim_fpu_denorm_zero;
  else
    denorm = 0;
  return denorm;
}


/* Comparison operations.  */

static sim_fpu_status
fp_test(unsigned64 op1,
	unsigned64 op2,
	FP_formats fmt,
	int abs,
	int cond,
	int *condition)
{
  sim_fpu wop1;
  sim_fpu wop2;
  sim_fpu_status status = 0;
  int  less, equal, unordered;

  /* The format type has already been checked:  */
  switch (fmt)
    {
    case fmt_single:
      {
	sim_fpu_32to (&wop1, op1);
	sim_fpu_32to (&wop2, op2);
	break;
      }
    case fmt_double:
      {
	sim_fpu_64to (&wop1, op1);
	sim_fpu_64to (&wop2, op2);
	break;
      }
    default:
      fprintf (stderr, "Bad switch\n");
      abort ();
    }

  if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
    {
      if ((cond & (1 << 3)) ||
	  sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
	status = sim_fpu_status_invalid_snan;
      less = 0;
      equal = 0;
      unordered = 1;
    }
  else
    {
      if (abs)
	{
	  status |= sim_fpu_abs (&wop1, &wop1);
	  status |= sim_fpu_abs (&wop2, &wop2);
	}
      equal = sim_fpu_is_eq (&wop1, &wop2);
      less = !equal && sim_fpu_is_lt (&wop1, &wop2);
      unordered = 0;
    }
  *condition = (((cond & (1 << 2)) && less)
		|| ((cond & (1 << 1)) && equal)
		|| ((cond & (1 << 0)) && unordered));
  return status;
}

void
fp_cmp(sim_cpu *cpu,
       address_word cia,
       unsigned64 op1,
       unsigned64 op2,
       FP_formats fmt,
       int abs,
       int cond,
       int cc)
{
  sim_fpu_status status = 0;

  /* The format type should already have been checked.  The FCSR is
     updated before the condition codes so that any exceptions will
     be signalled before the condition codes are changed.  */
  switch (fmt)
    {
    case fmt_single:
    case fmt_double:
      {
	int result;
	status = fp_test(op1, op2, fmt, abs, cond, &result);
	update_fcsr (cpu, cia, status);
	SETFCC (cc, result);
	break;
      }
    case fmt_ps:
      {
	int result0, result1;
	status  = fp_test(FP_PS_lower (op1), FP_PS_lower (op2), fmt_single,
			  abs, cond, &result0);
	status |= fp_test(FP_PS_upper (op1), FP_PS_upper (op2), fmt_single,
			  abs, cond, &result1);
	update_fcsr (cpu, cia, status);
	SETFCC (cc, result0);
	SETFCC (cc+1, result1);
	break;
      }
    default:
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }
}


/* Basic arithmetic operations.  */

static unsigned64
fp_unary(sim_cpu *cpu,
	 address_word cia,
	 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
	 unsigned64 op,
	 FP_formats fmt)
{
  sim_fpu wop;
  sim_fpu ans;
  sim_fpu_round round = rounding_mode (GETRM());
  sim_fpu_denorm denorm = denorm_mode (cpu);
  sim_fpu_status status = 0;
  unsigned64 result = 0;

  /* The format type has already been checked: */
  switch (fmt)
    {
    case fmt_single:
      {
	unsigned32 res;
	sim_fpu_32to (&wop, op);
	status |= (*sim_fpu_op) (&ans, &wop);
	status |= sim_fpu_round_32 (&ans, round, denorm);
	sim_fpu_to32 (&res, &ans);
	result = res;
	break;
      }
    case fmt_double:
      {
	unsigned64 res;
	sim_fpu_64to (&wop, op);
	status |= (*sim_fpu_op) (&ans, &wop);
	status |= sim_fpu_round_64 (&ans, round, denorm);
	sim_fpu_to64 (&res, &ans);
	result = res;
	break;
      }
    case fmt_ps:
      {
	int status_u = 0, status_l = 0;
	unsigned32 res_u, res_l;
	sim_fpu_32to (&wop, FP_PS_upper(op));
	status_u |= (*sim_fpu_op) (&ans, &wop);
	sim_fpu_to32 (&res_u, &ans);
	sim_fpu_32to (&wop, FP_PS_lower(op));
	status_l |= (*sim_fpu_op) (&ans, &wop);
	sim_fpu_to32 (&res_l, &ans);
	result = FP_PS_cat(res_u, res_l);
	status = status_u | status_l;
	break;
      }
    default:
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }

  update_fcsr (cpu, cia, status);
  return result;
}

static unsigned64
fp_binary(sim_cpu *cpu,
	  address_word cia,
	  int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
	  unsigned64 op1,
	  unsigned64 op2,
	  FP_formats fmt)
{
  sim_fpu wop1;
  sim_fpu wop2;
  sim_fpu ans;
  sim_fpu_round round = rounding_mode (GETRM());
  sim_fpu_denorm denorm = denorm_mode (cpu);
  sim_fpu_status status = 0;
  unsigned64 result = 0;

  /* The format type has already been checked: */
  switch (fmt)
    {
    case fmt_single:
      {
	unsigned32 res;
	sim_fpu_32to (&wop1, op1);
	sim_fpu_32to (&wop2, op2);
	status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
	status |= sim_fpu_round_32 (&ans, round, denorm);
	sim_fpu_to32 (&res, &ans);
	result = res;
	break;
      }
    case fmt_double:
      {
	unsigned64 res;
	sim_fpu_64to (&wop1, op1);
	sim_fpu_64to (&wop2, op2);
	status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
	status |= sim_fpu_round_64 (&ans, round, denorm);
	sim_fpu_to64 (&res, &ans);
	result = res;
	break;
      }
    case fmt_ps:
      {
	int status_u = 0, status_l = 0;
	unsigned32 res_u, res_l;
	sim_fpu_32to (&wop1, FP_PS_upper(op1));
	sim_fpu_32to (&wop2, FP_PS_upper(op2));
	status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
	sim_fpu_to32 (&res_u, &ans);
	sim_fpu_32to (&wop1, FP_PS_lower(op1));
	sim_fpu_32to (&wop2, FP_PS_lower(op2));
	status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
	sim_fpu_to32 (&res_l, &ans);
	result = FP_PS_cat(res_u, res_l);
	status = status_u | status_l;
	break;
      }
    default:
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }

  update_fcsr (cpu, cia, status);
  return result;
}

/* Common MAC code for single operands (.s or .d), defers setting FCSR.  */
static sim_fpu_status
inner_mac(int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
	  unsigned64 op1,
	  unsigned64 op2,
	  unsigned64 op3,
	  int scale,
	  int negate,
	  FP_formats fmt,
	  sim_fpu_round round,
	  sim_fpu_denorm denorm,
	  unsigned64 *result)
{
  sim_fpu wop1;
  sim_fpu wop2;
  sim_fpu ans;
  sim_fpu_status status = 0;
  sim_fpu_status op_status;
  unsigned64 temp = 0;

  switch (fmt)
    {
    case fmt_single:
      {
	unsigned32 res;
	sim_fpu_32to (&wop1, op1);
	sim_fpu_32to (&wop2, op2);
	status |= sim_fpu_mul (&ans, &wop1, &wop2);
	if (scale != 0 && sim_fpu_is_number (&ans))  /* number or denorm */
	  ans.normal_exp += scale;
	status |= sim_fpu_round_32 (&ans, round, denorm);
	wop1 = ans;
        op_status = 0;
	sim_fpu_32to (&wop2, op3);
	op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
	op_status |= sim_fpu_round_32 (&ans, round, denorm);
	status |= op_status;
	if (negate)
	  {
	    wop1 = ans;
	    op_status = sim_fpu_neg (&ans, &wop1);
	    op_status |= sim_fpu_round_32 (&ans, round, denorm);
	    status |= op_status;
	  }
	sim_fpu_to32 (&res, &ans);
	temp = res;
	break;
      }
    case fmt_double:
      {
	unsigned64 res;
	sim_fpu_64to (&wop1, op1);
	sim_fpu_64to (&wop2, op2);
	status |= sim_fpu_mul (&ans, &wop1, &wop2);
	if (scale != 0 && sim_fpu_is_number (&ans))  /* number or denorm */
	  ans.normal_exp += scale;
	status |= sim_fpu_round_64 (&ans, round, denorm);
	wop1 = ans;
        op_status = 0;
	sim_fpu_64to (&wop2, op3);
	op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
	op_status |= sim_fpu_round_64 (&ans, round, denorm);
	status |= op_status;
	if (negate)
	  {
	    wop1 = ans;
	    op_status = sim_fpu_neg (&ans, &wop1);
	    op_status |= sim_fpu_round_64 (&ans, round, denorm);
	    status |= op_status;
	  }
	sim_fpu_to64 (&res, &ans);
	temp = res;
	break;
      }
    default:
      fprintf (stderr, "Bad switch\n");
      abort ();
    }
  *result = temp;
  return status;
}

/* Common implementation of madd, nmadd, msub, nmsub that does
   intermediate rounding per spec.  Also used for recip2 and rsqrt2,
   which are transformed into equivalent nmsub operations.  The scale
   argument is an adjustment to the exponent of the intermediate
   product op1*op2.  It is currently non-zero for rsqrt2 (-1), which
   requires an effective division by 2. */
static unsigned64
fp_mac(sim_cpu *cpu,
       address_word cia,
       int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
       unsigned64 op1,
       unsigned64 op2,
       unsigned64 op3,
       int scale,
       int negate,
       FP_formats fmt)
{
  sim_fpu_round round = rounding_mode (GETRM());
  sim_fpu_denorm denorm = denorm_mode (cpu);
  sim_fpu_status status = 0;
  unsigned64 result = 0;

  /* The format type has already been checked: */
  switch (fmt)
    {
    case fmt_single:
    case fmt_double:
      status = inner_mac(sim_fpu_op, op1, op2, op3, scale,
			 negate, fmt, round, denorm, &result);
      break;
    case fmt_ps:
      {
	int status_u, status_l;
	unsigned64 result_u, result_l;
	status_u = inner_mac(sim_fpu_op, FP_PS_upper(op1), FP_PS_upper(op2),
			     FP_PS_upper(op3), scale, negate, fmt_single,
			     round, denorm, &result_u);
	status_l = inner_mac(sim_fpu_op, FP_PS_lower(op1), FP_PS_lower(op2),
			     FP_PS_lower(op3), scale, negate, fmt_single,
			     round, denorm, &result_l);
	result = FP_PS_cat(result_u, result_l);
	status = status_u | status_l;
	break;
      }
    default:
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }

  update_fcsr (cpu, cia, status);
  return result;
}

/* Common rsqrt code for single operands (.s or .d), intermediate rounding.  */
static sim_fpu_status
inner_rsqrt(unsigned64 op1,
	    FP_formats fmt,
	    sim_fpu_round round,
	    sim_fpu_denorm denorm,
	    unsigned64 *result)
{
  sim_fpu wop1;
  sim_fpu ans;
  sim_fpu_status status = 0;
  sim_fpu_status op_status;
  unsigned64 temp = 0;

  switch (fmt)
    {
    case fmt_single:
      {
	unsigned32 res;
	sim_fpu_32to (&wop1, 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_round_32 (&ans, round, denorm);
	sim_fpu_to32 (&res, &ans);
	temp = res;
	status |= op_status;
	break;
      }
    case fmt_double:
      {
	unsigned64 res;
	sim_fpu_64to (&wop1, 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_round_64 (&ans, round, denorm);
	sim_fpu_to64 (&res, &ans);
	temp = res;
	status |= op_status;
	break;
      }
    default:
      fprintf (stderr, "Bad switch\n");
      abort ();
    }
  *result = temp;
  return status;
}

static unsigned64
fp_inv_sqrt(sim_cpu *cpu,
	    address_word cia,
	    unsigned64 op1,
	    FP_formats fmt)
{
  sim_fpu_round round = rounding_mode (GETRM());
  sim_fpu_round denorm = denorm_mode (cpu);
  sim_fpu_status status = 0;
  unsigned64 result = 0;

  /* The format type has already been checked: */
  switch (fmt)
    {
    case fmt_single:
    case fmt_double:
      status = inner_rsqrt (op1, fmt, round, denorm, &result);
      break;
    case fmt_ps:
      {
	int status_u, status_l;
	unsigned64 result_u, result_l;
	status_u = inner_rsqrt (FP_PS_upper(op1), fmt_single, round, denorm,
				&result_u);
	status_l = inner_rsqrt (FP_PS_lower(op1), fmt_single, round, denorm,
				&result_l);
	result = FP_PS_cat(result_u, result_l);
	status = status_u | status_l;
	break;
      }
    default:
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }

  update_fcsr (cpu, cia, status);
  return result;
}


unsigned64
fp_abs(sim_cpu *cpu,
       address_word cia,
       unsigned64 op,
       FP_formats fmt)
{
  return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
}

unsigned64
fp_neg(sim_cpu *cpu,
       address_word cia,
       unsigned64 op,
       FP_formats fmt)
{
  return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
}

unsigned64
fp_add(sim_cpu *cpu,
       address_word cia,
       unsigned64 op1,
       unsigned64 op2,
       FP_formats fmt)
{
  return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
}

unsigned64
fp_sub(sim_cpu *cpu,
       address_word cia,
       unsigned64 op1,
       unsigned64 op2,
       FP_formats fmt)
{
  return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
}

unsigned64
fp_mul(sim_cpu *cpu,
       address_word cia,
       unsigned64 op1,
       unsigned64 op2,
       FP_formats fmt)
{
  return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
}

unsigned64
fp_div(sim_cpu *cpu,
       address_word cia,
       unsigned64 op1,
       unsigned64 op2,
       FP_formats fmt)
{
  return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
}

unsigned64
fp_recip(sim_cpu *cpu,
         address_word cia,
         unsigned64 op,
         FP_formats fmt)
{
  return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
}

unsigned64
fp_sqrt(sim_cpu *cpu,
        address_word cia,
        unsigned64 op,
        FP_formats fmt)
{
  return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
}

unsigned64
fp_rsqrt(sim_cpu *cpu,
         address_word cia,
         unsigned64 op,
         FP_formats fmt)
{
  return fp_inv_sqrt(cpu, cia, op, fmt);
}

unsigned64
fp_madd(sim_cpu *cpu,
        address_word cia,
        unsigned64 op1,
        unsigned64 op2,
        unsigned64 op3,
        FP_formats fmt)
{
  return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 0, fmt);
}

unsigned64
fp_msub(sim_cpu *cpu,
        address_word cia,
        unsigned64 op1,
        unsigned64 op2,
        unsigned64 op3,
        FP_formats fmt)
{
  return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 0, fmt);
}

unsigned64
fp_nmadd(sim_cpu *cpu,
         address_word cia,
         unsigned64 op1,
         unsigned64 op2,
         unsigned64 op3,
         FP_formats fmt)
{
  return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 1, fmt);
}

unsigned64
fp_nmsub(sim_cpu *cpu,
         address_word cia,
         unsigned64 op1,
         unsigned64 op2,
         unsigned64 op3,
         FP_formats fmt)
{
  return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 1, fmt);
}


/* MIPS-3D ASE operations.  */

/* Variant of fp_binary for *r.ps MIPS-3D operations. */
static unsigned64
fp_binary_r(sim_cpu *cpu,
	    address_word cia,
	    int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
	    unsigned64 op1,
	    unsigned64 op2) 
{
  sim_fpu wop1;
  sim_fpu wop2;
  sim_fpu ans;
  sim_fpu_round round = rounding_mode (GETRM ());
  sim_fpu_denorm denorm = denorm_mode (cpu);
  sim_fpu_status status_u, status_l;
  unsigned64 result;
  unsigned32 res_u, res_l;

  /* The format must be fmt_ps.  */
  status_u = 0;
  sim_fpu_32to (&wop1, FP_PS_upper (op1));
  sim_fpu_32to (&wop2, FP_PS_lower (op1));
  status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  status_u |= sim_fpu_round_32 (&ans, round, denorm);
  sim_fpu_to32 (&res_u, &ans);
  status_l = 0;
  sim_fpu_32to (&wop1, FP_PS_upper (op2));
  sim_fpu_32to (&wop2, FP_PS_lower (op2));
  status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  status_l |= sim_fpu_round_32 (&ans, round, denorm);
  sim_fpu_to32 (&res_l, &ans);
  result = FP_PS_cat (res_u, res_l);

  update_fcsr (cpu, cia, status_u | status_l);
  return result;
}

unsigned64
fp_add_r(sim_cpu *cpu,
         address_word cia,
         unsigned64 op1,
         unsigned64 op2,
         FP_formats fmt)
{
  return fp_binary_r (cpu, cia, &sim_fpu_add, op1, op2);
}

unsigned64
fp_mul_r(sim_cpu *cpu,
         address_word cia,
         unsigned64 op1,
         unsigned64 op2,
         FP_formats fmt)
{
  return fp_binary_r (cpu, cia, &sim_fpu_mul, op1, op2);
}

#define NR_FRAC_GUARD   (60)
#define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)

static int
fpu_inv1(sim_fpu *f, const sim_fpu *l)
{
  static const sim_fpu sim_fpu_one = {
    sim_fpu_class_number, 0, IMPLICIT_1, 0
  };
  int  status = 0;
  sim_fpu t;

  if (sim_fpu_is_zero (l))
    {
      *f = sim_fpu_maxfp;
      f->sign = l->sign;
      return sim_fpu_status_invalid_div0;
    }
  if (sim_fpu_is_infinity (l))
    {
      *f = sim_fpu_zero;
      f->sign = l->sign;
      return status;
    }
  status |= sim_fpu_div (f, &sim_fpu_one, l);
  return status;
}

static int
fpu_inv1_32(sim_fpu *f, const sim_fpu *l)
{
  if (sim_fpu_is_zero (l))
    {
      *f = sim_fpu_max32;
      f->sign = l->sign;
      return sim_fpu_status_invalid_div0;
    }
  return fpu_inv1 (f, l);
}

static int
fpu_inv1_64(sim_fpu *f, const sim_fpu *l)
{
  if (sim_fpu_is_zero (l))
    {
      *f = sim_fpu_max64;
      f->sign = l->sign;
      return sim_fpu_status_invalid_div0;
    }
  return fpu_inv1 (f, l);
}

unsigned64
fp_recip1(sim_cpu *cpu,
          address_word cia,
          unsigned64 op,
          FP_formats fmt)
{
  switch (fmt)
    {
    case fmt_single:
    case fmt_ps:
      return fp_unary (cpu, cia, &fpu_inv1_32, op, fmt);
    case fmt_double:
      return fp_unary (cpu, cia, &fpu_inv1_64, op, fmt);
    }
  return 0;
}

unsigned64
fp_recip2(sim_cpu *cpu,
          address_word cia,
          unsigned64 op1,
          unsigned64 op2,
          FP_formats fmt)
{
  static const unsigned64 one_single = UNSIGNED64 (0x3F800000);
  static const unsigned64 one_double = UNSIGNED64 (0x3FF0000000000000);
  static const unsigned64 one_ps = (UNSIGNED64 (0x3F800000) << 32 | UNSIGNED64 (0x3F800000));
  unsigned64 one;

  /* Implemented as nmsub fd, 1, fs, ft.  */
  switch (fmt)
    {
    case fmt_single:  one = one_single;  break;
    case fmt_double:  one = one_double;  break;
    case fmt_ps:      one = one_ps;      break;
    default:          one = 0;           abort ();
    }
  return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, one, 0, 1, fmt);
}

static int
fpu_inv_sqrt1(sim_fpu *f, const sim_fpu *l)
{
  static const sim_fpu sim_fpu_one = {
    sim_fpu_class_number, 0, IMPLICIT_1, 0
  };
  int  status = 0;
  sim_fpu t;

  if (sim_fpu_is_zero (l))
    {
      *f = sim_fpu_maxfp;
      f->sign = l->sign;
      return sim_fpu_status_invalid_div0;
    }
  if (sim_fpu_is_infinity (l))
    {
      if (!l->sign)
	{
	  f->class = sim_fpu_class_zero;
	  f->sign = 0;
	}
      else
	{
	  *f = sim_fpu_qnan;
	  status = sim_fpu_status_invalid_sqrt;
	}
      return status;
    }
  status |= sim_fpu_sqrt (&t, l);
  status |= sim_fpu_div (f, &sim_fpu_one, &t);
  return status;
}

static int
fpu_inv_sqrt1_32(sim_fpu *f, const sim_fpu *l)
{
  if (sim_fpu_is_zero (l))
    {
      *f = sim_fpu_max32;
      f->sign = l->sign;
      return sim_fpu_status_invalid_div0;
    }
  return fpu_inv_sqrt1 (f, l);
}

static int
fpu_inv_sqrt1_64(sim_fpu *f, const sim_fpu *l)
{
  if (sim_fpu_is_zero (l))
    {
      *f = sim_fpu_max64;
      f->sign = l->sign;
      return sim_fpu_status_invalid_div0;
    }
  return fpu_inv_sqrt1 (f, l);
}

unsigned64
fp_rsqrt1(sim_cpu *cpu,
          address_word cia,
          unsigned64 op,
          FP_formats fmt)
{
  switch (fmt)
    {
    case fmt_single:
    case fmt_ps:
      return fp_unary (cpu, cia, &fpu_inv_sqrt1_32, op, fmt);
    case fmt_double:
      return fp_unary (cpu, cia, &fpu_inv_sqrt1_64, op, fmt);
    }
  return 0;
}

unsigned64
fp_rsqrt2(sim_cpu *cpu,
          address_word cia,
          unsigned64 op1,
          unsigned64 op2,
          FP_formats fmt)
{
  static const unsigned64 half_single = UNSIGNED64 (0x3F000000);
  static const unsigned64 half_double = UNSIGNED64 (0x3FE0000000000000);
  static const unsigned64 half_ps = (UNSIGNED64 (0x3F000000) << 32 | UNSIGNED64 (0x3F000000));
  unsigned64 half;

  /* Implemented as (nmsub fd, 0.5, fs, ft)/2, where the divide is
     done by scaling the exponent during multiply.  */
  switch (fmt)
    {
    case fmt_single:  half = half_single;  break;
    case fmt_double:  half = half_double;  break;
    case fmt_ps:      half = half_ps;      break;
    default:          half = 0;            abort ();
    }
  return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, half, -1, 1, fmt);
}


/* Conversion operations.  */

uword64
convert (sim_cpu *cpu,
	 address_word cia,
	 int rm,
	 uword64 op,
	 FP_formats from,
	 FP_formats to)
{
  sim_fpu wop;
  sim_fpu_round round = rounding_mode (rm);
  sim_fpu_denorm denorm = denorm_mode (cpu);
  unsigned32 result32;
  unsigned64 result64;
  sim_fpu_status status = 0;

  /* Convert the input to sim_fpu internal format */
  switch (from)
    {
    case fmt_double:
      sim_fpu_64to (&wop, op);
      break;
    case fmt_single:
      sim_fpu_32to (&wop, op);
      break;
    case fmt_word:
      status = sim_fpu_i32to (&wop, op, round);
      break;
    case fmt_long:
      status = sim_fpu_i64to (&wop, op, round);
      break;
    default:
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }

  /* Convert sim_fpu format into the output */
  /* The value WOP is converted to the destination format, rounding
     using mode RM. When the destination is a fixed-point format, then
     a source value of Infinity, NaN or one which would round to an
     integer outside the fixed point range then an IEEE Invalid Operation
     condition is raised.  Not used if destination format is PS.  */
  switch (to)
    {
    case fmt_single:
      status |= sim_fpu_round_32 (&wop, round, denorm);
      /* For a NaN, normalize mantissa bits (cvt.s.d can't preserve them) */
      if (sim_fpu_is_qnan (&wop))
	wop = sim_fpu_qnan;
      sim_fpu_to32 (&result32, &wop);
      result64 = result32;
      break;
    case fmt_double:
      status |= sim_fpu_round_64 (&wop, round, denorm);
      /* For a NaN, normalize mantissa bits (make cvt.d.s consistent) */
      if (sim_fpu_is_qnan (&wop))
	wop = sim_fpu_qnan;
      sim_fpu_to64 (&result64, &wop);
      break;
    case fmt_word:
      status |= sim_fpu_to32i (&result32, &wop, round);
      result64 = result32;
      break;
    case fmt_long:
      status |= sim_fpu_to64i (&result64, &wop, round);
      break;
    default:
      result64 = 0;
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }

  update_fcsr (cpu, cia, status);
  return result64;
}

unsigned64
ps_lower(sim_cpu *cpu,
         address_word cia,
         unsigned64 op)
{
  return FP_PS_lower (op);
}

unsigned64
ps_upper(sim_cpu *cpu,
         address_word cia,
         unsigned64 op)
{
  return FP_PS_upper(op);
}

unsigned64
pack_ps(sim_cpu *cpu,
        address_word cia,
        unsigned64 op1,
        unsigned64 op2,
        FP_formats fmt)
{
  unsigned64 result = 0;

  /* The registers must specify FPRs valid for operands of type
     "fmt". If they are not valid, the result is undefined. */

  /* The format type should already have been checked: */
  switch (fmt)
    {
    case fmt_single:
      {
	sim_fpu wop;
	unsigned32 res_u, res_l;
	sim_fpu_32to (&wop, op1);
	sim_fpu_to32 (&res_u, &wop);
	sim_fpu_32to (&wop, op2);
	sim_fpu_to32 (&res_l, &wop);
	result = FP_PS_cat(res_u, res_l);
	break;
      }
    default:
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }

  return result;
}

unsigned64
convert_ps (sim_cpu *cpu,
            address_word cia,
            int rm,
            unsigned64 op,
            FP_formats from,
            FP_formats to)
{
  sim_fpu wop_u, wop_l;
  sim_fpu_round round = rounding_mode (rm);
  sim_fpu_denorm denorm = denorm_mode (cpu);
  unsigned32 res_u, res_l;
  unsigned64 result;
  sim_fpu_status status_u = 0, status_l = 0;

  /* As convert, but used only for paired values (formats PS, PW) */

  /* Convert the input to sim_fpu internal format */
  switch (from)
    {
    case fmt_word:   /* fmt_pw */
      sim_fpu_i32to (&wop_u, (op >> 32) & (unsigned)0xFFFFFFFF, round);
      sim_fpu_i32to (&wop_l, op & (unsigned)0xFFFFFFFF, round);
      break;
    case fmt_ps:
      sim_fpu_32to (&wop_u, FP_PS_upper(op));
      sim_fpu_32to (&wop_l, FP_PS_lower(op));
      break;
    default:
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }

  /* Convert sim_fpu format into the output */
  switch (to)
    {
    case fmt_word:   /* fmt_pw */
      status_u |= sim_fpu_to32i (&res_u, &wop_u, round);
      status_l |= sim_fpu_to32i (&res_l, &wop_l, round);
      result = (((unsigned64)res_u) << 32) | (unsigned64)res_l;
      break;
    case fmt_ps:
      status_u |= sim_fpu_round_32 (&wop_u, 0, round);
      status_l |= sim_fpu_round_32 (&wop_l, 0, round);
      sim_fpu_to32 (&res_u, &wop_u);
      sim_fpu_to32 (&res_l, &wop_l);
      result = FP_PS_cat(res_u, res_l);
      break;
    default:
      result = 0;
      sim_io_eprintf (SD, "Bad switch\n");
      abort ();
    }

  update_fcsr (cpu, cia, status_u | status_l);
  return result;
}

static const char *
fpu_format_name (FP_formats fmt)
{
  switch (fmt)
    {
    case fmt_single:
      return "single";
    case fmt_double:
      return "double";
    case fmt_word:
      return "word";
    case fmt_long:
      return "long";
    case fmt_ps:
      return "ps";
    case fmt_unknown:
      return "<unknown>";
    case fmt_uninterpreted:
      return "<uninterpreted>";
    case fmt_uninterpreted_32:
      return "<uninterpreted_32>";
    case fmt_uninterpreted_64:
      return "<uninterpreted_64>";
    default:
      return "<format error>";
    }
}

#ifdef DEBUG
static const char *
fpu_rounding_mode_name (int rm)
{
  switch (rm)
    {
    case FP_RM_NEAREST:
      return "Round";
    case FP_RM_TOZERO:
      return "Trunc";
    case FP_RM_TOPINF:
      return "Ceil";
    case FP_RM_TOMINF:
      return "Floor";
    default:
      return "<rounding mode error>";
    }
}
#endif /* DEBUG */
