// File: rurban[P]dgnlib/dgnfloat.cpp
// Function: DGN2IEEEDouble(void*)
void    DGN2IEEEDouble(void * dbl)

{
    double64_t  dt;
    GUInt32     sign;
    GUInt32     exponent;
    GUInt32     rndbits;
    unsigned char       *src;
    unsigned char       *dest;

/* -------------------------------------------------------------------- */
/*      Arrange the VAX double so that it may be accessed by a          */
/*      double64_t structure, (two GUInt32s).                           */
/* -------------------------------------------------------------------- */
    src =  (unsigned char *) dbl;
    dest = (unsigned char *) &dt;
#ifdef CPL_LSB
    dest[2] = src[0];
    dest[3] = src[1];
    dest[0] = src[2];
    dest[1] = src[3];
    dest[6] = src[4];
    dest[7] = src[5];
    dest[4] = src[6];
    dest[5] = src[7];
#else
    dest[1] = src[0];
    dest[0] = src[1];
    dest[3] = src[2];
    dest[2] = src[3];
    dest[5] = src[4];
    dest[4] = src[5];
    dest[7] = src[6];
    dest[6] = src[7];
#endif

/* -------------------------------------------------------------------- */
/*      Save the sign of the double                                     */
/* -------------------------------------------------------------------- */
    sign         = dt.hi & 0x80000000;

/* -------------------------------------------------------------------- */
/*      Adjust the exponent so that we may work with it                 */      
/* -------------------------------------------------------------------- */
    exponent = (dt.hi >> 23) & 0x000000ff;

    if (exponent)
        exponent = exponent -129 + 1023;

/* -------------------------------------------------------------------- */
/*      Save the bits that we are discarding so we can round properly   */
/* -------------------------------------------------------------------- */
    rndbits = dt.lo & 0x00000007;
        
    dt.lo = dt.lo >> 3;
    dt.lo = (dt.lo & 0x1fffffff) | (dt.hi << 29);

    if (rndbits)
        dt.lo = dt.lo | 0x00000001;

/* -------------------------------------------------------------------- */
/*      Shift the hi-order int over 3 and insert the exponent and sign  */
/* -------------------------------------------------------------------- */
    dt.hi = dt.hi >> 3;
    dt.hi = dt.hi & 0x000fffff;
    dt.hi = dt.hi | (exponent << 20) | sign;



#ifdef CPL_LSB
/* -------------------------------------------------------------------- */
/*      Change the number to a byte swapped format                      */
/* -------------------------------------------------------------------- */
    src = (unsigned char *) &dt;
    dest = (unsigned char *) dbl;

    dest[0] = src[4];
    dest[1] = src[5];
    dest[2] = src[6];
    dest[3] = src[7];
    dest[4] = src[0];
    dest[5] = src[1];
    dest[6] = src[2];
    dest[7] = src[3];
#else
    memcpy( dbl, &dt, 8 );
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
leaq -0x10(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movb (%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x2(%rax)
movq -0x28(%rbp), %rax
movb 0x1(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x3(%rax)
movq -0x28(%rbp), %rax
movb 0x2(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, (%rax)
movq -0x28(%rbp), %rax
movb 0x3(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x1(%rax)
movq -0x28(%rbp), %rax
movb 0x4(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x6(%rax)
movq -0x28(%rbp), %rax
movb 0x5(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x7(%rax)
movq -0x28(%rbp), %rax
movb 0x6(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x4(%rax)
movq -0x28(%rbp), %rax
movb 0x7(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x5(%rax)
movl -0x10(%rbp), %eax
andl $0x80000000, %eax       # imm = 0x80000000
movl %eax, -0x14(%rbp)
movl -0x10(%rbp), %eax
shrl $0x17, %eax
andl $0xff, %eax
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
je 0xa245
movl -0x18(%rbp), %eax
subl $0x81, %eax
addl $0x3ff, %eax            # imm = 0x3FF
movl %eax, -0x18(%rbp)
movl -0xc(%rbp), %eax
andl $0x7, %eax
movl %eax, -0x1c(%rbp)
movl -0xc(%rbp), %eax
shrl $0x3, %eax
movl %eax, -0xc(%rbp)
movl -0xc(%rbp), %eax
andl $0x1fffffff, %eax       # imm = 0x1FFFFFFF
movl -0x10(%rbp), %ecx
shll $0x1d, %ecx
orl %ecx, %eax
movl %eax, -0xc(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0xa279
movl -0xc(%rbp), %eax
orl $0x1, %eax
movl %eax, -0xc(%rbp)
movl -0x10(%rbp), %eax
shrl $0x3, %eax
movl %eax, -0x10(%rbp)
movl -0x10(%rbp), %eax
andl $0xfffff, %eax          # imm = 0xFFFFF
movl %eax, -0x10(%rbp)
movl -0x10(%rbp), %eax
movl -0x18(%rbp), %ecx
shll $0x14, %ecx
orl %ecx, %eax
orl -0x14(%rbp), %eax
movl %eax, -0x10(%rbp)
leaq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movb 0x4(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, (%rax)
movq -0x28(%rbp), %rax
movb 0x5(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x1(%rax)
movq -0x28(%rbp), %rax
movb 0x6(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x2(%rax)
movq -0x28(%rbp), %rax
movb 0x7(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x3(%rax)
movq -0x28(%rbp), %rax
movb (%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x4(%rax)
movq -0x28(%rbp), %rax
movb 0x1(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x5(%rax)
movq -0x28(%rbp), %rax
movb 0x2(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x6(%rax)
movq -0x28(%rbp), %rax
movb 0x3(%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x7(%rax)
popq %rbp
retq
nop