double jn(n, x)
double x;
{
  extern double j0(), j1();
  if (n < 0) {
    n = -n;
    x = -x;
  }
  if (n == 0)
    return j0(x);
  if (n == 1)
    return j1(x);
  if (x > n) {
    double jn2 = j0(x), jn1 = j1(x);
    register int i;
    for (i = 1; i < n; i++) {
      double tmp = jn1;
      jn1 = (2 * i) * jn1 / x - jn2;
      jn2 = tmp;
    }
    return jn1;
  }
  {
    register int i;
    double quotient = 0.0;
    double xsqr = x * x;
    double jn1, jn2;
    for (i = 20; i > 0; i--) {
      quotient = xsqr / (2 * (i + n) - quotient);
    }
    quotient = x / (2 * n - quotient);
    jn1 = quotient;
    jn2 = 1.0;
    for (i = n - 1; i > 0; i--) {
      double tmp = jn2;
      jn2 = (2 * i) * jn2 / x - jn1;
      jn1 = tmp;
    }
    return j0(x) * quotient / jn2;
  }
}


x86 assembly (clang, -O0):
<jn>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %edi,-0xc(%rbp)
movsd  %xmm0,-0x18(%rbp)
cmpl   $0x0,-0xc(%rbp)
jge    1163 <jn+0x43>
xor    %eax,%eax
sub    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movsd  -0x18(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x18(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    1183 <jn+0x63>
movsd  -0x18(%rbp),%xmm0
mov    $0x1,%al
call   1040 <j0@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    1333 <jn+0x213>
cmpl   $0x1,-0xc(%rbp)
jne    11a3 <jn+0x83>
movsd  -0x18(%rbp),%xmm0
mov    $0x1,%al
call   1030 <j1@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    1333 <jn+0x213>
movsd  -0x18(%rbp),%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
ucomisd %xmm1,%xmm0
jbe    123b <jn+0x11b>
movsd  -0x18(%rbp),%xmm0
mov    $0x1,%al
call   1040 <j0@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
mov    $0x1,%al
call   1030 <j1@plt>
movsd  %xmm0,-0x28(%rbp)
movl   $0x1,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    122c <jn+0x10c>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x2c(%rbp),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm0
mulsd  -0x28(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
subsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    11e0 <jn+0xc0>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1333 <jn+0x213>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x18(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movl   $0x14,-0x3c(%rbp)
cmpl   $0x0,-0x3c(%rbp)
jle    1291 <jn+0x171>
movsd  -0x50(%rbp),%xmm0
mov    -0x3c(%rbp),%eax
add    -0xc(%rbp),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm1
subsd  -0x48(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x3c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x3c(%rbp)
jmp    1259 <jn+0x139>
movsd  -0x18(%rbp),%xmm0
mov    -0xc(%rbp),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm1
subsd  -0x48(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  0xd40(%rip),%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x3c(%rbp)
cmpl   $0x0,-0x3c(%rbp)
jle    1318 <jn+0x1f8>
movsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x3c(%rbp),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm0
mulsd  -0x60(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
subsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x3c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x3c(%rbp)
jmp    12ce <jn+0x1ae>
movsd  -0x18(%rbp),%xmm0
mov    $0x1,%al
call   1040 <j0@plt>
mulsd  -0x48(%rbp),%xmm0
divsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<jn>:
push   %rbx
sub    $0x20,%rsp
test   %edi,%edi
jns    1131 <jn+0x11>
xorpd  0xecf(%rip),%xmm0
mov    %edi,%ebx
neg    %ebx
cmovs  %edi,%ebx
cmp    $0x1,%ebx
je     114d <jn+0x2d>
test   %ebx,%ebx
jne    1159 <jn+0x39>
mov    $0x1,%al
add    $0x20,%rsp
pop    %rbx
jmp    1040 <j0@plt>
mov    $0x1,%al
add    $0x20,%rsp
pop    %rbx
jmp    1030 <j1@plt>
cvtsi2sd %ebx,%xmm1
ucomisd %xmm1,%xmm0
jbe    11bd <jn+0x9d>
mov    $0x1,%al
movapd %xmm0,0x10(%rsp)
call   1040 <j0@plt>
movsd  %xmm0,0x8(%rsp)
movapd 0x10(%rsp),%xmm0
mov    $0x1,%al
call   1030 <j1@plt>
movapd %xmm0,%xmm3
cmp    $0x2,%ebx
jl     1369 <jn+0x249>
lea    -0x1(%rbx),%eax
cmp    $0x2,%ebx
jne    127a <jn+0x15a>
movsd  0xe74(%rip),%xmm0
movapd 0x10(%rsp),%xmm2
movsd  0x8(%rsp),%xmm4
test   $0x1,%al
jne    12db <jn+0x1bb>
jmp    1369 <jn+0x249>
movapd %xmm0,%xmm3
mulsd  %xmm0,%xmm3
lea    (%rbx,%rbx,1),%eax
add    $0x26,%eax
xorpd  %xmm1,%xmm1
mov    $0xffffffec,%ecx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
lea    0x2(%rax),%edx
xorps  %xmm2,%xmm2
cvtsi2sd %edx,%xmm2
subsd  %xmm1,%xmm2
movapd %xmm3,%xmm1
divsd  %xmm2,%xmm1
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
subsd  %xmm1,%xmm2
movapd %xmm3,%xmm1
divsd  %xmm2,%xmm1
add    $0xfffffffc,%eax
add    $0x2,%ecx
jne    11e0 <jn+0xc0>
lea    (%rbx,%rbx,1),%eax
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
subsd  %xmm1,%xmm2
movapd %xmm0,%xmm4
divsd  %xmm2,%xmm4
cmp    $0x2,%ebx
movsd  %xmm4,0x10(%rsp)
jl     126d <jn+0x14d>
test   $0x1,%bl
jne    12ec <jn+0x1cc>
lea    (%rbx,%rbx,1),%eax
add    $0xfffffffe,%eax
xorps  %xmm3,%xmm3
cvtsi2sd %eax,%xmm3
lea    -0x1(%rbx),%eax
divsd  %xmm0,%xmm3
subsd  %xmm4,%xmm3
movsd  0xdb5(%rip),%xmm1
movapd %xmm3,%xmm5
cmp    $0x2,%ebx
jne    12ff <jn+0x1df>
jmp    134c <jn+0x22c>
movsd  0xd9b(%rip),%xmm5
jmp    134c <jn+0x22c>
mov    %eax,%edx
and    $0xfffffffe,%edx
mov    $0x4,%ecx
movapd 0x10(%rsp),%xmm2
movsd  0x8(%rsp),%xmm4
movapd %xmm4,%xmm0
movapd %xmm3,%xmm1
lea    -0x2(%rcx),%esi
xorps  %xmm4,%xmm4
cvtsi2sd %esi,%xmm4
mulsd  %xmm3,%xmm4
divsd  %xmm2,%xmm4
subsd  %xmm0,%xmm4
xorps  %xmm3,%xmm3
cvtsi2sd %ecx,%xmm3
mulsd  %xmm4,%xmm3
divsd  %xmm2,%xmm3
subsd  %xmm1,%xmm3
add    $0x4,%ecx
add    $0xfffffffe,%edx
jne    1290 <jn+0x170>
add    $0xfffffffe,%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
test   $0x1,%al
je     1369 <jn+0x249>
mulsd  %xmm0,%xmm3
divsd  %xmm2,%xmm3
subsd  %xmm4,%xmm3
jmp    1369 <jn+0x249>
movsd  0xd1c(%rip),%xmm3
mov    %ebx,%eax
movapd %xmm4,%xmm1
cmp    $0x2,%ebx
je     134c <jn+0x22c>
lea    (%rax,%rax,1),%ecx
add    $0xfffffffc,%ecx
add    $0x1,%eax
nopl   0x0(%rax,%rax,1)
lea    0x2(%rcx),%edx
xorps  %xmm2,%xmm2
cvtsi2sd %edx,%xmm2
mulsd  %xmm3,%xmm2
divsd  %xmm0,%xmm2
subsd  %xmm1,%xmm2
xorps  %xmm5,%xmm5
cvtsi2sd %ecx,%xmm5
mulsd  %xmm2,%xmm5
divsd  %xmm0,%xmm5
subsd  %xmm3,%xmm5
add    $0xfffffffc,%ecx
add    $0xfffffffe,%eax
movapd %xmm5,%xmm3
movapd %xmm2,%xmm1
cmp    $0x2,%eax
ja     1310 <jn+0x1f0>
movsd  %xmm5,0x8(%rsp)
mov    $0x1,%al
call   1040 <j0@plt>
movsd  0x10(%rsp),%xmm3
mulsd  %xmm0,%xmm3
divsd  0x8(%rsp),%xmm3
movapd %xmm3,%xmm0
add    $0x20,%rsp
pop    %rbx
ret

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

LLVM IR (-O2):
define double @jn(i32 %0, double %1) {
%3 = icmp slt i32 %0, 0
%4 = sub nsw i32 0, %0
%5 = fneg double %1
%6 = select i1 %3, double %5, double %1
%7 = select i1 %3, i32 %4, i32 %0
switch i32 %7, label %12 [
i32 0, label %8
i32 1, label %10
]
8: ; preds = %2
%9 = tail call double (double, ...) bitcast (double (...)* @j0 to double (double, ...)*)(double %6)
br label %118
10: ; preds = %2
%11 = tail call double (double, ...) bitcast (double (...)* @j1 to double (double, ...)*)(double %6)
br label %118
12: ; preds = %2
%13 = sitofp i32 %7 to double
%14 = fcmp ogt double %6, %13
br i1 %14, label %15, label %44
15: ; preds = %12
%16 = tail call double (double, ...) bitcast (double (...)* @j0 to double (double, ...)*)(double %6)
%17 = tail call double (double, ...) bitcast (double (...)* @j1 to double (double, ...)*)(double %6)
%18 = icmp sgt i32 %7, 1
br i1 %18, label %19, label %118
19: ; preds = %15
%20 = add nsw i32 %7, -1
%21 = and i32 %20, 1
%22 = icmp eq i32 %7, 2
br i1 %22, label %108, label %23
23: ; preds = %19
%24 = and i32 %20, -2
br label %25
25: ; preds = %25, %23
%26 = phi i32 [ 1, %23 ], [ %41, %25 ]
%27 = phi double [ %17, %23 ], [ %40, %25 ]
%28 = phi double [ %16, %23 ], [ %34, %25 ]
%29 = phi i32 [ 0, %23 ], [ %42, %25 ]
%30 = shl nuw nsw i32 %26, 1
%31 = sitofp i32 %30 to double
%32 = fmul double %27, %31
%33 = fdiv double %32, %6
%34 = fsub double %33, %28
%35 = shl nuw i32 %26, 1
%36 = add i32 %35, 2
%37 = sitofp i32 %36 to double
%38 = fmul double %34, %37
%39 = fdiv double %38, %6
%40 = fsub double %39, %27
%41 = add nuw nsw i32 %26, 2
%42 = add i32 %29, 2
%43 = icmp eq i32 %42, %24
br i1 %43, label %105, label %25
44: ; preds = %12
%45 = fmul double %6, %6
br label %46
46: ; preds = %46, %44
%47 = phi double [ 0.000000e+00, %44 ], [ %59, %46 ]
%48 = phi i32 [ 20, %44 ], [ %60, %46 ]
%49 = add nuw nsw i32 %48, %7
%50 = shl nsw i32 %49, 1
%51 = sitofp i32 %50 to double
%52 = fsub double %51, %47
%53 = fdiv double %45, %52
%54 = add nsw i32 %48, -1
%55 = add nuw nsw i32 %54, %7
%56 = shl nsw i32 %55, 1
%57 = sitofp i32 %56 to double
%58 = fsub double %57, %53
%59 = fdiv double %45, %58
%60 = add nsw i32 %48, -2
%61 = icmp eq i32 %54, 1
br i1 %61, label %62, label %46
62: ; preds = %46
%63 = shl nuw nsw i32 %7, 1
%64 = sitofp i32 %63 to double
%65 = fsub double %64, %59
%66 = fdiv double %6, %65
%67 = icmp sgt i32 %7, 1
br i1 %67, label %68, label %100
68: ; preds = %62
%69 = and i32 %7, 1
%70 = icmp eq i32 %69, 0
br i1 %70, label %71, label %77
71: ; preds = %68
%72 = add nsw i32 %7, -1
%73 = shl nuw nsw i32 %72, 1
%74 = sitofp i32 %73 to double
%75 = fdiv double %74, %6
%76 = fsub double %75, %66
br label %77
77: ; preds = %71, %68
%78 = phi i32 [ %7, %68 ], [ %72, %71 ]
%79 = phi double [ 1.000000e+00, %68 ], [ %76, %71 ]
%80 = phi double [ %66, %68 ], [ 1.000000e+00, %71 ]
%81 = phi double [ undef, %68 ], [ %76, %71 ]
%82 = icmp eq i32 %7, 2
br i1 %82, label %100, label %83
83: ; preds = %77, %83
%84 = phi i32 [ %93, %83 ], [ %78, %77 ]
%85 = phi double [ %98, %83 ], [ %79, %77 ]
%86 = phi double [ %92, %83 ], [ %80, %77 ]
%87 = add nsw i32 %84, -1
%88 = shl nuw nsw i32 %87, 1
%89 = sitofp i32 %88 to double
%90 = fmul double %85, %89
%91 = fdiv double %90, %6
%92 = fsub double %91, %86
%93 = add nsw i32 %84, -2
%94 = shl nuw nsw i32 %93, 1
%95 = sitofp i32 %94 to double
%96 = fmul double %92, %95
%97 = fdiv double %96, %6
%98 = fsub double %97, %85
%99 = icmp ugt i32 %87, 2
br i1 %99, label %83, label %100
100: ; preds = %77, %83, %62
%101 = phi double [ 1.000000e+00, %62 ], [ %81, %77 ], [ %98, %83 ]
%102 = tail call double (double, ...) bitcast (double (...)* @j0 to double (double, ...)*)(double %6)
%103 = fmul double %66, %102
%104 = fdiv double %103, %101
br label %118
105: ; preds = %25
%106 = shl nuw i32 %41, 1
%107 = sitofp i32 %106 to double
br label %108
108: ; preds = %105, %19
%109 = phi double [ undef, %19 ], [ %40, %105 ]
%110 = phi double [ 2.000000e+00, %19 ], [ %107, %105 ]
%111 = phi double [ %17, %19 ], [ %40, %105 ]
%112 = phi double [ %16, %19 ], [ %34, %105 ]
%113 = icmp eq i32 %21, 0
br i1 %113, label %118, label %114
114: ; preds = %108
%115 = fmul double %111, %110
%116 = fdiv double %115, %6
%117 = fsub double %116, %112
br label %118
118: ; preds = %114, %108, %15, %100, %10, %8
%119 = phi double [ %9, %8 ], [ %11, %10 ], [ %104, %100 ], [ %17, %15 ], [ %109, %108 ], [ %117, %114 ]
ret double %119
}