/**********************************************************************/
/* NAME: C30ToHost_s(&host,&uut)                                      */
/*                                                                    */
/* DATE: 22-feb-97        VERSION: 2.01       FILE: C302hsts.c        */
/*                                                                    */
/*   IN: uut  > TMS320C30 32-bit single precision floating point      */
/*                                                                    */
/*  OUT: host > 80x87 (IEEE-754) 64-bit double floating point         */
/*                                                                    */
/*  RET: 0, no errors                                                 */
/*                                                                    */
/*  Revision Record:                                                  */
/*                                                                    */
/*  22-feb-97 Original.                                               */
/*  26-jul-01 Fixed processing of 0, must be 0x80000000 not exp=-128. */
/**********************************************************************/
/* This routine converts the Unit Under Test computer's (TMS320C30)   */
/* 32-bit single precision floating point number to the host comput-  */
/* er's (80x87) 64-bit double precision floating point number.        */
/*                                                                    */
/*                        80x87                    TMS320C30          */
/*                 -------------------     ----------------------     */
/*      exponent:  11-bits excess 1023      8-bits 2's complement     */
/*    s/mantissa:  53-bits s/magnitude     24-bits 2's complement     */
/*    normalized:  msb bit weight 1.0      msb bit weight 1.0         */
/*  unnormalized:  denormals (exp=0)       none                       */
/*          zero:  all zeros               max neg exp (-128)         */
/*    hidden bit:  msb (1 assumed)         msb (1 or -1 assumed)      */
/*                                                                    */
/*              63        52                                      0   */
/*             ----------------------------------------------------   */
/*  80x87      |s| exp(11) |           mantissa(52)               |   */
/*             ----------------------------------------------------   */
/*                                                                    */
/*              31      23               0                            */
/*             ---------------------------                            */
/*  TMS320C30  | exp(8) |s| mantissa(23) |                            */
/*             ---------------------------                            */
/*                                                                    */
/* The C30 floating point is passed into this routine as a pointer    */
/* to a 32 bit long in the order shown above (i.e. msb = exp msb).    */
/**********************************************************************/

int C30ToHost_s(double *host, long *uut)
{
union   LOCAL   { double        dbl;                /* PC parts */
                  unsigned long lng[2]; } hst;

long loc;       /* Temporary storage for uut      */
long exp;       /* Temporary storage for exponent */
long man;       /* Temporary storage for mantissa */
long sgn;       /* Temporary storage for sign bit */

/* Pull data in locally */

    loc = *uut;                         /* msb's = exp */

/* Isolate exponent (extend sign) */

    exp = loc >> 24;

/* Check for C30 0.0 */

    if(loc == 0x80000000)
        {
        *host = 0.0;
        return 0;
        }

/* Isolate mantissa (assume positive, shift up and unhide 1) */

    man = ((loc << 7) & 0x3FFFFF80) | 0x40000000;

/* 2's complement mantissa if negative and adjust exp if necessary */

    sgn = ((loc & 0x00800000) << 8);        /* move sign to final location */

    if(sgn)
        {
        man = man ^ 0xC0000000;             /* correct mantissa */
        man = -man;                         /* 2's complement   */

        if(man == 0x80000000)               /* power of 2 ?    */
            exp++;                          /* adjust exponent */
        }

/* Assemble the pieces and build results */

    exp = (exp + 1023) & 0x0000007FF;       /* excess exponent */

    hst.lng[1] = sgn                        /* sign */
    |        (exp << 20)                    /* exponent */
    |       ((man & 0x3FFFFFFF) >> 10);     /* msb's of mantissa (hide!) */

    hst.lng[0] = man << 22;                 /* lsb's of mantissa */

    *host = hst.dbl;

    return 0;
}
