/*
    NetWinder Floating Point Emulator
    (c) Rebel.COM, 1998,1999

    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>

    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 2 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, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "fpa11.h"

#include "fpopcode.h"

//#include "fpmodule.h"
//#include "fpmodule.inl"

//#include <asm/system.h>

#include <stdio.h>

FPA11* qemufpa = NULL;
CPUARMState* user_registers;

/* Reset the FPA11 chip.  Called to initialize and reset the emulator. */
void resetFPA11(void)
{
  int i;
  FPA11 *fpa11 = GET_FPA11();

  /* initialize the register type array */
  for (i=0;i<=7;i++)
  {
    fpa11->fType[i] = typeNone;
  }

  /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
  fpa11->fpsr = FP_EMULATOR | BIT_AC;

  /* FPCR: set SB, AB and DA bits, clear all others */
#ifdef MAINTAIN_FPCR
  fpa11->fpcr = MASK_RESET;
#endif
}

void SetRoundingMode(const unsigned int opcode)
{
    int rounding_mode;
   FPA11 *fpa11 = GET_FPA11();

#ifdef MAINTAIN_FPCR
   fpa11->fpcr &= ~MASK_ROUNDING_MODE;
#endif
   switch (opcode & MASK_ROUNDING_MODE)
   {
      default:
      case ROUND_TO_NEAREST:
         rounding_mode = float_round_nearest_even;
#ifdef MAINTAIN_FPCR
         fpa11->fpcr |= ROUND_TO_NEAREST;
#endif
      break;

      case ROUND_TO_PLUS_INFINITY:
         rounding_mode = float_round_up;
#ifdef MAINTAIN_FPCR
         fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
#endif
      break;

      case ROUND_TO_MINUS_INFINITY:
         rounding_mode = float_round_down;
#ifdef MAINTAIN_FPCR
         fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
#endif
      break;

      case ROUND_TO_ZERO:
         rounding_mode = float_round_to_zero;
#ifdef MAINTAIN_FPCR
         fpa11->fpcr |= ROUND_TO_ZERO;
#endif
      break;
  }
   set_float_rounding_mode(rounding_mode, &fpa11->fp_status);
}

void SetRoundingPrecision(const unsigned int opcode)
{
    int rounding_precision;
   FPA11 *fpa11 = GET_FPA11();
#ifdef MAINTAIN_FPCR
   fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
#endif
   switch (opcode & MASK_ROUNDING_PRECISION)
   {
      case ROUND_SINGLE:
         rounding_precision = 32;
#ifdef MAINTAIN_FPCR
         fpa11->fpcr |= ROUND_SINGLE;
#endif
      break;

      case ROUND_DOUBLE:
         rounding_precision = 64;
#ifdef MAINTAIN_FPCR
         fpa11->fpcr |= ROUND_DOUBLE;
#endif
      break;

      case ROUND_EXTENDED:
         rounding_precision = 80;
#ifdef MAINTAIN_FPCR
         fpa11->fpcr |= ROUND_EXTENDED;
#endif
      break;

      default: rounding_precision = 80;
  }
   set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status);
}

/* Emulate the instruction in the opcode. */
/* ??? This is not thread safe.  */
unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
{
  unsigned int nRc = 0;
//  unsigned long flags;
  FPA11 *fpa11;
//  save_flags(flags); sti();

  qemufpa=qfpa;
  user_registers=qregs;

#if 0
  fprintf(stderr,"emulating FP insn 0x%08x, PC=0x%08x\n",
          opcode, qregs[REG_PC]);
#endif
  fpa11 = GET_FPA11();

  if (fpa11->initflag == 0)		/* good place for __builtin_expect */
  {
    resetFPA11();
    SetRoundingMode(ROUND_TO_NEAREST);
    SetRoundingPrecision(ROUND_EXTENDED);
    fpa11->initflag = 1;
  }

  set_float_exception_flags(0, &fpa11->fp_status);

  if (TEST_OPCODE(opcode,MASK_CPRT))
  {
    //fprintf(stderr,"emulating CPRT\n");
    /* Emulate conversion opcodes. */
    /* Emulate register transfer opcodes. */
    /* Emulate comparison opcodes. */
    nRc = EmulateCPRT(opcode);
  }
  else if (TEST_OPCODE(opcode,MASK_CPDO))
  {
    //fprintf(stderr,"emulating CPDO\n");
    /* Emulate monadic arithmetic opcodes. */
    /* Emulate dyadic arithmetic opcodes. */
    nRc = EmulateCPDO(opcode);
  }
  else if (TEST_OPCODE(opcode,MASK_CPDT))
  {
    //fprintf(stderr,"emulating CPDT\n");
    /* Emulate load/store opcodes. */
    /* Emulate load/store multiple opcodes. */
    nRc = EmulateCPDT(opcode);
  }
  else
  {
    /* Invalid instruction detected.  Return FALSE. */
    nRc = 0;
  }

//  restore_flags(flags);
  if(nRc == 1 && get_float_exception_flags(&fpa11->fp_status))
  {
    //printf("fef 0x%x\n",float_exception_flags);
    nRc = -get_float_exception_flags(&fpa11->fp_status);
  }

  //printf("returning %d\n",nRc);
  return(nRc);
}

#if 0
unsigned int EmulateAll1(unsigned int opcode)
{
  switch ((opcode >> 24) & 0xf)
  {
     case 0xc:
     case 0xd:
       if ((opcode >> 20) & 0x1)
       {
          switch ((opcode >> 8) & 0xf)
          {
             case 0x1: return PerformLDF(opcode); break;
             case 0x2: return PerformLFM(opcode); break;
             default: return 0;
          }
       }
       else
       {
          switch ((opcode >> 8) & 0xf)
          {
             case 0x1: return PerformSTF(opcode); break;
             case 0x2: return PerformSFM(opcode); break;
             default: return 0;
          }
      }
     break;

     case 0xe:
       if (opcode & 0x10)
         return EmulateCPDO(opcode);
       else
         return EmulateCPRT(opcode);
     break;

     default: return 0;
  }
}
#endif
