void copy(unsigned long parms[]) {
  register unsigned long *source, *destination, length;
  source = (unsigned long *)parms[0];
  destination = (unsigned long *)parms[1];
  length = parms[2];
  if ((length == 0xFFFFFFFF) || (length == 0))
    return;
  while (length--)
    *destination++ = *source++;
}


x86 assembly (clang, -O0):
<copy>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
mov    0x8(%rax),%rax
mov    %rax,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    0x10(%rax),%rax
mov    %rax,-0x20(%rbp)
mov    $0xffffffff,%eax
cmp    %rax,-0x20(%rbp)
je     1145 <copy+0x45>
cmpq   $0x0,-0x20(%rbp)
jne    114a <copy+0x4a>
jmp    1191 <copy+0x91>
jmp    114f <copy+0x4f>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x20(%rbp)
cmp    $0x0,%rax
je     1191 <copy+0x91>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%rcx
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x18(%rbp)
mov    %rcx,(%rax)
jmp    114f <copy+0x4f>
pop    %rbp
ret

x86 assembly (clang, -O2):
<copy>:
mov    0x10(%rdi),%rax
test   %rax,%rax
je     12a7 <copy+0x1a7>
mov    $0xffffffff,%ecx
cmp    %rcx,%rax
je     12a7 <copy+0x1a7>
mov    (%rdi),%rcx
mov    0x8(%rdi),%rdx
cmp    $0x4,%rax
jb     1221 <copy+0x121>
lea    (%rcx,%rax,8),%rsi
cmp    %rsi,%rdx
jae    1142 <copy+0x42>
lea    (%rdx,%rax,8),%rsi
cmp    %rsi,%rcx
jb     1221 <copy+0x121>
mov    %rax,%r8
and    $0xfffffffffffffffc,%r8
lea    -0x4(%r8),%rsi
mov    %rsi,%rdi
shr    $0x2,%rdi
add    $0x1,%rdi
mov    %edi,%r9d
and    $0x3,%r9d
cmp    $0xc,%rsi
jae    1169 <copy+0x69>
xor    %esi,%esi
jmp    11c8 <copy+0xc8>
and    $0xfffffffffffffffc,%rdi
xor    %esi,%esi
nop
movups (%rcx,%rsi,8),%xmm0
movups 0x10(%rcx,%rsi,8),%xmm1
movups %xmm0,(%rdx,%rsi,8)
movups %xmm1,0x10(%rdx,%rsi,8)
movups 0x20(%rcx,%rsi,8),%xmm0
movups 0x30(%rcx,%rsi,8),%xmm1
movups %xmm0,0x20(%rdx,%rsi,8)
movups %xmm1,0x30(%rdx,%rsi,8)
movups 0x40(%rcx,%rsi,8),%xmm0
movups 0x50(%rcx,%rsi,8),%xmm1
movups %xmm0,0x40(%rdx,%rsi,8)
movups %xmm1,0x50(%rdx,%rsi,8)
movups 0x60(%rcx,%rsi,8),%xmm0
movups 0x70(%rcx,%rsi,8),%xmm1
movups %xmm0,0x60(%rdx,%rsi,8)
movups %xmm1,0x70(%rdx,%rsi,8)
add    $0x10,%rsi
add    $0xfffffffffffffffc,%rdi
jne    1170 <copy+0x70>
test   %r9,%r9
je     120d <copy+0x10d>
lea    (%rcx,%rsi,8),%r10
add    $0x10,%r10
lea    (%rdx,%rsi,8),%rsi
add    $0x10,%rsi
shl    $0x5,%r9
xor    %edi,%edi
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movups -0x10(%r10,%rdi,1),%xmm0
movups (%r10,%rdi,1),%xmm1
movups %xmm0,-0x10(%rsi,%rdi,1)
movups %xmm1,(%rsi,%rdi,1)
add    $0x20,%rdi
cmp    %rdi,%r9
jne    11f0 <copy+0xf0>
cmp    %r8,%rax
je     12a7 <copy+0x1a7>
and    $0x3,%eax
lea    (%rdx,%r8,8),%rdx
lea    (%rcx,%r8,8),%rcx
lea    -0x1(%rax),%r8
mov    %rax,%rdi
and    $0x7,%rdi
je     1248 <copy+0x148>
xchg   %ax,%ax
add    $0xffffffffffffffff,%rax
mov    (%rcx),%rsi
add    $0x8,%rcx
mov    %rsi,(%rdx)
add    $0x8,%rdx
add    $0xffffffffffffffff,%rdi
jne    1230 <copy+0x130>
cmp    $0x7,%r8
jb     12a7 <copy+0x1a7>
xor    %esi,%esi
mov    (%rcx,%rsi,8),%rdi
mov    %rdi,(%rdx,%rsi,8)
mov    0x8(%rcx,%rsi,8),%rdi
mov    %rdi,0x8(%rdx,%rsi,8)
mov    0x10(%rcx,%rsi,8),%rdi
mov    %rdi,0x10(%rdx,%rsi,8)
mov    0x18(%rcx,%rsi,8),%rdi
mov    %rdi,0x18(%rdx,%rsi,8)
mov    0x20(%rcx,%rsi,8),%rdi
mov    %rdi,0x20(%rdx,%rsi,8)
mov    0x28(%rcx,%rsi,8),%rdi
mov    %rdi,0x28(%rdx,%rsi,8)
mov    0x30(%rcx,%rsi,8),%rdi
mov    %rdi,0x30(%rdx,%rsi,8)
mov    0x38(%rcx,%rsi,8),%rdi
mov    %rdi,0x38(%rdx,%rsi,8)
add    $0x8,%rsi
cmp    %rsi,%rax
jne    1250 <copy+0x150>
ret

LLVM IR (-O0):
define void @copy(i64* %0) {
%2 = alloca i64*
%3 = alloca i64*
%4 = alloca i64*
%5 = alloca i64
store i64* %0, i64** %2
%6 = load i64*, i64** %2
%7 = getelementptr inbounds i64, i64* %6, i64 0
%8 = load i64, i64* %7
%9 = inttoptr i64 %8 to i64*
store i64* %9, i64** %3
%10 = load i64*, i64** %2
%11 = getelementptr inbounds i64, i64* %10, i64 1
%12 = load i64, i64* %11
%13 = inttoptr i64 %12 to i64*
store i64* %13, i64** %4
%14 = load i64*, i64** %2
%15 = getelementptr inbounds i64, i64* %14, i64 2
%16 = load i64, i64* %15
store i64 %16, i64* %5
%17 = load i64, i64* %5
%18 = icmp eq i64 %17, 4294967295
br i1 %18, label %22, label %19
19: ; preds = %1
%20 = load i64, i64* %5
%21 = icmp eq i64 %20, 0
br i1 %21, label %22, label %23
22: ; preds = %19, %1
br label %34
23: ; preds = %19
br label %24
24: ; preds = %28, %23
%25 = load i64, i64* %5
%26 = add i64 %25, -1
store i64 %26, i64* %5
%27 = icmp ne i64 %25, 0
br i1 %27, label %28, label %34
28: ; preds = %24
%29 = load i64*, i64** %3
%30 = getelementptr inbounds i64, i64* %29, i32 1
store i64* %30, i64** %3
%31 = load i64, i64* %29
%32 = load i64*, i64** %4
%33 = getelementptr inbounds i64, i64* %32, i32 1
store i64* %33, i64** %4
store i64 %31, i64* %32
br label %24
34: ; preds = %22, %24
ret void
}

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