#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int M_PI;
int strlen(char *);
char toupper(char);
void gridsquare_to_latlon(char *gs, double *lat, double *lon) {
  *lon = -M_PI + (toupper(gs[0]) - 'A') * ((M_PI / 180) * 20) +
         (gs[2] - '0') * ((M_PI / 180) * 2);
  *lat = -M_PI / 2 + (toupper(gs[1]) - 'A') * ((M_PI / 180) * 10) +
         (gs[3] - '0') * ((M_PI / 180) * 1);
  if (strlen(gs) == 4) {
    *lon += (M_PI / 180) * 1;
    *lat += (M_PI / 180) * .5;
  } else {
    *lon += (toupper(gs[4]) - 'A') * (((M_PI / 180) / 60) * 5);
    *lat += (toupper(gs[5]) - 'A') * (((M_PI / 180) / 60) * 2.5);
    *lon += ((M_PI / 180) / 60) * 2.5;
    *lat += ((M_PI / 180) / 60) * 1.25;
  }
}


x86 assembly (clang, -O0):
<gridsquare_to_latlon>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
xor    %eax,%eax
mov    0x2eab(%rip),%rcx
sub    (%rcx),%eax
mov    %eax,-0x28(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%edi
call   1030 <toupper@plt>
movsbl %al,%ecx
sub    $0x41,%ecx
mov    0x2e8d(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%esi
cltd
idiv   %esi
mov    %eax,%edx
mov    -0x28(%rbp),%eax
imul   $0x14,%edx,%edx
imul   %edx,%ecx
add    %ecx,%eax
mov    %eax,-0x24(%rbp)
mov    -0x8(%rbp),%rax
movsbl 0x2(%rax),%ecx
sub    $0x30,%ecx
mov    0x2e61(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%esi
cltd
idiv   %esi
mov    %eax,%edx
mov    -0x24(%rbp),%eax
shl    $0x1,%edx
imul   %edx,%ecx
add    %ecx,%eax
cvtsi2sd %eax,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
xor    %eax,%eax
mov    0x2e35(%rip),%rcx
sub    (%rcx),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,-0x20(%rbp)
mov    -0x8(%rbp),%rax
movsbl 0x1(%rax),%edi
call   1030 <toupper@plt>
movsbl %al,%ecx
sub    $0x41,%ecx
mov    0x2e0e(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%esi
cltd
idiv   %esi
mov    %eax,%edx
mov    -0x20(%rbp),%eax
imul   $0xa,%edx,%edx
imul   %edx,%ecx
add    %ecx,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movsbl 0x3(%rax),%ecx
sub    $0x30,%ecx
mov    0x2de2(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%esi
cltd
idiv   %esi
mov    %eax,%edx
mov    -0x1c(%rbp),%eax
shl    $0x0,%edx
imul   %edx,%ecx
add    %ecx,%eax
cvtsi2sd %eax,%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x8(%rbp),%rdi
call   1040 <strlen@plt>
cmp    $0x4,%eax
jne    1295 <gridsquare_to_latlon+0x175>
mov    0x2da6(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%ecx
cltd
idiv   %ecx
shl    $0x0,%eax
cvtsi2sd %eax,%xmm0
mov    -0x18(%rbp),%rax
addsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
mov    0x2d82(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%ecx
cltd
idiv   %ecx
cvtsi2sd %eax,%xmm0
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm1
movsd  0xd8c(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
jmp    13a5 <gridsquare_to_latlon+0x285>
mov    -0x8(%rbp),%rax
movsbl 0x4(%rax),%edi
call   1030 <toupper@plt>
movsbl %al,%eax
sub    $0x41,%eax
mov    %eax,-0x2c(%rbp)
mov    0x2d36(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%ecx
cltd
idiv   %ecx
mov    $0x3c,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x2c(%rbp),%eax
imul   $0x5,%ecx,%ecx
imul   %ecx,%eax
cvtsi2sd %eax,%xmm0
mov    -0x18(%rbp),%rax
addsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
mov    -0x8(%rbp),%rax
movsbl 0x5(%rax),%edi
call   1030 <toupper@plt>
movsbl %al,%eax
sub    $0x41,%eax
cvtsi2sd %eax,%xmm0
mov    0x2ceb(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%ecx
cltd
idiv   %ecx
mov    $0x3c,%ecx
cltd
idiv   %ecx
cvtsi2sd %eax,%xmm2
movsd  0xced(%rip),%xmm1
mulsd  %xmm1,%xmm2
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
mov    0x2cae(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%ecx
cltd
idiv   %ecx
mov    $0x3c,%ecx
cltd
idiv   %ecx
cvtsi2sd %eax,%xmm0
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm1
movsd  0xca8(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
mov    0x2c75(%rip),%rax
mov    (%rax),%eax
mov    $0xb4,%ecx
cltd
idiv   %ecx
mov    $0x3c,%ecx
cltd
idiv   %ecx
cvtsi2sd %eax,%xmm0
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm1
movsd  0xc67(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gridsquare_to_latlon>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %rdx,%r15
mov    %rsi,%r14
mov    %rdi,%rbx
mov    0x2eb0(%rip),%r12
mov    (%r12),%ebp
movsbl (%rdi),%edi
call   1030 <toupper@plt>
movsbl %al,%ecx
movslq (%r12),%rax
imul   $0xffffffffb60b60b7,%rax,%rdx
shr    $0x20,%rdx
add    %eax,%edx
mov    %edx,%esi
shr    $0x1f,%esi
sar    $0x7,%edx
add    %esi,%edx
lea    (%rcx,%rcx,4),%ecx
shl    $0x2,%ecx
movsbl 0x2(%rbx),%esi
lea    (%rcx,%rsi,2),%ecx
add    $0xfffffa8c,%ecx
imul   %edx,%ecx
sub    %ebp,%ecx
cvtsi2sd %ecx,%xmm0
movsd  %xmm0,(%r15)
mov    %eax,%ebp
shr    $0x1f,%ebp
add    %eax,%ebp
sar    %ebp
movsbl 0x1(%rbx),%edi
call   1030 <toupper@plt>
movsbl %al,%eax
movslq (%r12),%rcx
imul   $0xffffffffb60b60b7,%rcx,%rdx
shr    $0x20,%rdx
add    %ecx,%edx
mov    %edx,%ecx
shr    $0x1f,%ecx
sar    $0x7,%edx
add    %ecx,%edx
lea    (%rax,%rax,4),%eax
movsbl 0x3(%rbx),%ecx
lea    (%rcx,%rax,2),%eax
add    $0xfffffd46,%eax
imul   %edx,%eax
sub    %ebp,%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movsd  %xmm0,(%r14)
mov    %rbx,%rdi
call   1040 <strlen@plt>
cmp    $0x4,%eax
jne    121d <gridsquare_to_latlon+0xfd>
movslq (%r12),%rax
imul   $0xffffffffb60b60b7,%rax,%rcx
shr    $0x20,%rcx
add    %eax,%ecx
mov    %ecx,%eax
shr    $0x1f,%eax
sar    $0x7,%ecx
add    %eax,%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
movsd  (%r15),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,(%r15)
mulsd  0xdf8(%rip),%xmm0
jmp    12bf <gridsquare_to_latlon+0x19f>
movsbl 0x4(%rbx),%edi
call   1030 <toupper@plt>
movsbl %al,%eax
add    $0xffffffbf,%eax
movslq (%r12),%rcx
imul   $0xffffffffc22e4507,%rcx,%rdx
shr    $0x20,%rdx
add    %ecx,%edx
mov    %edx,%ecx
shr    $0x1f,%ecx
sar    $0xd,%edx
add    %ecx,%edx
imul   %eax,%edx
lea    (%rdx,%rdx,4),%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
addsd  (%r15),%xmm0
movsd  %xmm0,(%r15)
movsbl 0x5(%rbx),%edi
call   1030 <toupper@plt>
movsbl %al,%eax
add    $0xffffffbf,%eax
cvtsi2sd %eax,%xmm1
movslq (%r12),%rax
imul   $0xffffffffc22e4507,%rax,%rcx
shr    $0x20,%rcx
add    %eax,%ecx
mov    %ecx,%eax
shr    $0x1f,%eax
sar    $0xd,%ecx
add    %eax,%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
movsd  0xd65(%rip),%xmm2
mulsd  %xmm0,%xmm2
mulsd  %xmm2,%xmm1
addsd  (%r14),%xmm1
movsd  %xmm1,(%r14)
addsd  (%r15),%xmm2
movsd  %xmm2,(%r15)
mulsd  0xd49(%rip),%xmm0
addsd  (%r14),%xmm0
movsd  %xmm0,(%r14)
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@M_PI = global i32 0
define void @gridsquare_to_latlon(i8* %0, double* %1, double* %2) {
%4 = alloca i8*
%5 = alloca double*
%6 = alloca double*
store i8* %0, i8** %4
store double* %1, double** %5
store double* %2, double** %6
%7 = load i32, i32* @M_PI
%8 = sub nsw i32 0, %7
%9 = load i8*, i8** %4
%10 = getelementptr inbounds i8, i8* %9, i64 0
%11 = load i8, i8* %10
%12 = call signext i8 @toupper(i8 signext %11)
%13 = sext i8 %12 to i32
%14 = sub nsw i32 %13, 65
%15 = load i32, i32* @M_PI
%16 = sdiv i32 %15, 180
%17 = mul nsw i32 %16, 20
%18 = mul nsw i32 %14, %17
%19 = add nsw i32 %8, %18
%20 = load i8*, i8** %4
%21 = getelementptr inbounds i8, i8* %20, i64 2
%22 = load i8, i8* %21
%23 = sext i8 %22 to i32
%24 = sub nsw i32 %23, 48
%25 = load i32, i32* @M_PI
%26 = sdiv i32 %25, 180
%27 = mul nsw i32 %26, 2
%28 = mul nsw i32 %24, %27
%29 = add nsw i32 %19, %28
%30 = sitofp i32 %29 to double
%31 = load double*, double** %6
store double %30, double* %31
%32 = load i32, i32* @M_PI
%33 = sub nsw i32 0, %32
%34 = sdiv i32 %33, 2
%35 = load i8*, i8** %4
%36 = getelementptr inbounds i8, i8* %35, i64 1
%37 = load i8, i8* %36
%38 = call signext i8 @toupper(i8 signext %37)
%39 = sext i8 %38 to i32
%40 = sub nsw i32 %39, 65
%41 = load i32, i32* @M_PI
%42 = sdiv i32 %41, 180
%43 = mul nsw i32 %42, 10
%44 = mul nsw i32 %40, %43
%45 = add nsw i32 %34, %44
%46 = load i8*, i8** %4
%47 = getelementptr inbounds i8, i8* %46, i64 3
%48 = load i8, i8* %47
%49 = sext i8 %48 to i32
%50 = sub nsw i32 %49, 48
%51 = load i32, i32* @M_PI
%52 = sdiv i32 %51, 180
%53 = mul nsw i32 %52, 1
%54 = mul nsw i32 %50, %53
%55 = add nsw i32 %45, %54
%56 = sitofp i32 %55 to double
%57 = load double*, double** %5
store double %56, double* %57
%58 = load i8*, i8** %4
%59 = call i32 @strlen(i8* %58)
%60 = icmp eq i32 %59, 4
br i1 %60, label %61, label %75
61: ; preds = %3
%62 = load i32, i32* @M_PI
%63 = sdiv i32 %62, 180
%64 = mul nsw i32 %63, 1
%65 = sitofp i32 %64 to double
%66 = load double*, double** %6
%67 = load double, double* %66
%68 = fadd double %67, %65
store double %68, double* %66
%69 = load i32, i32* @M_PI
%70 = sdiv i32 %69, 180
%71 = sitofp i32 %70 to double
%72 = load double*, double** %5
%73 = load double, double* %72
%74 = call double @llvm.fmuladd.f64(double %71, double 5.000000e-01, double %73)
store double %74, double* %72
br label %120
75: ; preds = %3
%76 = load i8*, i8** %4
%77 = getelementptr inbounds i8, i8* %76, i64 4
%78 = load i8, i8* %77
%79 = call signext i8 @toupper(i8 signext %78)
%80 = sext i8 %79 to i32
%81 = sub nsw i32 %80, 65
%82 = load i32, i32* @M_PI
%83 = sdiv i32 %82, 180
%84 = sdiv i32 %83, 60
%85 = mul nsw i32 %84, 5
%86 = mul nsw i32 %81, %85
%87 = sitofp i32 %86 to double
%88 = load double*, double** %6
%89 = load double, double* %88
%90 = fadd double %89, %87
store double %90, double* %88
%91 = load i8*, i8** %4
%92 = getelementptr inbounds i8, i8* %91, i64 5
%93 = load i8, i8* %92
%94 = call signext i8 @toupper(i8 signext %93)
%95 = sext i8 %94 to i32
%96 = sub nsw i32 %95, 65
%97 = sitofp i32 %96 to double
%98 = load i32, i32* @M_PI
%99 = sdiv i32 %98, 180
%100 = sdiv i32 %99, 60
%101 = sitofp i32 %100 to double
%102 = fmul double %101, 2.500000e+00
%103 = load double*, double** %5
%104 = load double, double* %103
%105 = call double @llvm.fmuladd.f64(double %97, double %102, double %104)
store double %105, double* %103
%106 = load i32, i32* @M_PI
%107 = sdiv i32 %106, 180
%108 = sdiv i32 %107, 60
%109 = sitofp i32 %108 to double
%110 = load double*, double** %6
%111 = load double, double* %110
%112 = call double @llvm.fmuladd.f64(double %109, double 2.500000e+00, double %111)
store double %112, double* %110
%113 = load i32, i32* @M_PI
%114 = sdiv i32 %113, 180
%115 = sdiv i32 %114, 60
%116 = sitofp i32 %115 to double
%117 = load double*, double** %5
%118 = load double, double* %117
%119 = call double @llvm.fmuladd.f64(double %116, double 1.250000e+00, double %118)
store double %119, double* %117
br label %120
120: ; preds = %75, %61
ret void
}

LLVM IR (-O2):
@M_PI = global i32 0
define void @gridsquare_to_latlon(i8* %0, double* nocapture %1, double* nocapture %2) {
%4 = load i32, i32* @M_PI
%5 = load i8, i8* %0
%6 = tail call signext i8 @toupper(i8 signext %5)
%7 = sext i8 %6 to i32
%8 = load i32, i32* @M_PI
%9 = sdiv i32 %8, 180
%10 = mul nsw i32 %7, 20
%11 = getelementptr inbounds i8, i8* %0, i64 2
%12 = load i8, i8* %11
%13 = sext i8 %12 to i32
%14 = shl nsw i32 %13, 1
%15 = add nsw i32 %14, %10
%16 = add nsw i32 %15, -1396
%17 = mul i32 %16, %9
%18 = sub i32 %17, %4
%19 = sitofp i32 %18 to double
store double %19, double* %2
%20 = sdiv i32 %8, -2
%21 = getelementptr inbounds i8, i8* %0, i64 1
%22 = load i8, i8* %21
%23 = tail call signext i8 @toupper(i8 signext %22)
%24 = sext i8 %23 to i32
%25 = load i32, i32* @M_PI
%26 = sdiv i32 %25, 180
%27 = mul nsw i32 %24, 10
%28 = getelementptr inbounds i8, i8* %0, i64 3
%29 = load i8, i8* %28
%30 = sext i8 %29 to i32
%31 = add nsw i32 %27, %30
%32 = add nsw i32 %31, -698
%33 = mul i32 %32, %26
%34 = add i32 %33, %20
%35 = sitofp i32 %34 to double
store double %35, double* %1
%36 = tail call i32 @strlen(i8* %0)
%37 = icmp eq i32 %36, 4
br i1 %37, label %38, label %46
38: ; preds = %3
%39 = load i32, i32* @M_PI
%40 = sdiv i32 %39, 180
%41 = sitofp i32 %40 to double
%42 = load double, double* %2
%43 = fadd double %42, %41
store double %43, double* %2
%44 = load double, double* %1
%45 = tail call double @llvm.fmuladd.f64(double %41, double 5.000000e-01, double %44)
br label %75
46: ; preds = %3
%47 = getelementptr inbounds i8, i8* %0, i64 4
%48 = load i8, i8* %47
%49 = tail call signext i8 @toupper(i8 signext %48)
%50 = sext i8 %49 to i32
%51 = add nsw i32 %50, -65
%52 = load i32, i32* @M_PI
%53 = sdiv i32 %52, 10800
%54 = mul nsw i32 %53, 5
%55 = mul nsw i32 %54, %51
%56 = sitofp i32 %55 to double
%57 = load double, double* %2
%58 = fadd double %57, %56
store double %58, double* %2
%59 = getelementptr inbounds i8, i8* %0, i64 5
%60 = load i8, i8* %59
%61 = tail call signext i8 @toupper(i8 signext %60)
%62 = sext i8 %61 to i32
%63 = add nsw i32 %62, -65
%64 = sitofp i32 %63 to double
%65 = load i32, i32* @M_PI
%66 = sdiv i32 %65, 10800
%67 = sitofp i32 %66 to double
%68 = fmul double %67, 2.500000e+00
%69 = load double, double* %1
%70 = tail call double @llvm.fmuladd.f64(double %64, double %68, double %69)
store double %70, double* %1
%71 = load double, double* %2
%72 = tail call double @llvm.fmuladd.f64(double %67, double 2.500000e+00, double %71)
store double %72, double* %2
%73 = load double, double* %1
%74 = tail call double @llvm.fmuladd.f64(double %67, double 1.250000e+00, double %73)
br label %75
75: ; preds = %46, %38
%76 = phi double [ %74, %46 ], [ %45, %38 ]
store double %76, double* %1
ret void
}