#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 */
int /*<<< orphan*/ __generic_memcpy_tofs(void *, void const *, unsigned long);
int /*<<< orphan*/ put_user_byte(char const, char *);
int /*<<< orphan*/ put_user_long(int const, int *);
int /*<<< orphan*/ put_user_word(short const, short *);
void __constant_memcpy_tofs(void *to, const void *from, unsigned long n) {
  if (n == 0) {
    return;
  } else if (n == 1) {
    put_user_byte(*(const char *)from, (char *)to);
    return;
  } else if (n == 2) {
    put_user_word(*(const short *)from, (short *)to);
    return;
  } else if (n == 3) {
    put_user_word(*(const short *)from, (short *)to);
    put_user_byte(*(2 + (const char *)from), 2 + (char *)to);
    return;
  } else if (n == 4) {
    put_user_long(*(const int *)from, (int *)to);
    return;
  }
  __generic_memcpy_tofs(to, from, n);
}


x86 assembly (clang, -O0):
<__constant_memcpy_tofs>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    1164 <__constant_memcpy_tofs+0x24>
jmp    1227 <__constant_memcpy_tofs+0xe7>
cmpq   $0x1,-0x18(%rbp)
jne    1186 <__constant_memcpy_tofs+0x46>
mov    -0x10(%rbp),%rax
mov    (%rax),%al
mov    -0x8(%rbp),%rsi
movsbl %al,%edi
call   1050 <put_user_byte@plt>
jmp    1227 <__constant_memcpy_tofs+0xe7>
cmpq   $0x2,-0x18(%rbp)
jne    11a9 <__constant_memcpy_tofs+0x69>
mov    -0x10(%rbp),%rax
mov    (%rax),%ax
mov    -0x8(%rbp),%rsi
movswl %ax,%edi
call   1030 <put_user_word@plt>
jmp    1227 <__constant_memcpy_tofs+0xe7>
cmpq   $0x3,-0x18(%rbp)
jne    11e3 <__constant_memcpy_tofs+0xa3>
mov    -0x10(%rbp),%rax
mov    (%rax),%ax
mov    -0x8(%rbp),%rsi
movswl %ax,%edi
call   1030 <put_user_word@plt>
mov    -0x10(%rbp),%rax
mov    0x2(%rax),%al
mov    -0x8(%rbp),%rsi
add    $0x2,%rsi
movsbl %al,%edi
call   1050 <put_user_byte@plt>
jmp    1227 <__constant_memcpy_tofs+0xe7>
cmpq   $0x4,-0x18(%rbp)
jne    1202 <__constant_memcpy_tofs+0xc2>
mov    -0x10(%rbp),%rax
mov    (%rax),%edi
mov    -0x8(%rbp),%rsi
call   1040 <put_user_long@plt>
jmp    1227 <__constant_memcpy_tofs+0xe7>
jmp    1207 <__constant_memcpy_tofs+0xc7>
jmp    120c <__constant_memcpy_tofs+0xcc>
jmp    1211 <__constant_memcpy_tofs+0xd1>
jmp    1216 <__constant_memcpy_tofs+0xd6>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
call   1060 <__generic_memcpy_tofs@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<__constant_memcpy_tofs>:
push   %r14
push   %rbx
push   %rax
mov    %rsi,%rbx
mov    %rdi,%r14
cmp    $0x4,%rdx
ja     1168 <__constant_memcpy_tofs+0x28>
lea    0xea9(%rip),%rax
movslq (%rax,%rdx,4),%rcx
add    %rax,%rcx
jmp    *%rcx
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret
mov    %r14,%rdi
mov    %rbx,%rsi
add    $0x8,%rsp
pop    %rbx
pop    %r14
jmp    1060 <__generic_memcpy_tofs@plt>
movsbl (%rbx),%edi
jmp    11a4 <__constant_memcpy_tofs+0x64>
movswl (%rbx),%edi
mov    %r14,%rsi
add    $0x8,%rsp
pop    %rbx
pop    %r14
jmp    1030 <put_user_word@plt>
movswl (%rbx),%edi
mov    %r14,%rsi
call   1030 <put_user_word@plt>
movsbl 0x2(%rbx),%edi
add    $0x2,%r14
mov    %r14,%rsi
add    $0x8,%rsp
pop    %rbx
pop    %r14
jmp    1050 <put_user_byte@plt>
mov    (%rbx),%edi
mov    %r14,%rsi
add    $0x8,%rsp
pop    %rbx
pop    %r14
jmp    1040 <put_user_long@plt>

