/*
    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;
#ifdef HOST_WORDS_BIGENDIAN
         p[0] ^= 0x80000000;
#else
         p[1] ^= 0x80000000;
#endif
         fpa11->fpreg[Fd].fDouble = rFm;
      }
      break;

      case ABS_CODE:
      {
         unsigned int *p = (unsigned int*)&rFm;
#ifdef HOST_WORDS_BIGENDIAN
         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
