// File: /workspace/github_cpp_makefile_star2_O3/jkingan[P]ladyheather/heathgps.cpp
// Function: tsip_fp80()
double tsip_fp80()  
{
u08 i;
u08 x[10];
u08 d[8];
u16 c;
int exponent;
s64 mantissa;
double val;

   // get FP80 10 byte floating number from binary message (in Intel byte order!)
   // and return it as a standard double 

   for(i=0; i<10; i++) {  // get 10 bytes from the receiver (always in intel byte order)
      c = get_next_tsip_byte();
      if(c & 0xFF00) tsip_error |= FP80_ERROR;
      x[i] = (u08) c;
   }

   for(i=0; i<8; i++) d[i] = 0;

   exponent = (((x[9] << 8) | x[8]) & 0x7FFF);
   mantissa =
       ((u64)x[7] << 56) | ((u64)x[6] << 48) | ((u64)x[5] << 40) | ((u64)x[4] << 32) | 
       ((u64)x[3] << 24) | ((u64)x[2] << 16) | ((u64)x[1] << 8) | (u64)x[0];

   d[7] = x[9] & 0x80; // Set sign

   if((exponent == 0x7FFF) || (exponent == 0)) { // Infinite, NaN or denormal 
      if(exponent == 0x7FFF) {  // Infinite or NaN 
         d[7] |= 0x7F;
         d[6] = 0xF0;
      }
      else { // It's denormal. It cannot be represented as double. Translate as zero.
         return 0.0;
      }
   }
   else {  // Normal number
      exponent = exponent - 0x3FFF + 0x03FF; // exponent for double precision.

      if(exponent <= -52) { // too small to represent. Translate as (signed) zero.
         return 0.0;
      }
      else if(exponent < 0) {  // Denormal, exponent bits are already zero here.
      }
      else if(exponent >= 0x7FF) { // Too large to represent. Translate as infinite.
         d[7] |= 0x7F;
         d[6] = 0xF0;
         goto got_it;
      }
      else { // Representable number 
         d[7] |= (exponent & 0x7F0) >> 4;
         d[6] |= (exponent & 0xF) << 4;
      }
   }

   // Translate mantissa

   mantissa >>= 11;

   if(exponent < 0) { // Denormal, further shifting is required here.
      mantissa >>= (-exponent + 1);
   }

   d[0]  = (u08) ((mantissa >> 0) & 0xFF);  // break down the mantissa
   d[1]  = (u08) ((mantissa >> 8) & 0xFF);
   d[2]  = (u08) ((mantissa >> 16) & 0xFF);
   d[3]  = (u08) ((mantissa >> 24) & 0xFF);
   d[4]  = (u08) ((mantissa >> 32) & 0xFF);
   d[5]  = (u08) ((mantissa >> 40) & 0xFF);
   d[6] |= (u08) ((mantissa >> 48) & 0x0F);

   got_it:
   if(!ENDIAN) {  // need to reverse the result byte order
      i = d[0];  d[0] = d[7];  d[7] = i;
      i = d[1];  d[1] = d[6];  d[6] = i;
      i = d[2];  d[2] = d[5];  d[5] = i;
      i = d[3];  d[3] = d[4];  d[4] = i;
   }

   val = (* ((double *) (void *) &d[0]));
   val = check_double(val);   // checks for NAN's, etc
   return val;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x10, %rsp
xorl %r14d, %r14d
leaq 0x1e63bb(%rip), %rbx    # 0x23ef70
callq 0x587be
cmpl $0x100, %eax            # imm = 0x100
jb 0x58bc5
orb $0x2, 0x1(%rbx)
movb %al, -0x1a(%rbp,%r14)
incq %r14
cmpq $0xa, %r14
jne 0x58bb5
movb -0x11(%rbp), %dil
movzbl %dil, %ecx
movzbl -0x12(%rbp), %esi
andl $0x7f, %ecx
shll $0x8, %ecx
movl %ecx, %edx
orl %esi, %edx
xorpd %xmm0, %xmm0
je 0x58d57
movl -0x16(%rbp), %eax
shlq $0x20, %rax
movzbl -0x17(%rbp), %r8d
shll $0x18, %r8d
orq %rax, %r8
movzbl -0x18(%rbp), %r9d
shll $0x10, %r9d
orq %r8, %r9
movzbl -0x19(%rbp), %eax
shll $0x8, %eax
orq %r9, %rax
cmpl $0x7fff, %edx           # imm = 0x7FFF
jne 0x58c46
orb $0x7f, %dil
movzbl %dil, %ecx
shlq $0x38, %rcx
movabsq $0xf0000000000000, %rsi # imm = 0xF0000000000000
orq %rcx, %rsi
sarq $0xb, %rax
jmp 0x58cd4
cmpl $0x3bcd, %edx           # imm = 0x3BCD
jb 0x58d57
movl %edi, %r8d
andb $-0x80, %r8b
cmpl $0x3c00, %ecx           # imm = 0x3C00
jae 0x58c6b
movzbl %r8b, %esi
shlq $0x38, %rsi
jmp 0x58cb8
cmpl $0x43ff, %edx           # imm = 0x43FF
jb 0x58c91
orb $0x7f, %dil
movzbl %dil, %ecx
shlq $0x38, %rcx
movabsq $0xf0000000000000, %rax # imm = 0xF0000000000000
orq %rcx, %rax
jmp 0x58d11
movl %edx, %edi
shrl $0x4, %edi
andb $0x7f, %dil
orb %r8b, %dil
xorb $0x40, %dil
movzbl %dil, %edi
shlq $0x38, %rdi
shlb $0x4, %sil
movzbl %sil, %esi
shlq $0x30, %rsi
orq %rdi, %rsi
sarq $0xb, %rax
movb $0x1, %dil
subb %dl, %dil
xorl %edx, %edx
cmpl $0x3c00, %ecx           # imm = 0x3C00
movzbl %dil, %ecx
cmovael %edx, %ecx
sarq %cl, %rax
movabsq $0xffffffffffff, %rcx   # imm = 0xFFFFFFFFFFFF
andq %rax, %rcx
movabsq $0xf000000000000, %rdx  # imm = 0xF000000000000
andq %rax, %rdx
movabsq $0xff000000000000, %rdi # imm = 0xFF000000000000
andq %rsi, %rdi
orq %rdx, %rdi
movabsq $-0xff000000000001, %rax # imm = 0xFF00FFFFFFFFFFFF
andq %rsi, %rax
orq %rcx, %rax
orq %rdi, %rax
leaq 0x1bfabc(%rip), %rcx    # 0x2187d4
cmpb $0x0, (%rcx)
movq %rax, %rcx
bswapq %rcx
cmovneq %rax, %rcx
movq %rcx, %xmm0
ucomisd %xmm0, %xmm0
jp 0x58d60
movsd 0xc53e8(%rip), %xmm1    # 0x11e120
movl $0x800, %eax            # imm = 0x800
ucomisd %xmm1, %xmm0
ja 0x58d51
movsd 0xc53dd(%rip), %xmm1    # 0x11e128
ucomisd %xmm0, %xmm1
jbe 0x58d57
orl %eax, (%rbx)
movapd %xmm1, %xmm0
addq $0x10, %rsp
popq %rbx
popq %r14
popq %rbp
retq
xorpd %xmm1, %xmm1
movl $0x400, %eax            # imm = 0x400
jmp 0x58d51