// File: WojciechMula[P]utf16utf8/benchmarks/benchmark_from_utf16.cpp
// Function: Benchmark::run_from_utf16()
void run_from_utf16() {
        printf("\n");
        printf("Running UTF16 => UTF8 benchmark.\n");
        printf("The speed is normalized by the number of input bytes.\n");

        const size_t repeat = 10000;
        RandomUTF16 gen_1byte (rd, 1, 0, 0, 0);
        RandomUTF16 gen_2bytes(rd, 0, 1, 0, 0);
        RandomUTF16 gen_3bytes(rd, 0, 0, 1, 0);
        RandomUTF16 gen_4bytes(rd, 0, 0, 0, 1);
        RandomUTF16 gen_1_2(rd, 1, 1, 0, 0);
        RandomUTF16 gen_1_2_3(rd, 1, 1, 1, 0);
        RandomUTF16 anylength (rd, 1, 1, 1, 1);

        printf("Input size: (UTF16) %lu\n", size);

        puts("- Output ASCII characters");
        run_from_utf16(gen_1byte, repeat);

        puts("- Output exactly 2 UTF8 bytes");
        run_from_utf16(gen_2bytes, repeat);

        puts("- Output exactly 3 UTF8 bytes");
        run_from_utf16(gen_3bytes, repeat);

        //puts("- Output exactly 4 UTF8 bytes");
        // Given that we do not optimize this case at
        // all, it is not a relevant benchmark.
        //run(gen_4bytes, repeat);

        puts("- Output 1 or 2 UTF8 bytes");
        run_from_utf16(gen_1_2, repeat);

        puts("- Output 1, 2 or 3 UTF8 bytes");
        run_from_utf16(gen_1_2_3, repeat);

        // Results from this benchmark appear bogus: SSE is too fast!!!
        //puts("- Output 1, 2, 3 or 4 UTF8 bytes");
        //run(anylength, repeat);
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x8b60, %rsp           # imm = 0x8B60
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x8b58(%rbp)
leaq 0xc719(%rip), %rdi      # 0x1942a
xorl %eax, %eax
movl %eax, -0x8b44(%rbp)
movb %al, -0x8b59(%rbp)
callq 0x2050
movb -0x8b59(%rbp), %al
leaq 0xc577(%rip), %rdi      # 0x192a8
callq 0x2050
movb -0x8b59(%rbp), %al
leaq 0xc587(%rip), %rdi      # 0x192ca
callq 0x2050
movq -0x8b58(%rbp), %rsi
movl -0x8b44(%rbp), %r9d
movq $0x2710, -0x10(%rbp)    # imm = 0x2710
addq $0x8, %rsi
movq %rsi, -0x8b50(%rbp)
leaq -0x13f0(%rbp), %rdi
movl $0x1, %edx
movl %edx, -0x8b48(%rbp)
movl %r9d, %ecx
movl %r9d, %r8d
callq 0x7380
movq -0x8b50(%rbp), %rsi
movl -0x8b48(%rbp), %ecx
movl -0x8b44(%rbp), %r9d
leaq -0x27d0(%rbp), %rdi
movl %r9d, %edx
movl %r9d, %r8d
callq 0x7380
jmp 0xcdae
movq -0x8b58(%rbp), %rsi
addq $0x8, %rsi
leaq -0x3bc0(%rbp), %rdi
movl $0x1, %r8d
xorl %r9d, %r9d
movl %r9d, %edx
movl %r9d, %ecx
callq 0x7380
jmp 0xcdd6
movq -0x8b58(%rbp), %rsi
addq $0x8, %rsi
leaq -0x4fa0(%rbp), %rdi
xorl %r8d, %r8d
movl $0x1, %r9d
movl %r8d, %edx
movl %r8d, %ecx
callq 0x7380
jmp 0xcdfe
movq -0x8b58(%rbp), %rsi
addq $0x8, %rsi
leaq -0x6380(%rbp), %rdi
movl $0x1, %ecx
xorl %r9d, %r9d
movl %ecx, %edx
movl %r9d, %r8d
callq 0x7380
jmp 0xce24
movq -0x8b58(%rbp), %rsi
addq $0x8, %rsi
leaq -0x7760(%rbp), %rdi
movl $0x1, %r8d
xorl %r9d, %r9d
movl %r8d, %edx
movl %r8d, %ecx
callq 0x7380
jmp 0xce4c
movq -0x8b58(%rbp), %rsi
addq $0x8, %rsi
leaq -0x8b40(%rbp), %rdi
movl $0x1, %r9d
movl %r9d, %edx
movl %r9d, %ecx
movl %r9d, %r8d
callq 0x7380
jmp 0xce74
movq -0x8b58(%rbp), %rax
movq (%rax), %rsi
leaq 0xc47c(%rip), %rdi      # 0x19301
xorl %eax, %eax
callq 0x2050
jmp 0xce8e
leaq 0xc485(%rip), %rdi      # 0x1931a
callq 0x2280
jmp 0xce9c
movq -0x8b58(%rbp), %rdi
leaq -0x13f0(%rbp), %rsi
movl $0x2710, %edx           # imm = 0x2710
callq 0xd1f0
jmp 0xceb6
leaq 0xc477(%rip), %rdi      # 0x19334
callq 0x2280
jmp 0xcec4
movq -0x8b58(%rbp), %rdi
leaq -0x27d0(%rbp), %rsi
movl $0x2710, %edx           # imm = 0x2710
callq 0xd1f0
jmp 0xcede
leaq 0xc46d(%rip), %rdi      # 0x19352
callq 0x2280
jmp 0xceec
movq -0x8b58(%rbp), %rdi
leaq -0x3bc0(%rbp), %rsi
movl $0x2710, %edx           # imm = 0x2710
callq 0xd1f0
jmp 0xcf06
leaq 0xc463(%rip), %rdi      # 0x19370
callq 0x2280
jmp 0xcf14
movq -0x8b58(%rbp), %rdi
leaq -0x6380(%rbp), %rsi
movl $0x2710, %edx           # imm = 0x2710
callq 0xd1f0
jmp 0xcf2e
leaq 0xc456(%rip), %rdi      # 0x1938b
callq 0x2280
jmp 0xcf3c
movq -0x8b58(%rbp), %rdi
leaq -0x7760(%rbp), %rsi
movl $0x2710, %edx           # imm = 0x2710
callq 0xd1f0
jmp 0xcf56
leaq -0x8b40(%rbp), %rdi
callq 0xdd40
leaq -0x7760(%rbp), %rdi
callq 0xdd40
leaq -0x6380(%rbp), %rdi
callq 0xdd40
leaq -0x4fa0(%rbp), %rdi
callq 0xdd40
leaq -0x3bc0(%rbp), %rdi
callq 0xdd40
leaq -0x27d0(%rbp), %rdi
callq 0xdd40
leaq -0x13f0(%rbp), %rdi
callq 0xdd40
addq $0x8b60, %rsp           # imm = 0x8B60
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x27d8(%rbp)
movl %eax, -0x27dc(%rbp)
jmp 0xd08b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x27d8(%rbp)
movl %eax, -0x27dc(%rbp)
jmp 0xd07f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x27d8(%rbp)
movl %eax, -0x27dc(%rbp)
jmp 0xd073
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x27d8(%rbp)
movl %eax, -0x27dc(%rbp)
jmp 0xd067
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x27d8(%rbp)
movl %eax, -0x27dc(%rbp)
jmp 0xd05b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x27d8(%rbp)
movl %eax, -0x27dc(%rbp)
jmp 0xd04f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x27d8(%rbp)
movl %eax, -0x27dc(%rbp)
leaq -0x8b40(%rbp), %rdi
callq 0xdd40
leaq -0x7760(%rbp), %rdi
callq 0xdd40
leaq -0x6380(%rbp), %rdi
callq 0xdd40
leaq -0x4fa0(%rbp), %rdi
callq 0xdd40
leaq -0x3bc0(%rbp), %rdi
callq 0xdd40
leaq -0x27d0(%rbp), %rdi
callq 0xdd40
leaq -0x13f0(%rbp), %rdi
callq 0xdd40
movq -0x27d8(%rbp), %rdi
callq 0x22e0
nopw %cs:(%rax,%rax)
nopl (%rax)