// File: /workspace/github_c_makefile_star2_O0/canboat[P]canboat/n2kd/gps_ais.c
// Function: aisFloat
static long int aisFloat(const char *msg, const char *fieldName)
{
#define DEGREES_PER_RADIAN (57.295779513)
#define SECONDS_PER_MINUTE (60.0)
#define KNOTS_IN_MS (1.943844492)
#define ROT_MULTIPLICATOR (4.733)
#define SOG_MULTIPLICATOR (10.0)
#define COG_MULTIPLICATOR (10.0)
#define NO_MULTIPLICATOR (1.0)
#define LON_MULTIPLICATOR (600000.0)
#define LAT_MULTIPLICATOR (600000.0)
#define SIZE_MULTIPLICATOR (10.0)
#define DRAUGHT_MULTIPLICATOR (10.0)
#define ALTITUDE_MULTIPLICATOR (1.0)

  typedef struct
  {
    const char *value;
    double      min;
    double      max;
    double      defValue;
    double      multiplier;
    Unit        unit;
  } floatParam;

  int      i;
  double   value;
  int      sign;
  long int result;

  floatParam paramRange[] = {{/* Clamp Rate of Turn to -127 .. 127 (which boils down to 720 degs/min)
                               */
                              "Rate of Turn",
                              -127,
                              127,
                              -128,
                              SECONDS_PER_MINUTE},
                             {"SOG", 0, 1022, 1023, KNOTS_IN_MS * SOG_MULTIPLICATOR, U_VELOCITY},
                             {"COG", 0, 3599, 3600, COG_MULTIPLICATOR, U_ANGLE},
                             {"Heading", 0, 359, 511, NO_MULTIPLICATOR, U_ANGLE},
                             {"Longitude", -108000000, 108000000, 0x6791AC0, LON_MULTIPLICATOR, U_GEO},
                             {"Latitude", -54000000, 54000000, 0x3412140, LAT_MULTIPLICATOR, U_GEO},
                             {"Length", 0, 10220, 0, SIZE_MULTIPLICATOR, U_DISTANCE},
                             {"Beam", 0, 1260, 0, SIZE_MULTIPLICATOR, U_DISTANCE},
                             {"Position reference from Starboard", 0, 630, 0, SIZE_MULTIPLICATOR, U_DISTANCE},
                             {"Position reference from Bow", 0, 5110, 0, SIZE_MULTIPLICATOR, U_DISTANCE},
                             {"Draft", 0, 255, 0, DRAUGHT_MULTIPLICATOR, U_DISTANCE},
                             {"True Heading", 0, 359, 511, NO_MULTIPLICATOR},
                             {"Length/Diameter", 0, 10220, 0, SIZE_MULTIPLICATOR, U_DISTANCE},
                             {"Beam/Diameter", 0, 1260, 0, SIZE_MULTIPLICATOR, U_DISTANCE},
                             {"Position Reference from Starboard Edge", 0, 630, 0, SIZE_MULTIPLICATOR, U_DISTANCE},
                             {"Position Reference from True North Facing Edge", 0, 5110, 0, SIZE_MULTIPLICATOR, U_DISTANCE},
                             {"Altitude", 0, 4094, 4095, ALTITUDE_MULTIPLICATOR, U_DISTANCE}};

  for (i = 0; i < ARRAY_SIZE(paramRange); i++)
  {
    if (!strcmp(fieldName, paramRange[i].value))
    {
      break;
    }
  }
  if (i == ARRAY_SIZE(paramRange))
  {
    logAbort("Unhandled AIS number field '%s'; please report this bug\n", fieldName);
  }

  if (!getJSONNumber(msg, fieldName, &value, paramRange[i].unit))
  {
    return paramRange[i].defValue;
  }
  value *= paramRange[i].multiplier;
  sign = (value >= 0) - (value < 0);
  value *= sign;
  if (i == 0)
  {
    // ROT is calculated with a non-linear value in ITU-R M.1371...
    result = (long int) (ROT_MULTIPLICATOR * sqrt(value) + 0.5);
    result = CB_MAX(result, paramRange[i].min);
    result = CB_MIN(result, paramRange[i].max);
    logDebug("ROT %f deg/min -> %d\n", value, result);
  }
  else
  {
    result = (long int) (value + 0.5);
  }
  result *= sign;
  // Make sure values are valid
  if (result != paramRange[i].defValue && (result < paramRange[i].min || result > paramRange[i].max))
  {
    result = paramRange[i].defValue;
  }

  logDebug("aisFloat %s = %f = %d\n", fieldName, value, result);
  return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x380, %rsp            # imm = 0x380
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
leaq -0x370(%rbp), %rdi
leaq 0x8d6f(%rip), %rsi      # 0x10aa0
movl $0x330, %edx            # imm = 0x330
callq 0x2220
movl $0x0, -0x1c(%rbp)
movslq -0x1c(%rbp), %rax
cmpq $0x11, %rax
jae 0x7d7e
movq -0x18(%rbp), %rdi
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rsi
callq 0x21f0
cmpl $0x0, %eax
jne 0x7d71
jmp 0x7d7e
jmp 0x7d73
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x7d42
movslq -0x1c(%rbp), %rax
cmpq $0x11, %rax
jne 0x7d9a
movq -0x18(%rbp), %rsi
leaq 0x57b3(%rip), %rdi      # 0xd546
movb $0x0, %al
callq 0x9c40
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movl 0x28(%rax), %ecx
leaq -0x28(%rbp), %rdx
callq 0x9750
testb $0x1, %al
jne 0x7de5
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
cvttsd2si 0x18(%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x8016
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movsd 0x20(%rax), %xmm0
mulsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x28(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
setae %al
andb $0x1, %al
movzbl %al, %eax
xorps %xmm0, %xmm0
ucomisd -0x28(%rbp), %xmm0
seta %cl
andb $0x1, %cl
movzbl %cl, %ecx
subl %ecx, %eax
movl %eax, -0x2c(%rbp)
cvtsi2sdl -0x2c(%rbp), %xmm0
mulsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
cmpl $0x0, -0x1c(%rbp)
jne 0x7f4f
movsd -0x28(%rbp), %xmm0
callq 0x2350
movsd 0x5215(%rip), %xmm1     # 0xd070
mulsd %xmm1, %xmm0
movsd 0x5201(%rip), %xmm1     # 0xd068
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x38(%rbp)
cvtsi2sdq -0x38(%rbp), %xmm0
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
ucomisd 0x8(%rax), %xmm0
jbe 0x7ea3
cvtsi2sdq -0x38(%rbp), %xmm0
movsd %xmm0, -0x378(%rbp)
jmp 0x7ec2
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x378(%rbp)
movsd -0x378(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x38(%rbp)
cvtsi2sdq -0x38(%rbp), %xmm1
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x7f06
cvtsi2sdq -0x38(%rbp), %xmm0
movsd %xmm0, -0x380(%rbp)
jmp 0x7f25
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0x380(%rbp)
movsd -0x380(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x38(%rbp)
movsd -0x28(%rbp), %xmm0
movq -0x38(%rbp), %rsi
leaq 0x5639(%rip), %rdi      # 0xd57f
movb $0x1, %al
callq 0x9ae0
jmp 0x7f65
movsd 0x5111(%rip), %xmm0     # 0xd068
addsd -0x28(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x38(%rbp)
movslq -0x2c(%rbp), %rax
imulq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
cvtsi2sdq -0x38(%rbp), %xmm0
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
ucomisd 0x18(%rax), %xmm0
jne 0x7f95
jp 0x7f95
jmp 0x7ff3
cvtsi2sdq -0x38(%rbp), %xmm1
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
ucomisd %xmm1, %xmm0
ja 0x7fd7
cvtsi2sdq -0x38(%rbp), %xmm0
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
ucomisd 0x10(%rax), %xmm0
jbe 0x7ff3
movslq -0x1c(%rbp), %rcx
leaq -0x370(%rbp), %rax
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
cvttsd2si 0x18(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rsi
movsd -0x28(%rbp), %xmm0
movq -0x38(%rbp), %rdx
leaq 0x558e(%rip), %rdi      # 0xd595
movb $0x1, %al
callq 0x9ae0
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x380, %rsp            # imm = 0x380
popq %rbp
retq
nopw %cs:(%rax,%rax)