int dust_triplet_find(unsigned char *seq_start, int icur, int max,
                      unsigned char *s1, const unsigned char *blastnaMap) {
  int n;
  unsigned char *s2, *s3;
  short c;
  unsigned char *seq = &seq_start[icur];
  unsigned char end_byte = 15;
  n = 0;
  s2 = s1 + 1;
  s3 = s1 + 2;
  if ((c = blastnaMap[*seq++]) == end_byte)
    return n;
  c &= 0x03;
  *s1 |= c;
  *s1 <<= 2;
  if ((c = blastnaMap[*seq++]) == end_byte)
    return n;
  c &= 0x03;
  *s1 |= c;
  *s2 |= c;
  while (n < max && (c = blastnaMap[*seq++]) != end_byte) {
    c &= 0x03;
    *s1 <<= 2;
    *s2 <<= 2;
    *s1 |= c;
    *s2 |= c;
    *s3 |= c;
    s1++;
    s2++;
    s3++;
    n++;
  }
  return n;
}


x86 assembly (clang, -O0):
<dust_triplet_find>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %edx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x50(%rbp)
movb   $0xf,-0x51(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x40(%rbp)
mov    -0x28(%rbp),%rax
mov    -0x50(%rbp),%rcx
mov    %rcx,%rdx
add    $0x1,%rdx
mov    %rdx,-0x50(%rbp)
movzbl (%rcx),%ecx
movzbl (%rax,%rcx,1),%eax
mov    %ax,-0x42(%rbp)
cwtl
movzbl -0x51(%rbp),%ecx
cmp    %ecx,%eax
jne    117e <dust_triplet_find+0x7e>
mov    -0x2c(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    12d7 <dust_triplet_find+0x1d7>
movswl -0x42(%rbp),%eax
and    $0x3,%eax
mov    %ax,-0x42(%rbp)
movswl -0x42(%rbp),%edx
mov    -0x20(%rbp),%rax
movzbl (%rax),%ecx
or     %edx,%ecx
mov    %cl,(%rax)
mov    -0x20(%rbp),%rax
movzbl (%rax),%ecx
shl    $0x2,%ecx
mov    %cl,(%rax)
mov    -0x28(%rbp),%rax
mov    -0x50(%rbp),%rcx
mov    %rcx,%rdx
add    $0x1,%rdx
mov    %rdx,-0x50(%rbp)
movzbl (%rcx),%ecx
movzbl (%rax,%rcx,1),%eax
mov    %ax,-0x42(%rbp)
cwtl
movzbl -0x51(%rbp),%ecx
cmp    %ecx,%eax
jne    11da <dust_triplet_find+0xda>
mov    -0x2c(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    12d7 <dust_triplet_find+0x1d7>
movswl -0x42(%rbp),%eax
and    $0x3,%eax
mov    %ax,-0x42(%rbp)
movswl -0x42(%rbp),%edx
mov    -0x20(%rbp),%rax
movzbl (%rax),%ecx
or     %edx,%ecx
mov    %cl,(%rax)
movswl -0x42(%rbp),%edx
mov    -0x38(%rbp),%rax
movzbl (%rax),%ecx
or     %edx,%ecx
mov    %cl,(%rax)
mov    -0x2c(%rbp),%ecx
xor    %eax,%eax
cmp    -0x18(%rbp),%ecx
mov    %al,-0x52(%rbp)
jge    123f <dust_triplet_find+0x13f>
mov    -0x28(%rbp),%rax
mov    -0x50(%rbp),%rcx
mov    %rcx,%rdx
add    $0x1,%rdx
mov    %rdx,-0x50(%rbp)
movzbl (%rcx),%ecx
movzbl (%rax,%rcx,1),%eax
mov    %ax,-0x42(%rbp)
cwtl
movzbl -0x51(%rbp),%ecx
cmp    %ecx,%eax
setne  %al
mov    %al,-0x52(%rbp)
mov    -0x52(%rbp),%al
test   $0x1,%al
jne    124f <dust_triplet_find+0x14f>
jmp    12d1 <dust_triplet_find+0x1d1>
movswl -0x42(%rbp),%eax
and    $0x3,%eax
mov    %ax,-0x42(%rbp)
mov    -0x20(%rbp),%rax
movzbl (%rax),%ecx
shl    $0x2,%ecx
mov    %cl,(%rax)
mov    -0x38(%rbp),%rax
movzbl (%rax),%ecx
shl    $0x2,%ecx
mov    %cl,(%rax)
movswl -0x42(%rbp),%edx
mov    -0x20(%rbp),%rax
movzbl (%rax),%ecx
or     %edx,%ecx
mov    %cl,(%rax)
movswl -0x42(%rbp),%edx
mov    -0x38(%rbp),%rax
movzbl (%rax),%ecx
or     %edx,%ecx
mov    %cl,(%rax)
movswl -0x42(%rbp),%edx
mov    -0x40(%rbp),%rax
movzbl (%rax),%ecx
or     %edx,%ecx
mov    %cl,(%rax)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1203 <dust_triplet_find+0x103>
mov    -0x2c(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<dust_triplet_find>:
movslq %esi,%r11
movzbl (%rdi,%r11,1),%eax
mov    (%r8,%rax,1),%r9b
xor    %eax,%eax
cmp    $0xf,%r9b
je     1192 <dust_triplet_find+0x92>
and    $0x3,%r9b
or     (%rcx),%r9b
shl    $0x2,%r9b
mov    %r9b,(%rcx)
movzbl 0x1(%rdi,%r11,1),%esi
mov    (%r8,%rsi,1),%r10b
cmp    $0xf,%r10b
je     1192 <dust_triplet_find+0x92>
and    $0x3,%r10b
or     %r10b,%r9b
mov    %r9b,(%rcx)
or     %r10b,0x1(%rcx)
test   %edx,%edx
jle    1192 <dust_triplet_find+0x92>
mov    %edx,%eax
lea    (%r11,%rdi,1),%rsi
add    $0x2,%rsi
xor    %edx,%edx
movzbl (%rsi,%rdx,1),%edi
movzbl (%r8,%rdi,1),%edi
cmp    $0xf,%dil
je     1193 <dust_triplet_find+0x93>
and    $0x3,%dil
movzbl (%rcx,%rdx,1),%r9d
movzbl 0x1(%rcx,%rdx,1),%r10d
shl    $0x2,%r9b
shl    $0x2,%r10b
or     %dil,%r9b
mov    %r9b,(%rcx,%rdx,1)
or     %dil,%r10b
mov    %r10b,0x1(%rcx,%rdx,1)
or     %dil,0x2(%rcx,%rdx,1)
add    $0x1,%rdx
cmp    %edx,%eax
jne    1150 <dust_triplet_find+0x50>
ret
mov    %edx,%eax
ret

LLVM IR (-O0):
define i32 @dust_triplet_find(i8* %0, i32 %1, i32 %2, i8* %3, i8* %4) {
%6 = alloca i32
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i8*
%11 = alloca i8*
%12 = alloca i32
%13 = alloca i8*
%14 = alloca i8*
%15 = alloca i16
%16 = alloca i8*
%17 = alloca i8
store i8* %0, i8** %7
store i32 %1, i32* %8
store i32 %2, i32* %9
store i8* %3, i8** %10
store i8* %4, i8** %11
%18 = load i8*, i8** %7
%19 = load i32, i32* %8
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds i8, i8* %18, i64 %20
store i8* %21, i8** %16
store i8 15, i8* %17
store i32 0, i32* %12
%22 = load i8*, i8** %10
%23 = getelementptr inbounds i8, i8* %22, i64 1
store i8* %23, i8** %13
%24 = load i8*, i8** %10
%25 = getelementptr inbounds i8, i8* %24, i64 2
store i8* %25, i8** %14
%26 = load i8*, i8** %11
%27 = load i8*, i8** %16
%28 = getelementptr inbounds i8, i8* %27, i32 1
store i8* %28, i8** %16
%29 = load i8, i8* %27
%30 = zext i8 %29 to i64
%31 = getelementptr inbounds i8, i8* %26, i64 %30
%32 = load i8, i8* %31
%33 = zext i8 %32 to i16
store i16 %33, i16* %15
%34 = sext i16 %33 to i32
%35 = load i8, i8* %17
%36 = zext i8 %35 to i32
%37 = icmp eq i32 %34, %36
br i1 %37, label %38, label %40
38: ; preds = %5
%39 = load i32, i32* %12
store i32 %39, i32* %6
br label %155
40: ; preds = %5
%41 = load i16, i16* %15
%42 = sext i16 %41 to i32
%43 = and i32 %42, 3
%44 = trunc i32 %43 to i16
store i16 %44, i16* %15
%45 = load i16, i16* %15
%46 = sext i16 %45 to i32
%47 = load i8*, i8** %10
%48 = load i8, i8* %47
%49 = zext i8 %48 to i32
%50 = or i32 %49, %46
%51 = trunc i32 %50 to i8
store i8 %51, i8* %47
%52 = load i8*, i8** %10
%53 = load i8, i8* %52
%54 = zext i8 %53 to i32
%55 = shl i32 %54, 2
%56 = trunc i32 %55 to i8
store i8 %56, i8* %52
%57 = load i8*, i8** %11
%58 = load i8*, i8** %16
%59 = getelementptr inbounds i8, i8* %58, i32 1
store i8* %59, i8** %16
%60 = load i8, i8* %58
%61 = zext i8 %60 to i64
%62 = getelementptr inbounds i8, i8* %57, i64 %61
%63 = load i8, i8* %62
%64 = zext i8 %63 to i16
store i16 %64, i16* %15
%65 = sext i16 %64 to i32
%66 = load i8, i8* %17
%67 = zext i8 %66 to i32
%68 = icmp eq i32 %65, %67
br i1 %68, label %69, label %71
69: ; preds = %40
%70 = load i32, i32* %12
store i32 %70, i32* %6
br label %155
71: ; preds = %40
%72 = load i16, i16* %15
%73 = sext i16 %72 to i32
%74 = and i32 %73, 3
%75 = trunc i32 %74 to i16
store i16 %75, i16* %15
%76 = load i16, i16* %15
%77 = sext i16 %76 to i32
%78 = load i8*, i8** %10
%79 = load i8, i8* %78
%80 = zext i8 %79 to i32
%81 = or i32 %80, %77
%82 = trunc i32 %81 to i8
store i8 %82, i8* %78
%83 = load i16, i16* %15
%84 = sext i16 %83 to i32
%85 = load i8*, i8** %13
%86 = load i8, i8* %85
%87 = zext i8 %86 to i32
%88 = or i32 %87, %84
%89 = trunc i32 %88 to i8
store i8 %89, i8* %85
br label %90
90: ; preds = %109, %71
%91 = load i32, i32* %12
%92 = load i32, i32* %9
%93 = icmp slt i32 %91, %92
br i1 %93, label %94, label %107
94: ; preds = %90
%95 = load i8*, i8** %11
%96 = load i8*, i8** %16
%97 = getelementptr inbounds i8, i8* %96, i32 1
store i8* %97, i8** %16
%98 = load i8, i8* %96
%99 = zext i8 %98 to i64
%100 = getelementptr inbounds i8, i8* %95, i64 %99
%101 = load i8, i8* %100
%102 = zext i8 %101 to i16
store i16 %102, i16* %15
%103 = sext i16 %102 to i32
%104 = load i8, i8* %17
%105 = zext i8 %104 to i32
%106 = icmp ne i32 %103, %105
br label %107
107: ; preds = %94, %90
%108 = phi i1 [ false, %90 ], [ %106, %94 ]
br i1 %108, label %109, label %153
109: ; preds = %107
%110 = load i16, i16* %15
%111 = sext i16 %110 to i32
%112 = and i32 %111, 3
%113 = trunc i32 %112 to i16
store i16 %113, i16* %15
%114 = load i8*, i8** %10
%115 = load i8, i8* %114
%116 = zext i8 %115 to i32
%117 = shl i32 %116, 2
%118 = trunc i32 %117 to i8
store i8 %118, i8* %114
%119 = load i8*, i8** %13
%120 = load i8, i8* %119
%121 = zext i8 %120 to i32
%122 = shl i32 %121, 2
%123 = trunc i32 %122 to i8
store i8 %123, i8* %119
%124 = load i16, i16* %15
%125 = sext i16 %124 to i32
%126 = load i8*, i8** %10
%127 = load i8, i8* %126
%128 = zext i8 %127 to i32
%129 = or i32 %128, %125
%130 = trunc i32 %129 to i8
store i8 %130, i8* %126
%131 = load i16, i16* %15
%132 = sext i16 %131 to i32
%133 = load i8*, i8** %13
%134 = load i8, i8* %133
%135 = zext i8 %134 to i32
%136 = or i32 %135, %132
%137 = trunc i32 %136 to i8
store i8 %137, i8* %133
%138 = load i16, i16* %15
%139 = sext i16 %138 to i32
%140 = load i8*, i8** %14
%141 = load i8, i8* %140
%142 = zext i8 %141 to i32
%143 = or i32 %142, %139
%144 = trunc i32 %143 to i8
store i8 %144, i8* %140
%145 = load i8*, i8** %10
%146 = getelementptr inbounds i8, i8* %145, i32 1
store i8* %146, i8** %10
%147 = load i8*, i8** %13
%148 = getelementptr inbounds i8, i8* %147, i32 1
store i8* %148, i8** %13
%149 = load i8*, i8** %14
%150 = getelementptr inbounds i8, i8* %149, i32 1
store i8* %150, i8** %14
%151 = load i32, i32* %12
%152 = add nsw i32 %151, 1
store i32 %152, i32* %12
br label %90
153: ; preds = %107
%154 = load i32, i32* %12
store i32 %154, i32* %6
br label %155
155: ; preds = %153, %69, %38
%156 = load i32, i32* %6
ret i32 %156
}

LLVM IR (-O2):
define i32 @dust_triplet_find(i8* nocapture %0, i32 %1, i32 %2, i8* nocapture %3, i8* nocapture %4) {
%6 = sext i32 %1 to i64
%7 = getelementptr inbounds i8, i8* %0, i64 %6
%8 = getelementptr inbounds i8, i8* %3, i64 1
%9 = getelementptr inbounds i8, i8* %3, i64 2
%10 = getelementptr inbounds i8, i8* %7, i64 1
%11 = load i8, i8* %7
%12 = zext i8 %11 to i64
%13 = getelementptr inbounds i8, i8* %4, i64 %12
%14 = load i8, i8* %13
%15 = icmp eq i8 %14, 15
br i1 %15, label %59, label %16
16: ; preds = %5
%17 = and i8 %14, 3
%18 = load i8, i8* %3
%19 = or i8 %18, %17
%20 = shl i8 %19, 2
store i8 %20, i8* %3
%21 = load i8, i8* %10
%22 = zext i8 %21 to i64
%23 = getelementptr inbounds i8, i8* %4, i64 %22
%24 = load i8, i8* %23
%25 = icmp eq i8 %24, 15
br i1 %25, label %59, label %26
26: ; preds = %16
%27 = and i8 %24, 3
%28 = or i8 %27, %20
store i8 %28, i8* %3
%29 = load i8, i8* %8
%30 = or i8 %29, %27
store i8 %30, i8* %8
%31 = icmp sgt i32 %2, 0
br i1 %31, label %32, label %59
32: ; preds = %26, %44
%33 = phi i8* [ %38, %44 ], [ %10, %26 ]
%34 = phi i8* [ %56, %44 ], [ %9, %26 ]
%35 = phi i8* [ %55, %44 ], [ %8, %26 ]
%36 = phi i32 [ %57, %44 ], [ 0, %26 ]
%37 = phi i8* [ %54, %44 ], [ %3, %26 ]
%38 = getelementptr inbounds i8, i8* %33, i64 1
%39 = load i8, i8* %38
%40 = zext i8 %39 to i64
%41 = getelementptr inbounds i8, i8* %4, i64 %40
%42 = load i8, i8* %41
%43 = icmp eq i8 %42, 15
br i1 %43, label %59, label %44
44: ; preds = %32
%45 = and i8 %42, 3
%46 = load i8, i8* %37
%47 = shl i8 %46, 2
%48 = load i8, i8* %35
%49 = shl i8 %48, 2
%50 = or i8 %47, %45
store i8 %50, i8* %37
%51 = or i8 %49, %45
store i8 %51, i8* %35
%52 = load i8, i8* %34
%53 = or i8 %52, %45
store i8 %53, i8* %34
%54 = getelementptr inbounds i8, i8* %37, i64 1
%55 = getelementptr inbounds i8, i8* %35, i64 1
%56 = getelementptr inbounds i8, i8* %34, i64 1
%57 = add nuw nsw i32 %36, 1
%58 = icmp eq i32 %57, %2
br i1 %58, label %59, label %32
59: ; preds = %44, %32, %26, %16, %5
%60 = phi i32 [ 0, %5 ], [ 0, %16 ], [ 0, %26 ], [ %2, %44 ], [ %36, %32 ]
ret i32 %60
}