#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 */
void Str2BCD(unsigned char *dst, char *src, unsigned char length) {
  int i, j;
  unsigned char lo_nibble, hi_nibble;
  char c;
  if ((dst == NULL) || (src == NULL)) {
    return;
  }
  j = 0;
  for (i = 0; i < length; i++) {
    c = src[i];
    lo_nibble = src[i] & 0x0f;
    hi_nibble = (src[i] >> 4) & 0x0f;
    if ((hi_nibble >= 0x0) && (hi_nibble <= 0x09)) {
      dst[j++] = hi_nibble + 0x30;
    } else {
      dst[j++] = hi_nibble + 'A' - 10;
    }
    if ((lo_nibble >= 0x0) && (lo_nibble <= 0x09)) {
      dst[j++] = lo_nibble + 0x30;
    } else {
      dst[j++] = lo_nibble + 'A' - 10;
    }
  }
}


x86 assembly (clang, -O0):
<Str2BCD>:
push   %rbp
mov    %rsp,%rbp
mov    %dl,%al
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %al,-0x11(%rbp)
cmpq   $0x0,-0x8(%rbp)
je     1127 <Str2BCD+0x27>
cmpq   $0x0,-0x10(%rbp)
jne    112c <Str2BCD+0x2c>
jmp    124d <Str2BCD+0x14d>
movl   $0x0,-0x1c(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
movzbl -0x11(%rbp),%ecx
cmp    %ecx,%eax
jge    124d <Str2BCD+0x14d>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x1f(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xf,%eax
mov    %al,-0x1d(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
sar    $0x4,%eax
and    $0xf,%eax
mov    %al,-0x1e(%rbp)
movzbl -0x1e(%rbp),%eax
cmp    $0x0,%eax
jl     11bb <Str2BCD+0xbb>
movzbl -0x1e(%rbp),%eax
cmp    $0x9,%eax
jg     11bb <Str2BCD+0xbb>
movzbl -0x1e(%rbp),%eax
add    $0x30,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11dc <Str2BCD+0xdc>
movzbl -0x1e(%rbp),%eax
add    $0x41,%eax
sub    $0xa,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
movzbl -0x1d(%rbp),%eax
cmp    $0x0,%eax
jl     1219 <Str2BCD+0x119>
movzbl -0x1d(%rbp),%eax
cmp    $0x9,%eax
jg     1219 <Str2BCD+0x119>
movzbl -0x1d(%rbp),%eax
add    $0x30,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    123a <Str2BCD+0x13a>
movzbl -0x1d(%rbp),%eax
add    $0x41,%eax
sub    $0xa,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    123f <Str2BCD+0x13f>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    113a <Str2BCD+0x3a>
pop    %rbp
ret

x86 assembly (clang, -O2):
<Str2BCD>:
test   %rdi,%rdi
je     1198 <Str2BCD+0x98>
test   %rsi,%rsi
je     1198 <Str2BCD+0x98>
test   %dl,%dl
je     1198 <Str2BCD+0x98>
movzbl %dl,%r9d
cmp    $0x8,%dl
jb     1135 <Str2BCD+0x35>
lea    (%rsi,%r9,1),%rcx
cmp    %rdi,%rcx
jbe    1199 <Str2BCD+0x99>
lea    (%rdi,%r9,2),%rcx
cmp    %rsi,%rcx
jbe    1199 <Str2BCD+0x99>
xor    %r8d,%r8d
xor    %ecx,%ecx
add    %rdi,%r8
add    $0x1,%r8
add    %rcx,%rsi
sub    %rcx,%r9
xor    %ecx,%ecx
nopl   0x0(%rax)
movzbl (%rsi,%rcx,1),%eax
mov    %eax,%edi
and    $0xf,%dil
mov    %eax,%edx
shr    $0x4,%dl
lea    0x30(%rdx),%r10d
add    $0x37,%dl
cmp    $0xa0,%al
movzbl %r10b,%eax
movzbl %dl,%edx
cmovb  %eax,%edx
lea    0x30(%rdi),%eax
cmp    $0xa,%dil
lea    0x37(%rdi),%edi
movzbl %al,%eax
movzbl %dil,%edi
cmovb  %eax,%edi
mov    %dl,-0x1(%r8,%rcx,2)
mov    %dil,(%r8,%rcx,2)
add    $0x1,%rcx
cmp    %rcx,%r9
jne    1150 <Str2BCD+0x50>
ret
mov    %r9d,%ecx
and    $0xfffffff8,%ecx
lea    (%rcx,%rcx,1),%r8
xor    %edx,%edx
movdqa 0xe52(%rip),%xmm8
movdqa 0xe59(%rip),%xmm9
movdqa 0xe61(%rip),%xmm2
movdqa 0xe69(%rip),%xmm3
movdqa 0xe71(%rip),%xmm4
movdqa 0xe79(%rip),%xmm5
nopw   0x0(%rax,%rax,1)
movq   (%rsi,%rdx,1),%xmm0
movdqa %xmm0,%xmm7
movdqa %xmm0,%xmm6
pmaxub %xmm2,%xmm6
pcmpeqb %xmm0,%xmm6
pand   %xmm8,%xmm0
psrlw  $0x4,%xmm7
pand   %xmm9,%xmm7
movdqa %xmm7,%xmm1
por    %xmm3,%xmm1
paddb  %xmm4,%xmm7
pand   %xmm6,%xmm7
pandn  %xmm1,%xmm6
por    %xmm7,%xmm6
movdqa %xmm0,%xmm1
pmaxub %xmm5,%xmm1
pcmpeqb %xmm0,%xmm1
movdqa %xmm0,%xmm7
por    %xmm3,%xmm7
paddb  %xmm4,%xmm0
pand   %xmm1,%xmm0
pandn  %xmm7,%xmm1
por    %xmm0,%xmm1
punpcklbw %xmm1,%xmm6
movdqu %xmm6,(%rdi,%rdx,2)
add    $0x8,%rdx
cmp    %rdx,%rcx
jne    11e0 <Str2BCD+0xe0>
cmp    %r9,%rcx
jne    113a <Str2BCD+0x3a>
jmp    1198 <Str2BCD+0x98>

LLVM IR (-O0):
define void @Str2BCD(i8* %0, i8* %1, i8 zeroext %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8
%7 = alloca i32
%8 = alloca i32
%9 = alloca i8
%10 = alloca i8
%11 = alloca i8
store i8* %0, i8** %4
store i8* %1, i8** %5
store i8 %2, i8* %6
%12 = load i8*, i8** %4
%13 = icmp eq i8* %12, null
br i1 %13, label %17, label %14
14: ; preds = %3
%15 = load i8*, i8** %5
%16 = icmp eq i8* %15, null
br i1 %16, label %17, label %18
17: ; preds = %14, %3
br label %108
18: ; preds = %14
store i32 0, i32* %8
store i32 0, i32* %7
br label %19
19: ; preds = %105, %18
%20 = load i32, i32* %7
%21 = load i8, i8* %6
%22 = zext i8 %21 to i32
%23 = icmp slt i32 %20, %22
br i1 %23, label %24, label %108
24: ; preds = %19
%25 = load i8*, i8** %5
%26 = load i32, i32* %7
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds i8, i8* %25, i64 %27
%29 = load i8, i8* %28
store i8 %29, i8* %11
%30 = load i8*, i8** %5
%31 = load i32, i32* %7
%32 = sext i32 %31 to i64
%33 = getelementptr inbounds i8, i8* %30, i64 %32
%34 = load i8, i8* %33
%35 = sext i8 %34 to i32
%36 = and i32 %35, 15
%37 = trunc i32 %36 to i8
store i8 %37, i8* %9
%38 = load i8*, i8** %5
%39 = load i32, i32* %7
%40 = sext i32 %39 to i64
%41 = getelementptr inbounds i8, i8* %38, i64 %40
%42 = load i8, i8* %41
%43 = sext i8 %42 to i32
%44 = ashr i32 %43, 4
%45 = and i32 %44, 15
%46 = trunc i32 %45 to i8
store i8 %46, i8* %10
%47 = load i8, i8* %10
%48 = zext i8 %47 to i32
%49 = icmp sge i32 %48, 0
br i1 %49, label %50, label %64
50: ; preds = %24
%51 = load i8, i8* %10
%52 = zext i8 %51 to i32
%53 = icmp sle i32 %52, 9
br i1 %53, label %54, label %64
54: ; preds = %50
%55 = load i8, i8* %10
%56 = zext i8 %55 to i32
%57 = add nsw i32 %56, 48
%58 = trunc i32 %57 to i8
%59 = load i8*, i8** %4
%60 = load i32, i32* %8
%61 = add nsw i32 %60, 1
store i32 %61, i32* %8
%62 = sext i32 %60 to i64
%63 = getelementptr inbounds i8, i8* %59, i64 %62
store i8 %58, i8* %63
br label %75
64: ; preds = %50, %24
%65 = load i8, i8* %10
%66 = zext i8 %65 to i32
%67 = add nsw i32 %66, 65
%68 = sub nsw i32 %67, 10
%69 = trunc i32 %68 to i8
%70 = load i8*, i8** %4
%71 = load i32, i32* %8
%72 = add nsw i32 %71, 1
store i32 %72, i32* %8
%73 = sext i32 %71 to i64
%74 = getelementptr inbounds i8, i8* %70, i64 %73
store i8 %69, i8* %74
br label %75
75: ; preds = %64, %54
%76 = load i8, i8* %9
%77 = zext i8 %76 to i32
%78 = icmp sge i32 %77, 0
br i1 %78, label %79, label %93
79: ; preds = %75
%80 = load i8, i8* %9
%81 = zext i8 %80 to i32
%82 = icmp sle i32 %81, 9
br i1 %82, label %83, label %93
83: ; preds = %79
%84 = load i8, i8* %9
%85 = zext i8 %84 to i32
%86 = add nsw i32 %85, 48
%87 = trunc i32 %86 to i8
%88 = load i8*, i8** %4
%89 = load i32, i32* %8
%90 = add nsw i32 %89, 1
store i32 %90, i32* %8
%91 = sext i32 %89 to i64
%92 = getelementptr inbounds i8, i8* %88, i64 %91
store i8 %87, i8* %92
br label %104
93: ; preds = %79, %75
%94 = load i8, i8* %9
%95 = zext i8 %94 to i32
%96 = add nsw i32 %95, 65
%97 = sub nsw i32 %96, 10
%98 = trunc i32 %97 to i8
%99 = load i8*, i8** %4
%100 = load i32, i32* %8
%101 = add nsw i32 %100, 1
store i32 %101, i32* %8
%102 = sext i32 %100 to i64
%103 = getelementptr inbounds i8, i8* %99, i64 %102
store i8 %98, i8* %103
br label %104
104: ; preds = %93, %83
br label %105
105: ; preds = %104
%106 = load i32, i32* %7
%107 = add nsw i32 %106, 1
store i32 %107, i32* %7
br label %19
108: ; preds = %17, %19
ret void
}

LLVM IR (-O2):
define void @Str2BCD(i8* writeonly %0, i8* %1, i8 zeroext %2) {
%4 = icmp eq i8* %0, null
%5 = icmp eq i8* %1, null
%6 = or i1 %4, %5
%7 = icmp eq i8 %2, 0
%8 = or i1 %6, %7
br i1 %8, label %71, label %9
9: ; preds = %3
%10 = zext i8 %2 to i64
%11 = icmp ult i8 %2, 8
br i1 %11, label %47, label %12
12: ; preds = %9
%13 = shl nuw nsw i64 %10, 1
%14 = getelementptr i8, i8* %0, i64 %13
%15 = getelementptr i8, i8* %1, i64 %10
%16 = icmp ugt i8* %15, %0
%17 = icmp ugt i8* %14, %1
%18 = and i1 %16, %17
br i1 %18, label %47, label %19
19: ; preds = %12
%20 = and i64 %10, 248
%21 = shl nuw nsw i64 %20, 1
%22 = getelementptr inbounds i8, i8* %0, i64 -1
br label %23
23: ; preds = %23, %19
%24 = phi i64 [ 0, %19 ], [ %43, %23 ]
%25 = shl i64 %24, 1
%26 = getelementptr inbounds i8, i8* %1, i64 %24
%27 = bitcast i8* %26 to <8 x i8>*
%28 = load <8 x i8>, <8 x i8>* %27
%29 = and <8 x i8> %28, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
%30 = lshr <8 x i8> %28, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
%31 = icmp ult <8 x i8> %28, <i8 -96, i8 -96, i8 -96, i8 -96, i8 -96, i8 -96, i8 -96, i8 -96>
%32 = or <8 x i8> %30, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%33 = add nuw nsw <8 x i8> %30, <i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55>
%34 = select <8 x i1> %31, <8 x i8> %32, <8 x i8> %33
%35 = or i64 %25, 1
%36 = icmp ult <8 x i8> %29, <i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10>
%37 = or <8 x i8> %29, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%38 = add nuw nsw <8 x i8> %29, <i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55>
%39 = select <8 x i1> %36, <8 x i8> %37, <8 x i8> %38
%40 = getelementptr inbounds i8, i8* %22, i64 %35
%41 = bitcast i8* %40 to <16 x i8>*
%42 = shufflevector <8 x i8> %34, <8 x i8> %39, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
store <16 x i8> %42, <16 x i8>* %41
%43 = add nuw i64 %24, 8
%44 = icmp eq i64 %43, %20
br i1 %44, label %45, label %23
45: ; preds = %23
%46 = icmp eq i64 %20, %10
br i1 %46, label %71, label %47
47: ; preds = %12, %9, %45
%48 = phi i64 [ 0, %12 ], [ 0, %9 ], [ %21, %45 ]
%49 = phi i64 [ 0, %12 ], [ 0, %9 ], [ %20, %45 ]
br label %50
50: ; preds = %47, %50
%51 = phi i64 [ %68, %50 ], [ %48, %47 ]
%52 = phi i64 [ %69, %50 ], [ %49, %47 ]
%53 = getelementptr inbounds i8, i8* %1, i64 %52
%54 = load i8, i8* %53
%55 = and i8 %54, 15
%56 = lshr i8 %54, 4
%57 = icmp ult i8 %54, -96
%58 = or i8 %56, 48
%59 = add nuw nsw i8 %56, 55
%60 = select i1 %57, i8 %58, i8 %59
%61 = getelementptr inbounds i8, i8* %0, i64 %51
store i8 %60, i8* %61
%62 = or i64 %51, 1
%63 = icmp ult i8 %55, 10
%64 = or i8 %55, 48
%65 = add nuw nsw i8 %55, 55
%66 = select i1 %63, i8 %64, i8 %65
%67 = getelementptr inbounds i8, i8* %0, i64 %62
store i8 %66, i8* %67
%68 = add nuw nsw i64 %51, 2
%69 = add nuw nsw i64 %52, 1
%70 = icmp eq i64 %69, %10
br i1 %70, label %71, label %50
71: ; preds = %50, %45, %3
ret void
}