/*
    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, see <http://www.gnu.org/licenses/>.
*/

#include "qemu/osdep.h"
#include "fpa11.h"
#include "fpu/softfloat.h"
#include "fpopcode.h"

float64 float64_exp(float64 Fm);
float64 float64_ln(float64 Fm);
float64 float64_sin(float64 rFm);
float64 float64_cos(float64 rFm);
float64 float64_arcsin(float64 rFm);
float64 float64_arctan(float64 rFm);
float64 float64_log(float64 rFm);
float64 float64_tan(float64 rFm);
float64 float64_arccos(float64 rFm);
float64 float64_pow(float64 rFn,float64 rFm);
float64 float64_pol(float64 rFn,float64 rFm);

unsigned int DoubleCPDO(const unsigned int opcode)
{
   FPA11 *fpa11 = GET_FPA11();
   float64 rFm, rFn = float64_zero;
   unsigned int Fd, Fm, Fn, nRc = 1;

   //printk("DoubleCPDO(0x%08x)\n",opcode);

   Fm = getFm(opcode);
   if (CONSTANT_FM(opcode))
   {
     rFm = getDoubleConstant(Fm);
   }
   else
   {
     switch (fpa11->fType[Fm])
     {
        case typeSingle:
          rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
        break;

        case typeDouble:
          rFm = fpa11->fpreg[Fm].fDouble;
          break;

        case typeExtended:
            // !! patb
	    //printk("not implemented! why not?\n");
            //!! ScottB
            // should never get here, if extended involved
            // then other operand should be promoted then
            // ExtendedCPDO called.
            break;

        default: return 0;
     }
   }

   if (!MONADIC_INSTRUCTION(opcode))
   {
      Fn = getFn(opcode);
      switch (fpa11->fType[Fn])
      {
        case typeSingle:
          rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
        break;

        case typeDouble:
          rFn = fpa11->fpreg[Fn].fDouble;
        break;

        default: return 0;
      }
   }

   Fd = getFd(opcode);
   /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
   switch (opcode & MASK_ARITHMETIC_OPCODE)
   {
      /* dyadic opcodes */
      case ADF_CODE:
         fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status);
      break;

      case MUF_CODE:
      case FML_CODE:
         fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status);
      break;

      case SUF_CODE:
         fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status);
      break;

      case RSF_CODE:
         fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status);
      break;

      case DVF_CODE:
      case FDV_CODE:
         fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status);
      break;

      case RDF_CODE:
      case FRD_CODE:
         fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status);
      break;

#if 0
      case POW_CODE:
         fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
      break;

      case RPW_CODE:
         fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
      break;
#endif

      case RMF_CODE:
         fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status);
      break;

#if 0
      case POL_CODE:
         fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
      break;
#endif

      /* monadic opcodes */
      case MVF_CODE:
         fpa11->fpreg[Fd].fDouble = rFm;
      break;

      case MNF_CODE:
      {
         unsigned int *p = (unsigned int*)&rFm;
#if HOST_BIG_ENDIAN
         p[0] ^= 0x80000000;
#else
         p[1] ^= 0x80000000;
#endif
         fpa11->fpreg[Fd].fDouble = rFm;
      }
      break;

      case ABS_CODE:
      {
         unsigned int *p = (unsigned int*)&rFm;
#if HOST_BIG_ENDIAN
         p[0] &= 0x7fffffff;
#else
         p[1] &= 0x7fffffff;
#endif
         fpa11->fpreg[Fd].fDouble = rFm;
      }
      break;

      case RND_CODE:
      case URD_CODE:
         fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status);
      break;

      case SQT_CODE:
         fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status);
      break;

#if 0
      case LOG_CODE:
         fpa11->fpreg[Fd].fDouble = float64_log(rFm);
      break;

      case LGN_CODE:
         fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
      break;

      case EXP_CODE:
         fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
      break;

      case SIN_CODE:
         fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
      break;

      case COS_CODE:
         fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
      break;

      case TAN_CODE:
         fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
      break;

      case ASN_CODE:
         fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
      break;

      case ACS_CODE:
         fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
      break;

      case ATN_CODE:
         fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
      break;
#endif

      case NRM_CODE:
      break;

      default:
      {
        nRc = 0;
      }
   }

   if (0 != nRc) fpa11->fType[Fd] = typeDouble;
   return nRc;
}

#if 0
float64 float64_exp(float64 rFm)
{
  return rFm;
//series
}

float64 float64_ln(float64 rFm)
{
  return rFm;
//series
}

float64 float64_sin(float64 rFm)
{
  return rFm;
//series
}

float64 float64_cos(float64 rFm)
{
   return rFm;
   //series
}

#if 0
float64 float64_arcsin(float64 rFm)
{
//series
}

float64 float64_arctan(float64 rFm)
{
  //series
}
#endif

float64 float64_log(float64 rFm)
{
  return float64_div(float64_ln(rFm),getDoubleConstant(7));
}

float64 float64_tan(float64 rFm)
{
  return float64_div(float64_sin(rFm),float64_cos(rFm));
}

float64 float64_arccos(float64 rFm)
{
return rFm;
   //return float64_sub(halfPi,float64_arcsin(rFm));
}

float64 float64_pow(float64 rFn,float64 rFm)
{
  return float64_exp(float64_mul(rFm,float64_ln(rFn)));
}

float64 float64_pol(float64 rFn,float64 rFm)
{
  return float64_arctan(float64_div(rFn,rFm));
}
#endif