LLVM IR (-O0):
define void @__constant_memcpy_tofs(i8* %0, i8* %1, i64 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i64
store i8* %0, i8** %4
store i8* %1, i8** %5
store i64 %2, i64* %6
%7 = load i64, i64* %6
%8 = icmp eq i64 %7, 0
br i1 %8, label %9, label %10
9: ; preds = %3
br label %63
10: ; preds = %3
%11 = load i64, i64* %6
%12 = icmp eq i64 %11, 1
br i1 %12, label %13, label %18
13: ; preds = %10
%14 = load i8*, i8** %5
%15 = load i8, i8* %14
%16 = load i8*, i8** %4
%17 = call i32 @put_user_byte(i8 signext %15, i8* %16)
br label %63
18: ; preds = %10
%19 = load i64, i64* %6
%20 = icmp eq i64 %19, 2
br i1 %20, label %21, label %28
21: ; preds = %18
%22 = load i8*, i8** %5
%23 = bitcast i8* %22 to i16*
%24 = load i16, i16* %23
%25 = load i8*, i8** %4
%26 = bitcast i8* %25 to i16*
%27 = call i32 @put_user_word(i16 signext %24, i16* %26)
br label %63
28: ; preds = %18
%29 = load i64, i64* %6
%30 = icmp eq i64 %29, 3
br i1 %30, label %31, label %44
31: ; preds = %28
%32 = load i8*, i8** %5
%33 = bitcast i8* %32 to i16*
%34 = load i16, i16* %33
%35 = load i8*, i8** %4
%36 = bitcast i8* %35 to i16*
%37 = call i32 @put_user_word(i16 signext %34, i16* %36)
%38 = load i8*, i8** %5
%39 = getelementptr inbounds i8, i8* %38, i64 2
%40 = load i8, i8* %39
%41 = load i8*, i8** %4
%42 = getelementptr inbounds i8, i8* %41, i64 2
%43 = call i32 @put_user_byte(i8 signext %40, i8* %42)
br label %63
44: ; preds = %28
%45 = load i64, i64* %6
%46 = icmp eq i64 %45, 4
br i1 %46, label %47, label %54
47: ; preds = %44
%48 = load i8*, i8** %5
%49 = bitcast i8* %48 to i32*
%50 = load i32, i32* %49
%51 = load i8*, i8** %4
%52 = bitcast i8* %51 to i32*
%53 = call i32 @put_user_long(i32 %50, i32* %52)
br label %63
54: ; preds = %44
br label %55
55: ; preds = %54
br label %56
56: ; preds = %55
br label %57
57: ; preds = %56
br label %58
58: ; preds = %57
%59 = load i8*, i8** %4
%60 = load i8*, i8** %5
%61 = load i64, i64* %6
%62 = call i32 @__generic_memcpy_tofs(i8* %59, i8* %60, i64 %61)
br label %63
63: ; preds = %58, %47, %31, %21, %13, %9
ret void
}

LLVM IR (-O2):
define void @__constant_memcpy_tofs(i8* %0, i8* %1, i64 %2) {
switch i64 %2, label %26 [
i64 0, label %28
i64 1, label %4
i64 2, label %7
i64 3, label %12
i64 4, label %21
]
4: ; preds = %3
%5 = load i8, i8* %1
%6 = tail call i32 @put_user_byte(i8 signext %5, i8* %0)
br label %28
7: ; preds = %3
%8 = bitcast i8* %1 to i16*
%9 = load i16, i16* %8
%10 = bitcast i8* %0 to i16*
%11 = tail call i32 @put_user_word(i16 signext %9, i16* %10)
br label %28
12: ; preds = %3
%13 = bitcast i8* %1 to i16*
%14 = load i16, i16* %13
%15 = bitcast i8* %0 to i16*
%16 = tail call i32 @put_user_word(i16 signext %14, i16* %15)
%17 = getelementptr inbounds i8, i8* %1, i64 2
%18 = load i8, i8* %17
%19 = getelementptr inbounds i8, i8* %0, i64 2
%20 = tail call i32 @put_user_byte(i8 signext %18, i8* %19)
br label %28
21: ; preds = %3
%22 = bitcast i8* %1 to i32*
%23 = load i32, i32* %22
%24 = bitcast i8* %0 to i32*
%25 = tail call i32 @put_user_long(i32 %23, i32* %24)
br label %28
26: ; preds = %3
%27 = tail call i32 @__generic_memcpy_tofs(i8* %0, i8* %1, i64 %2)
br label %28
28: ; preds = %3, %26, %21, %12, %7, %4
ret void
}