// File: 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
subq $0x40, %rsp
movb $0x0, -0x9(%rbp)
movzbl -0x9(%rbp), %eax
cmpl $0xa, %eax
jge 0x7aadc
callq 0x7a3f0
movw %ax, -0x1e(%rbp)
movzwl -0x1e(%rbp), %eax
andl $0xff00, %eax           # imm = 0xFF00
cmpl $0x0, %eax
je 0x7aac4
leaq 0x22369d(%rip), %rax    # 0x29e150
movl (%rax), %ecx
orl $0x200, %ecx            # imm = 0x200
leaq 0x22368e(%rip), %rax    # 0x29e150
movl %ecx, (%rax)
movw -0x1e(%rbp), %ax
movb %al, %cl
movzbl -0x9(%rbp), %eax
movb %cl, -0x13(%rbp,%rax)
movb -0x9(%rbp), %al
addb $0x1, %al
movb %al, -0x9(%rbp)
jmp 0x7aa8c
movb $0x0, -0x9(%rbp)
movzbl -0x9(%rbp), %eax
cmpl $0x8, %eax
jge 0x7aafc
movzbl -0x9(%rbp), %eax
movb $0x0, -0x1b(%rbp,%rax)
movb -0x9(%rbp), %al
addb $0x1, %al
movb %al, -0x9(%rbp)
jmp 0x7aae0
movzbl -0xa(%rbp), %eax
shll $0x8, %eax
movzbl -0xb(%rbp), %ecx
orl %ecx, %eax
andl $0x7fff, %eax           # imm = 0x7FFF
movl %eax, -0x24(%rbp)
movzbl -0xc(%rbp), %eax
shlq $0x38, %rax
movzbl -0xd(%rbp), %ecx
shlq $0x30, %rcx
orq %rcx, %rax
movzbl -0xe(%rbp), %ecx
shlq $0x28, %rcx
orq %rcx, %rax
movzbl -0xf(%rbp), %ecx
shlq $0x20, %rcx
orq %rcx, %rax
movzbl -0x10(%rbp), %ecx
shlq $0x18, %rcx
orq %rcx, %rax
movzbl -0x11(%rbp), %ecx
shlq $0x10, %rcx
orq %rcx, %rax
movzbl -0x12(%rbp), %ecx
shlq $0x8, %rcx
orq %rcx, %rax
movzbl -0x13(%rbp), %ecx
orq %rcx, %rax
movq %rax, -0x30(%rbp)
movzbl -0xa(%rbp), %eax
andl $0x80, %eax
movb %al, -0x14(%rbp)
cmpl $0x7fff, -0x24(%rbp)    # imm = 0x7FFF
je 0x7ab81
cmpl $0x0, -0x24(%rbp)
jne 0x7aba9
cmpl $0x7fff, -0x24(%rbp)    # imm = 0x7FFF
jne 0x7ab9a
movzbl -0x14(%rbp), %eax
orl $0x7f, %eax
movb %al, -0x14(%rbp)
movb $-0x10, -0x15(%rbp)
jmp 0x7aba7
xorps %xmm0, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x7ad39
jmp 0x7ac1d
movl -0x24(%rbp), %eax
subl $0x3fff, %eax           # imm = 0x3FFF
addl $0x3ff, %eax            # imm = 0x3FF
movl %eax, -0x24(%rbp)
cmpl $-0x34, -0x24(%rbp)
jg 0x7abcc
xorps %xmm0, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x7ad39
cmpl $0x0, -0x24(%rbp)
jge 0x7abd4
jmp 0x7ac19
cmpl $0x7ff, -0x24(%rbp)     # imm = 0x7FF
jl 0x7abf0
movzbl -0x14(%rbp), %eax
orl $0x7f, %eax
movb %al, -0x14(%rbp)
movb $-0x10, -0x15(%rbp)
jmp 0x7acc2
movl -0x24(%rbp), %ecx
andl $0x7f0, %ecx            # imm = 0x7F0
sarl $0x4, %ecx
movzbl -0x14(%rbp), %eax
orl %ecx, %eax
movb %al, -0x14(%rbp)
movl -0x24(%rbp), %ecx
andl $0xf, %ecx
shll $0x4, %ecx
movzbl -0x15(%rbp), %eax
orl %ecx, %eax
movb %al, -0x15(%rbp)
jmp 0x7ac19
jmp 0x7ac1b
jmp 0x7ac1d
movq -0x30(%rbp), %rax
sarq $0xb, %rax
movq %rax, -0x30(%rbp)
cmpl $0x0, -0x24(%rbp)
jge 0x7ac44
xorl %ecx, %ecx
subl -0x24(%rbp), %ecx
addl $0x1, %ecx
movq -0x30(%rbp), %rax
movl %ecx, %ecx
sarq %cl, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
sarq $0x0, %rax
andq $0xff, %rax
movb %al, -0x1b(%rbp)
movq -0x30(%rbp), %rax
sarq $0x8, %rax
andq $0xff, %rax
movb %al, -0x1a(%rbp)
movq -0x30(%rbp), %rax
sarq $0x10, %rax
andq $0xff, %rax
movb %al, -0x19(%rbp)
movq -0x30(%rbp), %rax
sarq $0x18, %rax
andq $0xff, %rax
movb %al, -0x18(%rbp)
movq -0x30(%rbp), %rax
sarq $0x20, %rax
andq $0xff, %rax
movb %al, -0x17(%rbp)
movq -0x30(%rbp), %rax
sarq $0x28, %rax
andq $0xff, %rax
movb %al, -0x16(%rbp)
movq -0x30(%rbp), %rax
sarq $0x30, %rax
andq $0xf, %rax
movzbl %al, %ecx
movzbl -0x15(%rbp), %eax
orl %ecx, %eax
movb %al, -0x15(%rbp)
leaq 0x1fcceb(%rip), %rax    # 0x2779b4
cmpb $0x0, (%rax)
jne 0x7ad16
movb -0x1b(%rbp), %al
movb %al, -0x9(%rbp)
movb -0x14(%rbp), %al
movb %al, -0x1b(%rbp)
movb -0x9(%rbp), %al
movb %al, -0x14(%rbp)
movb -0x1a(%rbp), %al
movb %al, -0x9(%rbp)
movb -0x15(%rbp), %al
movb %al, -0x1a(%rbp)
movb -0x9(%rbp), %al
movb %al, -0x15(%rbp)
movb -0x19(%rbp), %al
movb %al, -0x9(%rbp)
movb -0x16(%rbp), %al
movb %al, -0x19(%rbp)
movb -0x9(%rbp), %al
movb %al, -0x16(%rbp)
movb -0x18(%rbp), %al
movb %al, -0x9(%rbp)
movb -0x17(%rbp), %al
movb %al, -0x18(%rbp)
movb -0x9(%rbp), %al
movb %al, -0x17(%rbp)
movsd -0x1b(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
movsd -0x38(%rbp), %xmm0
callq 0x7a910
movsd %xmm0, -0x38(%rbp)
movsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movsd -0x8(%rbp), %xmm0
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)