/*
    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=0;
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
