// File: /workspace/github_cpp_makefile_star2_O2/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 $0x20, %rsp
xorl %ebx, %ebx
leaq 0x1d7086(%rip), %r14    # 0x228f70
cmpq $0xa, %rbx
je 0x51f0a
callq 0x51b76
cmpl $0x100, %eax            # imm = 0x100
jb 0x51f01
orb $0x2, 0x1(%r14)
movb %al, -0x22(%rbp,%rbx)
incq %rbx
jmp 0x51eea
xorl %eax, %eax
cmpq $0x8, %rax
je 0x51f1c
movb $0x0, -0x18(%rbp,%rax)
incq %rax
jmp 0x51f0c
movzbl -0x19(%rbp), %r10d
movzbl -0x1a(%rbp), %esi
movl %r10d, %r11d
andl $0x7f, %r11d
shll $0x8, %r11d
movl -0x1e(%rbp), %r9d
movzbl -0x1f(%rbp), %r8d
movzbl -0x20(%rbp), %edi
movzbl -0x21(%rbp), %eax
movl %r10d, %edx
andb $-0x80, %dl
movl %r11d, %ebx
orl %esi, %ebx
movb %dl, -0x11(%rbp)
je 0x5201b
cmpl $0x7fff, %ebx           # imm = 0x7FFF
jne 0x52013
orb $0x7f, %r10b
movb %r10b, -0x11(%rbp)
movl $0x7fff, %ecx           # imm = 0x7FFF
movb $-0x10, %sil
movl %r10d, %edx
shlq $0x20, %r9
shll $0x18, %r8d
orq %r9, %r8
shll $0x10, %edi
orq %r8, %rdi
shll $0x8, %eax
orq %rdi, %rax
sarq $0xb, %rax
pushq $0x1
popq %rdi
subl %ecx, %edi
sarl $0x1f, %ecx
andl %edi, %ecx
sarq %cl, %rax
movb %al, -0x18(%rbp)
movb %ah, -0x17(%rbp)
movl %eax, %ecx
shrl $0x10, %ecx
movb %cl, -0x16(%rbp)
movl %eax, %ecx
shrl $0x18, %ecx
movb %cl, -0x15(%rbp)
movq %rax, %rcx
shrq $0x20, %rcx
movb %cl, -0x14(%rbp)
movq %rax, %rcx
shrq $0x28, %rcx
movb %cl, -0x13(%rbp)
shrq $0x30, %rax
andb $0xf, %al
orb %sil, %al
movb %al, -0x12(%rbp)
leaq 0x1b07fb(%rip), %rcx    # 0x2027d4
cmpb $0x0, (%rcx)
jne 0x52001
movb -0x18(%rbp), %cl
movb %dl, -0x18(%rbp)
movb %cl, -0x11(%rbp)
movzwl -0x17(%rbp), %ecx
rolw $0x8, %cx
movb %al, -0x17(%rbp)
movb -0x13(%rbp), %al
movb %al, -0x16(%rbp)
movw %cx, -0x13(%rbp)
rolw $0x8, -0x15(%rbp)
movsd -0x18(%rbp), %xmm0
addq $0x20, %rsp
popq %rbx
popq %r14
popq %rbp
jmp 0x51e2a
cmpl $0x3bcd, %ebx           # imm = 0x3BCD
jae 0x52027
xorps %xmm0, %xmm0
addq $0x20, %rsp
popq %rbx
popq %r14
popq %rbp
retq
leal -0x3c00(%rbx), %ecx
cmpl $0x3bff, %r11d          # imm = 0x3BFF
ja 0x5203f
movb -0x12(%rbp), %sil
jmp 0x51f74
cmpl $0x43ff, %ebx           # imm = 0x43FF
jb 0x5205d
orb $0x7f, %r10b
movb %r10b, -0x11(%rbp)
movb $-0x10, -0x12(%rbp)
movb $-0x10, %al
movl %r10d, %edx
jmp 0x51fd2
movl %ecx, %r10d
shrl $0x4, %r10d
andb $0x7f, %r10b
orb %dl, %r10b
movb %r10b, -0x11(%rbp)
shlb $0x4, %sil
orb -0x12(%rbp), %sil
jmp 0x51f71