user: Translate the below assembly code into C programming language:

```asm
<checkQthToCoords>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  movsd  %xmm0,-0x40(%rbp)
  movsd  %xmm1,-0x48(%rbp)
  movsd  %xmm2,-0x50(%rbp)
  mov    %rcx,-0x58(%rbp)
  mov    %r8,-0x60(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0x58(%rbp),%rax
  mov    (%rax),%rax
  lea    0x1(%rax),%rdx
  mov    -0x58(%rbp),%rax
  mov    %rdx,(%rax)
  movq   $0x0,-0x20(%rbp)
  movsd  D50(%rip),%xmm0
  movsd  %xmm0,-0x18(%rbp)
  movsd  D50(%rip),%xmm0
  movsd  %xmm0,-0x10(%rbp)
  lea    -0x20(%rbp),%rdi
  lea    -0x10(%rbp),%rcx
  lea    -0x18(%rbp),%rdx
  mov    -0x30(%rbp),%rsi
  mov    -0x28(%rbp),%rax
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <qth_to_coords@plt>
  test   %rax,%rax
  je     L45
  mov    -0x30(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  lea    D90(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  lea    D161(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  jmp    L38
L45:
  mov    -0x20(%rbp),%rax
  cmp    %rax,-0x38(%rbp)
  je     L56
  mov    -0x30(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  lea    D90(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x20(%rbp),%rax
  mov    -0x38(%rbp),%rdx
  mov    %rax,%rsi
  lea    D150(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L38
L56:
  movsd  -0x50(%rbp),%xmm0
  movsd  D75(%rip),%xmm1
  divsd  %xmm1,%xmm0
  movapd %xmm0,%xmm1
  addsd  -0x40(%rbp),%xmm1
  movsd  D3(%rip),%xmm0
  addsd  %xmm0,%xmm1
  movsd  -0x18(%rbp),%xmm0
  comisd %xmm1,%xmm0
  ja     L84
  movsd  -0x50(%rbp),%xmm0
  movsd  D75(%rip),%xmm2
  movapd %xmm0,%xmm1
  divsd  %xmm2,%xmm1
  movsd  -0x40(%rbp),%xmm0
  subsd  %xmm1,%xmm0
  movsd  D3(%rip),%xmm1
  subsd  %xmm1,%xmm0
  movsd  -0x18(%rbp),%xmm1
  comisd %xmm1,%xmm0
  jbe    L28
L84:
  mov    -0x30(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  lea    D90(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  movsd  -0x50(%rbp),%xmm0
  movsd  D75(%rip),%xmm2
  movapd %xmm0,%xmm1
  divsd  %xmm2,%xmm1
  movsd  D3(%rip),%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x18(%rbp),%rax
  movsd  -0x40(%rbp),%xmm0
  movapd %xmm1,%xmm2
  movapd %xmm0,%xmm1
  movq   %rax,%xmm0
  lea    D87(%rip),%rax
  mov    %rax,%rdi
  mov    $0x3,%eax
  call   <printf@plt>
  jmp    L38
L28:
  movsd  -0x48(%rbp),%xmm0
  movapd %xmm0,%xmm1
  addsd  -0x50(%rbp),%xmm1
  movsd  D3(%rip),%xmm0
  addsd  %xmm0,%xmm1
  movsd  -0x10(%rbp),%xmm0
  comisd %xmm1,%xmm0
  ja     L41
  movsd  -0x48(%rbp),%xmm0
  subsd  -0x50(%rbp),%xmm0
  movsd  D3(%rip),%xmm1
  subsd  %xmm1,%xmm0
  movsd  -0x10(%rbp),%xmm1
  comisd %xmm1,%xmm0
  jbe    L77
L41:
  mov    -0x30(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  lea    D90(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  movsd  -0x50(%rbp),%xmm1
  movsd  D3(%rip),%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x10(%rbp),%rax
  movsd  -0x48(%rbp),%xmm0
  movapd %xmm1,%xmm2
  movapd %xmm0,%xmm1
  movq   %rax,%xmm0
  lea    D173(%rip),%rax
  mov    %rax,%rdi
  mov    $0x3,%eax
  call   <printf@plt>
  jmp    L38
L77:
  mov    -0x60(%rbp),%rax
  mov    (%rax),%rax
  lea    0x1(%rax),%rdx
  mov    -0x60(%rbp),%rax
  mov    %rdx,(%rax)
  nop
L38:
  mov    -0x8(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L67
  call   <__stack_chk_fail@plt>
L67:
  leave
  ret
```

tool_calls: name: disassemble_data
arguments: label: D50
type: byte[8]
name: disassemble_data
arguments: label: D90
type: string
name: disassemble_data
arguments: label: D161
type: string
name: disassemble_data
arguments: label: D150
type: string
name: disassemble_data
arguments: label: D75
type: byte[8]
name: disassemble_data
arguments: label: D3
type: f64
name: disassemble_data
arguments: label: D87
type: string
name: disassemble_data
arguments: label: D173
type: string

tool: {"D50": [0x00,0x00,0x00,0x00,0x00,0xc0,0x72,0xc0]}

tool: D90: Test failed: qth_to_coords( "%s", %lu, &lat, &lng, &precision):


tool: D161: 	Invalid test sample.

tool: D150: 	Bad precision, got %lu, expected %lu. 


tool: {"D75": [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40]}

tool: D3: 1e-06

tool: D87: 	Latitude out of acceptable range: got %f, expected %f +/- %f.


tool: D173: 	Longitude out of acceptable range: got %f, expected %f +/- %f.


assistant: ```c
void checkQthToCoords(const char *qth, size_t qthStringSize, size_t expectedPrecisionLvl, double expectedLat, double expectedLng, double acceptedBias, size_t *takenTests, size_t *passedTests) {
  ++(*takenTests);
  size_t precision = 0;
  double lat = -300;
  double lng = -300;
  if (qth_to_coords(qth, qthStringSize, &lat, &lng, &precision) != 0) {
    printf("Test failed: qth_to_coords( \"%s\", %lu, &lat, &lng, &precision):\n", qth, qthStringSize);
    printf("\tInvalid test sample.\n");
    return;
  }
  if (precision != expectedPrecisionLvl) {
    printf("Test failed: qth_to_coords( \"%s\", %lu, &lat, &lng, &precision):\n", qth, qthStringSize);
    printf("\tBad precision, got %lu, expected %lu. \n", precision, expectedPrecisionLvl);
    return;
  }
  if (lat > (expectedLat + (acceptedBias / 2) + 0.000001) || lat < (expectedLat - (acceptedBias / 2) - 0.000001)) {
    printf("Test failed: qth_to_coords( \"%s\", %lu, &lat, &lng, &precision):\n", qth, qthStringSize);
    printf("\tLatitude out of acceptable range: got %f, expected %f +/- %f.\n", lat, expectedLat, (acceptedBias / 2) + 0.000001);
    return;
  }
  if (lng > (expectedLng + acceptedBias + 0.000001) || lng < (expectedLng - acceptedBias - 0.000001)) {
    printf("Test failed: qth_to_coords( \"%s\", %lu, &lat, &lng, &precision):\n", qth, qthStringSize);
    printf("\tLongitude out of acceptable range: got %f, expected %f +/- %f.\n", lng, expectedLng, acceptedBias + 0.000001);
    return;
  }
  ++(*passedTests);
  return;
}
```