#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 */
typedef int /*<<< orphan*/ uint8_t;
typedef int uint64_t;
typedef int uint32_t;

/* Variables and functions */
void websocket_xmask(void *msg, uint64_t len, uint32_t mask) {
  if (len > 7) {
    {
      const uintptr_t offset = 4 - ((uintptr_t)msg & 3);
      switch (offset) {
      case 3:
        ((uint8_t *)msg)[2] ^= ((uint8_t *)(&mask))[2];
      case 2:
        ((uint8_t *)msg)[1] ^= ((uint8_t *)(&mask))[1];
      case 1:
        ((uint8_t *)msg)[0] ^= ((uint8_t *)(&mask))[0];
        uint64_t comb = mask | ((uint64_t)mask << 32);
        ((uint8_t *)(&mask))[0] = ((uint8_t *)(&comb))[0 + offset];
        ((uint8_t *)(&mask))[1] = ((uint8_t *)(&comb))[1 + offset];
        ((uint8_t *)(&mask))[2] = ((uint8_t *)(&comb))[2 + offset];
        ((uint8_t *)(&mask))[3] = ((uint8_t *)(&comb))[3 + offset];
        msg = (void *)((uintptr_t)msg + offset);
        len -= offset;
      }
    }
    while (len >= 4) {
      *((uint32_t *)msg) ^= mask;
      len -= 4;
      msg = (void *)((uintptr_t)msg + 4);
    }
  }
  switch (len) {
  case 7:
    ((uint8_t *)msg)[6] ^= ((uint8_t *)(&mask))[2];
  case 6:
    ((uint8_t *)msg)[5] ^= ((uint8_t *)(&mask))[1];
  case 5:
    ((uint8_t *)msg)[4] ^= ((uint8_t *)(&mask))[0];
  case 4:
    ((uint8_t *)msg)[3] ^= ((uint8_t *)(&mask))[3];
  case 3:
    ((uint8_t *)msg)[2] ^= ((uint8_t *)(&mask))[2];
  case 2:
    ((uint8_t *)msg)[1] ^= ((uint8_t *)(&mask))[1];
  case 1:
    ((uint8_t *)msg)[0] ^= ((uint8_t *)(&mask))[0];
  }
}


