void nnmath_translate(int window_x, int window_y, int window_width,
                      int window_height, int image_width, int image_height,
                      int *image_x, int *image_y) {
  float height_ratio = (float)window_height / image_height;
  float width_ratio = (float)window_width / image_width;
  float ratio_to_use = height_ratio > width_ratio ? width_ratio : height_ratio;
  int offset_x = 0;
  int offset_y = 0;
  if (height_ratio > width_ratio) {
    offset_y = (int)((window_height - ratio_to_use * image_height) / 2);
  } else {
    offset_x = (int)((window_width - ratio_to_use * image_width) / 2);
  }
  *image_x = (int)((window_x - offset_x) / ratio_to_use);
  *image_y = (int)((window_y - offset_y) / ratio_to_use);
}


x86 assembly (clang, -O0):
<nnmath_translate>:
push   %rbp
mov    %rsp,%rbp
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%rax
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    %ecx,-0x10(%rbp)
mov    %r8d,-0x14(%rbp)
mov    %r9d,-0x18(%rbp)
cvtsi2ssl -0x10(%rbp),%xmm0
cvtsi2ssl -0x18(%rbp),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,-0x1c(%rbp)
cvtsi2ssl -0xc(%rbp),%xmm0
cvtsi2ssl -0x14(%rbp),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,-0x20(%rbp)
movss  -0x1c(%rbp),%xmm0
ucomiss -0x20(%rbp),%xmm0
jbe    1164 <nnmath_translate+0x64>
movss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
jmp    116e <nnmath_translate+0x6e>
movss  -0x1c(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0x30(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
movl   $0x0,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
movss  -0x1c(%rbp),%xmm0
ucomiss -0x20(%rbp),%xmm0
jbe    11d1 <nnmath_translate+0xd1>
cvtsi2ssl -0x10(%rbp),%xmm1
movss  -0x24(%rbp),%xmm0
cvtsi2ssl -0x18(%rbp),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  0xe3f(%rip),%xmm1
divss  %xmm1,%xmm0
cvttss2si %xmm0,%eax
mov    %eax,-0x2c(%rbp)
jmp    1208 <nnmath_translate+0x108>
cvtsi2ssl -0xc(%rbp),%xmm1
movss  -0x24(%rbp),%xmm0
cvtsi2ssl -0x14(%rbp),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  0xe03(%rip),%xmm1
divss  %xmm1,%xmm0
cvttss2si %xmm0,%eax
mov    %eax,-0x28(%rbp)
mov    -0x4(%rbp),%eax
sub    -0x28(%rbp),%eax
cvtsi2ss %eax,%xmm0
divss  -0x24(%rbp),%xmm0
cvttss2si %xmm0,%ecx
mov    0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x8(%rbp),%eax
sub    -0x2c(%rbp),%eax
cvtsi2ss %eax,%xmm0
divss  -0x24(%rbp),%xmm0
cvttss2si %xmm0,%ecx
mov    0x18(%rbp),%rax
mov    %ecx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<nnmath_translate>:
mov    0x10(%rsp),%r10
movd   %edx,%xmm0
movd   %ecx,%xmm1
punpckldq %xmm0,%xmm1
cvtdq2ps %xmm1,%xmm1
movd   %r8d,%xmm0
movd   %r9d,%xmm2
punpckldq %xmm0,%xmm2
cvtdq2ps %xmm2,%xmm3
movaps %xmm1,%xmm2
divps  %xmm3,%xmm2
movaps %xmm2,%xmm0
shufps $0x55,%xmm2,%xmm0
ucomiss %xmm0,%xmm2
mov    0x8(%rsp),%rcx
minss  %xmm2,%xmm0
movaps 0xebb(%rip),%xmm2
xorps  %xmm0,%xmm2
jbe    1162 <nnmath_translate+0x62>
mulss  %xmm3,%xmm2
addss  %xmm1,%xmm2
mulss  0xeb6(%rip),%xmm2
cvttss2si %xmm2,%edx
xor    %eax,%eax
jmp    1180 <nnmath_translate+0x80>
shufps $0x55,%xmm1,%xmm1
shufps $0x55,%xmm3,%xmm3
mulss  %xmm3,%xmm2
addss  %xmm1,%xmm2
mulss  0xe96(%rip),%xmm2
cvttss2si %xmm2,%eax
xor    %edx,%edx
sub    %eax,%edi
xorps  %xmm1,%xmm1
cvtsi2ss %edi,%xmm1
divss  %xmm0,%xmm1
cvttss2si %xmm1,%eax
mov    %eax,(%rcx)
sub    %edx,%esi
xorps  %xmm1,%xmm1
cvtsi2ss %esi,%xmm1
divss  %xmm0,%xmm1
cvttss2si %xmm1,%eax
mov    %eax,(%r10)
ret

LLVM IR (-O0):
define void @nnmath_translate(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32* %6, i32* %7) {
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32*
%16 = alloca i32*
%17 = alloca float
%18 = alloca float
%19 = alloca float
%20 = alloca i32
%21 = alloca i32
store i32 %0, i32* %9
store i32 %1, i32* %10
store i32 %2, i32* %11
store i32 %3, i32* %12
store i32 %4, i32* %13
store i32 %5, i32* %14
store i32* %6, i32** %15
store i32* %7, i32** %16
%22 = load i32, i32* %12
%23 = sitofp i32 %22 to float
%24 = load i32, i32* %14
%25 = sitofp i32 %24 to float
%26 = fdiv float %23, %25
store float %26, float* %17
%27 = load i32, i32* %11
%28 = sitofp i32 %27 to float
%29 = load i32, i32* %13
%30 = sitofp i32 %29 to float
%31 = fdiv float %28, %30
store float %31, float* %18
%32 = load float, float* %17
%33 = load float, float* %18
%34 = fcmp ogt float %32, %33
br i1 %34, label %35, label %37
35: ; preds = %8
%36 = load float, float* %18
br label %39
37: ; preds = %8
%38 = load float, float* %17
br label %39
39: ; preds = %37, %35
%40 = phi float [ %36, %35 ], [ %38, %37 ]
store float %40, float* %19
store i32 0, i32* %20
store i32 0, i32* %21
%41 = load float, float* %17
%42 = load float, float* %18
%43 = fcmp ogt float %41, %42
br i1 %43, label %44, label %54
44: ; preds = %39
%45 = load i32, i32* %12
%46 = sitofp i32 %45 to float
%47 = load float, float* %19
%48 = load i32, i32* %14
%49 = sitofp i32 %48 to float
%50 = fneg float %47
%51 = call float @llvm.fmuladd.f32(float %50, float %49, float %46)
%52 = fdiv float %51, 2.000000e+00
%53 = fptosi float %52 to i32
store i32 %53, i32* %21
br label %64
54: ; preds = %39
%55 = load i32, i32* %11
%56 = sitofp i32 %55 to float
%57 = load float, float* %19
%58 = load i32, i32* %13
%59 = sitofp i32 %58 to float
%60 = fneg float %57
%61 = call float @llvm.fmuladd.f32(float %60, float %59, float %56)
%62 = fdiv float %61, 2.000000e+00
%63 = fptosi float %62 to i32
store i32 %63, i32* %20
br label %64
64: ; preds = %54, %44
%65 = load i32, i32* %9
%66 = load i32, i32* %20
%67 = sub nsw i32 %65, %66
%68 = sitofp i32 %67 to float
%69 = load float, float* %19
%70 = fdiv float %68, %69
%71 = fptosi float %70 to i32
%72 = load i32*, i32** %15
store i32 %71, i32* %72
%73 = load i32, i32* %10
%74 = load i32, i32* %21
%75 = sub nsw i32 %73, %74
%76 = sitofp i32 %75 to float
%77 = load float, float* %19
%78 = fdiv float %76, %77
%79 = fptosi float %78 to i32
%80 = load i32*, i32** %16
store i32 %79, i32* %80
ret void
}

LLVM IR (-O2):
define void @nnmath_translate(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32* nocapture writeonly %6, i32* nocapture writeonly %7) {
%9 = insertelement <2 x i32> poison, i32 %3, i64 0
%10 = insertelement <2 x i32> %9, i32 %2, i64 1
%11 = sitofp <2 x i32> %10 to <2 x float>
%12 = insertelement <2 x i32> poison, i32 %5, i64 0
%13 = insertelement <2 x i32> %12, i32 %4, i64 1
%14 = sitofp <2 x i32> %13 to <2 x float>
%15 = fdiv <2 x float> %11, %14
%16 = extractelement <2 x float> %15, i64 0
%17 = extractelement <2 x float> %15, i64 1
%18 = fcmp ogt float %16, %17
%19 = select i1 %18, float %17, float %16
%20 = fneg float %19
br i1 %18, label %21, label %27
21: ; preds = %8
%22 = extractelement <2 x float> %11, i64 0
%23 = extractelement <2 x float> %14, i64 0
%24 = tail call float @llvm.fmuladd.f32(float %20, float %23, float %22)
%25 = fmul float %24, 5.000000e-01
%26 = fptosi float %25 to i32
br label %33
27: ; preds = %8
%28 = extractelement <2 x float> %11, i64 1
%29 = extractelement <2 x float> %14, i64 1
%30 = tail call float @llvm.fmuladd.f32(float %20, float %29, float %28)
%31 = fmul float %30, 5.000000e-01
%32 = fptosi float %31 to i32
br label %33
33: ; preds = %27, %21
%34 = phi i32 [ 0, %21 ], [ %32, %27 ]
%35 = phi i32 [ %26, %21 ], [ 0, %27 ]
%36 = sub nsw i32 %0, %34
%37 = sitofp i32 %36 to float
%38 = fdiv float %37, %19
%39 = fptosi float %38 to i32
store i32 %39, i32* %6
%40 = sub nsw i32 %1, %35
%41 = sitofp i32 %40 to float
%42 = fdiv float %41, %19
%43 = fptosi float %42 to i32
store i32 %43, i32* %7
ret void
}