/*
    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 "softfloat.h"
#include "fpopcode.h"
#include "fpsr.h"
//#include "fpmodule.h"
//#include "fpmodule.inl"

const floatx80 floatx80Constant[] = {
  { 0x0000000000000000ULL, 0x0000},	/* extended 0.0 */
  { 0x8000000000000000ULL, 0x3fff},	/* extended 1.0 */
  { 0x8000000000000000ULL, 0x4000},	/* extended 2.0 */
  { 0xc000000000000000ULL, 0x4000},	/* extended 3.0 */
  { 0x8000000000000000ULL, 0x4001},	/* extended 4.0 */
  { 0xa000000000000000ULL, 0x4001},	/* extended 5.0 */
  { 0x8000000000000000ULL, 0x3ffe},	/* extended 0.5 */
  { 0xa000000000000000ULL, 0x4002}	/* extended 10.0 */
};

const float64 float64Constant[] = {
  0x0000000000000000ULL,		/* double 0.0 */
  0x3ff0000000000000ULL,		/* double 1.0 */
  0x4000000000000000ULL,		/* double 2.0 */
  0x4008000000000000ULL,		/* double 3.0 */
  0x4010000000000000ULL,		/* double 4.0 */
  0x4014000000000000ULL,		/* double 5.0 */
  0x3fe0000000000000ULL,		/* double 0.5 */
  0x4024000000000000ULL			/* double 10.0 */
};

const float32 float32Constant[] = {
  0x00000000,				/* single 0.0 */
  0x3f800000,				/* single 1.0 */
  0x40000000,				/* single 2.0 */
  0x40400000,				/* single 3.0 */
  0x40800000,				/* single 4.0 */
  0x40a00000,				/* single 5.0 */
  0x3f000000,				/* single 0.5 */
  0x41200000				/* single 10.0 */
};

unsigned int getTransferLength(const unsigned int opcode)
{
  unsigned int nRc;

  switch (opcode & MASK_TRANSFER_LENGTH)
  {
    case 0x00000000: nRc = 1; break; /* single precision */
    case 0x00008000: nRc = 2; break; /* double precision */
    case 0x00400000: nRc = 3; break; /* extended precision */
    default: nRc = 0;
  }

  return(nRc);
}

unsigned int getRegisterCount(const unsigned int opcode)
{
  unsigned int nRc;

  switch (opcode & MASK_REGISTER_COUNT)
  {
    case 0x00000000: nRc = 4; break;
    case 0x00008000: nRc = 1; break;
    case 0x00400000: nRc = 2; break;
    case 0x00408000: nRc = 3; break;
    default: nRc = 0;
  }

  return(nRc);
}

unsigned int getRoundingPrecision(const unsigned int opcode)
{
  unsigned int nRc;

  switch (opcode & MASK_ROUNDING_PRECISION)
  {
    case 0x00000000: nRc = 1; break;
    case 0x00000080: nRc = 2; break;
    case 0x00080000: nRc = 3; break;
    default: nRc = 0;
  }

  return(nRc);
}

unsigned int getDestinationSize(const unsigned int opcode)
{
  unsigned int nRc;

  switch (opcode & MASK_DESTINATION_SIZE)
  {
    case 0x00000000: nRc = typeSingle; break;
    case 0x00000080: nRc = typeDouble; break;
    case 0x00080000: nRc = typeExtended; break;
    default: nRc = typeNone;
  }

  return(nRc);
}

/* condition code lookup table
 index into the table is test code: EQ, NE, ... LT, GT, AL, NV
 bit position in short is condition code: NZCV */
static const unsigned short aCC[16] = {
    0xF0F0, // EQ == Z set
    0x0F0F, // NE
    0xCCCC, // CS == C set
    0x3333, // CC
    0xFF00, // MI == N set
    0x00FF, // PL
    0xAAAA, // VS == V set
    0x5555, // VC
    0x0C0C, // HI == C set && Z clear
    0xF3F3, // LS == C clear || Z set
    0xAA55, // GE == (N==V)
    0x55AA, // LT == (N!=V)
    0x0A05, // GT == (!Z && (N==V))
    0xF5FA, // LE == (Z || (N!=V))
    0xFFFF, // AL always
    0 // NV
};

unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes)
{
  return (aCC[opcode>>28] >> (ccodes>>28)) & 1;
}