x86 assembly (clang, -O0):
<websocket_xmask>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
cmpl   $0x7,-0xc(%rbp)
jle    1232 <websocket_xmask+0x132>
mov    -0x8(%rbp),%rax
and    $0x3,%eax
mov    %eax,%ecx
mov    $0x4,%eax
sub    %rcx,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x28(%rbp)
sub    $0x1,%rax
je     1184 <websocket_xmask+0x84>
jmp    1144 <websocket_xmask+0x44>
mov    -0x28(%rbp),%rax
sub    $0x2,%rax
je     1177 <websocket_xmask+0x77>
jmp    1157 <websocket_xmask+0x57>
mov    -0x28(%rbp),%rax
sub    $0x3,%rax
jne    11f9 <websocket_xmask+0xf9>
jmp    116a <websocket_xmask+0x6a>
mov    -0x8(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    0x8(%rax),%ecx
mov    %ecx,0x8(%rax)
mov    -0xc(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    0x4(%rax),%ecx
mov    %ecx,0x4(%rax)
mov    -0x10(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    (%rax),%ecx
mov    %ecx,(%rax)
mov    -0x10(%rbp),%eax
mov    -0x10(%rbp),%edx
mov    $0x20,%ecx
shl    %cl,%edx
mov    %edx,%ecx
or     %ecx,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x18(%rbp),%rax
add    $0x0,%rax
mov    -0x1c(%rbp,%rax,4),%eax
mov    %eax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    -0x1c(%rbp,%rax,4),%eax
mov    %eax,-0xc(%rbp)
mov    -0x18(%rbp),%rax
add    $0x2,%rax
mov    -0x1c(%rbp,%rax,4),%eax
mov    %eax,-0x8(%rbp)
mov    -0x18(%rbp),%rax
add    $0x3,%rax
mov    -0x1c(%rbp,%rax,4),%eax
mov    %eax,-0x4(%rbp)
mov    -0x8(%rbp),%rax
add    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x18(%rbp),%rcx
movslq -0xc(%rbp),%rax
sub    %rcx,%rax
mov    %eax,-0xc(%rbp)
jmp    11fe <websocket_xmask+0xfe>
cmpl   $0x4,-0xc(%rbp)
jl     122d <websocket_xmask+0x12d>
mov    -0x10(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    (%rax),%ecx
mov    %ecx,(%rax)
mov    -0xc(%rbp),%eax
sub    $0x4,%eax
mov    %eax,-0xc(%rbp)
mov    -0x8(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x8(%rbp)
jmp    11fe <websocket_xmask+0xfe>
jmp    1232 <websocket_xmask+0x132>
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,%ecx
mov    %rcx,-0x30(%rbp)
sub    $0x6,%eax
ja     12b4 <websocket_xmask+0x1b4>
mov    -0x30(%rbp),%rax
lea    0xdae(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x8(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    0x18(%rax),%ecx
mov    %ecx,0x18(%rax)
mov    -0xc(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    0x14(%rax),%ecx
mov    %ecx,0x14(%rax)
mov    -0x10(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    0x10(%rax),%ecx
mov    %ecx,0x10(%rax)
mov    -0x4(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    0xc(%rax),%ecx
mov    %ecx,0xc(%rax)
mov    -0x8(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    0x8(%rax),%ecx
mov    %ecx,0x8(%rax)
mov    -0xc(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    0x4(%rax),%ecx
mov    %ecx,0x4(%rax)
mov    -0x10(%rbp),%ecx
mov    -0x8(%rbp),%rax
xor    (%rax),%ecx
mov    %ecx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<websocket_xmask>:
cmp    $0x8,%esi
jl     1130 <websocket_xmask+0x30>
mov    %edi,%eax
and    $0x3,%eax
test   %rax,%rax
je     1120 <websocket_xmask+0x20>
xor    %edx,(%rdi)
mov    $0x4,%ecx
sub    %rax,%rcx
add    %rcx,%rdi
sub    %ecx,%esi
xchg   %ax,%ax
xor    %edx,(%rdi)
mov    %esi,%eax
lea    -0x4(%rax),%esi
add    $0x4,%rdi
cmp    $0x7,%eax
ja     1120 <websocket_xmask+0x20>
lea    -0x1(%rsi),%eax
cmp    $0x4,%eax
jb     1143 <websocket_xmask+0x43>
add    $0xfffffffb,%esi
cmp    $0x2,%esi
ja     1145 <websocket_xmask+0x45>
xor    %edx,0x10(%rdi)
xor    %edx,(%rdi)
ret

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

LLVM IR (-O2):
define void @websocket_xmask(i8* %0, i32 %1, i32 %2) {
%4 = icmp sgt i32 %1, 7
br i1 %4, label %5, label %34
5: ; preds = %3
%6 = ptrtoint i8* %0 to i64
%7 = and i64 %6, 3
%8 = sub nuw nsw i64 4, %7
%9 = icmp eq i64 %7, 0
br i1 %9, label %18, label %10
10: ; preds = %5
%11 = bitcast i8* %0 to i32*
%12 = load i32, i32* %11
%13 = xor i32 %12, %2
store i32 %13, i32* %11
%14 = add i64 %8, %6
%15 = inttoptr i64 %14 to i8*
%16 = trunc i64 %8 to i32
%17 = sub nuw nsw i32 %1, %16
br label %18
18: ; preds = %10, %5
%19 = phi i8* [ %15, %10 ], [ %0, %5 ]
%20 = phi i32 [ %17, %10 ], [ %1, %5 ]
br label %21
21: ; preds = %18, %21
%22 = phi i8* [ %30, %21 ], [ %19, %18 ]
%23 = phi i32 [ %27, %21 ], [ %20, %18 ]
%24 = bitcast i8* %22 to i32*
%25 = load i32, i32* %24
%26 = xor i32 %25, %2
store i32 %26, i32* %24
%27 = add nsw i32 %23, -4
%28 = ptrtoint i8* %22 to i64
%29 = add i64 %28, 4
%30 = inttoptr i64 %29 to i8*
%31 = icmp ugt i32 %23, 7
br i1 %31, label %21, label %32
32: ; preds = %21
%33 = inttoptr i64 %29 to i8*
br label %34
34: ; preds = %32, %3
%35 = phi i32 [ %1, %3 ], [ %27, %32 ]
%36 = phi i8* [ %0, %3 ], [ %33, %32 ]
switch i32 %35, label %46 [
i32 7, label %37
i32 6, label %37
i32 5, label %37
i32 4, label %42
i32 3, label %42
i32 2, label %42
i32 1, label %42
]
37: ; preds = %34, %34, %34
%38 = getelementptr inbounds i8, i8* %36, i64 16
%39 = bitcast i8* %38 to i32*
%40 = load i32, i32* %39
%41 = xor i32 %40, %2
store i32 %41, i32* %39
br label %42
42: ; preds = %34, %37, %34, %34, %34
%43 = bitcast i8* %36 to i32*
%44 = load i32, i32* %43
%45 = xor i32 %44, %2
store i32 %45, i32* %43
br label %46
46: ; preds = %42, %34
ret void
}