// File: /workspace/github_cpp_makefile_star2_O1/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 %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
xorl %r14d, %r14d
leaq 0x1e6337(%rip), %rbx    # 0x23ef70
callq 0x587d1
cmpl $0x100, %eax            # imm = 0x100
jb 0x58c49
orb $0x2, 0x1(%rbx)
movb %al, -0x32(%rbp,%r14)
incq %r14
cmpq $0xa, %r14
jne 0x58c39
movzbl -0x29(%rbp), %r15d
movzbl -0x2a(%rbp), %r14d
movl %r15d, %r12d
andl $0x7f, %r12d
shll $0x8, %r12d
movl %r12d, %r13d
orl %r14d, %r13d
xorpd %xmm0, %xmm0
je 0x58d93
movzbl -0x2b(%rbp), %r11d
movzbl -0x2c(%rbp), %r10d
movzbl -0x2d(%rbp), %r9d
movzbl -0x2e(%rbp), %r8d
movzbl -0x2f(%rbp), %edi
movzbl -0x30(%rbp), %esi
movzbl -0x31(%rbp), %eax
cmpl $0x7fff, %r13d          # imm = 0x7FFF
jne 0x58d8a
orl $0x7f, %r15d
shlq $0x38, %r15
movabsq $0xf0000000000000, %rdx # imm = 0xF0000000000000
orq %r15, %rdx
movl $0x7fff, %ecx           # imm = 0x7FFF
shlq $0x38, %r11
shlq $0x30, %r10
orq %r11, %r10
shlq $0x28, %r9
orq %r10, %r9
shlq $0x20, %r8
orq %r9, %r8
shll $0x18, %edi
orq %r8, %rdi
shll $0x10, %esi
orq %rdi, %rsi
shll $0x8, %eax
orq %rsi, %rax
sarq $0xb, %rax
movl $0x1, %esi
subl %ecx, %esi
sarl $0x1f, %ecx
andl %esi, %ecx
sarq %cl, %rax
movabsq $0xffffffffffff, %rcx   # imm = 0xFFFFFFFFFFFF
andq %rax, %rcx
movabsq $0xf000000000000, %rsi  # imm = 0xF000000000000
andq %rax, %rsi
movabsq $0xff000000000000, %rdi # imm = 0xFF000000000000
andq %rdx, %rdi
orq %rsi, %rdi
movabsq $-0xff000000000001, %rax # imm = 0xFF00FFFFFFFFFFFF
andq %rdx, %rax
orq %rcx, %rax
orq %rdi, %rax
leaq 0x1bfa8f(%rip), %rcx    # 0x2187d4
cmpb $0x0, (%rcx)
movq %rax, %rcx
bswapq %rcx
cmovneq %rax, %rcx
movq %rcx, %xmm0
ucomisd %xmm0, %xmm0
jp 0x58e12
movsd 0xc530f(%rip), %xmm1    # 0x11e078
movl $0x800, %eax            # imm = 0x800
ucomisd %xmm1, %xmm0
ja 0x58d82
movsd 0xc5304(%rip), %xmm1    # 0x11e080
ucomisd %xmm0, %xmm1
jbe 0x58d93
orl %eax, (%rbx)
movapd %xmm1, %xmm0
jmp 0x58d93
cmpl $0x3bcd, %r13d          # imm = 0x3BCD
jae 0x58da2
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %r15d, %edx
andl $-0x80, %edx
leal -0x3c00(%r13), %ecx
cmpl $0x3c00, %r12d          # imm = 0x3C00
jae 0x58dc1
shlq $0x38, %rdx
jmp 0x58cc3
cmpl $0x43ff, %r13d          # imm = 0x43FF
jb 0x58de8
orb $0x7f, %r15b
movzbl %r15b, %ecx
shlq $0x38, %rcx
movabsq $0xf0000000000000, %rax # imm = 0xF0000000000000
orq %rcx, %rax
jmp 0x58d3e
movl %ecx, %r15d
shrl $0x4, %r15d
andb $0x7f, %r15b
orb %dl, %r15b
movzbl %r15b, %r15d
shlq $0x38, %r15
shlb $0x4, %r14b
movzbl %r14b, %edx
shlq $0x30, %rdx
orq %r15, %rdx
jmp 0x58cc3
xorpd %xmm1, %xmm1
movl $0x400, %eax            # imm = 0x400
jmp 0x58d82