char process_keyboard(struct ep_status *ep, unsigned char *buf,
                      unsigned char len) {
  unsigned char m, i;
  if (len < 6)
    return 0;
  m = (*(unsigned char *)(0x1142));
  for (i = 0; i < 8; i++)
    (*(unsigned char *)(0x1143 + (8 * m + i))) = buf[i];
  (*(unsigned char *)(0x1142)) = (m + 1) & 0x07;
  return 1;
}


x86 assembly (clang, -O0):
<process_keyboard>:
push   %rbp
mov    %rsp,%rbp
mov    %dl,%al
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %al,-0x19(%rbp)
movzbl -0x19(%rbp),%eax
cmp    $0x6,%eax
jge    1127 <process_keyboard+0x27>
movb   $0x0,-0x1(%rbp)
jmp    1187 <process_keyboard+0x87>
mov    $0x1142,%eax
mov    (%rax),%al
mov    %al,-0x1a(%rbp)
movb   $0x0,-0x1b(%rbp)
movzbl -0x1b(%rbp),%eax
cmp    $0x8,%eax
jge    1170 <process_keyboard+0x70>
mov    -0x18(%rbp),%rax
movzbl -0x1b(%rbp),%ecx
mov    (%rax,%rcx,1),%cl
movzbl -0x1a(%rbp),%eax
shl    $0x3,%eax
movzbl -0x1b(%rbp),%edx
add    %edx,%eax
add    $0x1143,%eax
cltq
mov    %cl,(%rax)
mov    -0x1b(%rbp),%al
add    $0x1,%al
mov    %al,-0x1b(%rbp)
jmp    1135 <process_keyboard+0x35>
movzbl -0x1a(%rbp),%eax
add    $0x1,%eax
and    $0x7,%eax
mov    %al,%cl
mov    $0x1142,%eax
mov    %cl,(%rax)
movb   $0x1,-0x1(%rbp)
movsbl -0x1(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<process_keyboard>:
cmp    $0x6,%dl
jae    1108 <process_keyboard+0x8>
xor    %eax,%eax
ret
movzbl 0x1142,%eax
mov    (%rsi),%cl
mov    %cl,0x1143(,%rax,8)
mov    0x1(%rsi),%cl
mov    %cl,0x1144(,%rax,8)
mov    0x2(%rsi),%cl
mov    %cl,0x1145(,%rax,8)
mov    0x3(%rsi),%cl
mov    %cl,0x1146(,%rax,8)
mov    0x4(%rsi),%cl
mov    %cl,0x1147(,%rax,8)
mov    0x5(%rsi),%cl
mov    %cl,0x1148(,%rax,8)
mov    0x6(%rsi),%cl
mov    %cl,0x1149(,%rax,8)
mov    0x7(%rsi),%cl
mov    %cl,0x114a(,%rax,8)
add    $0x1,%eax
and    $0x7,%al
mov    %al,0x1142
mov    $0x1,%al
ret

LLVM IR (-O0):
%struct.ep_status = type opaque
define signext i8 @process_keyboard(%struct.ep_status* %0, i8* %1, i8 zeroext %2) {
%4 = alloca i8
%5 = alloca %struct.ep_status*
%6 = alloca i8*
%7 = alloca i8
%8 = alloca i8
%9 = alloca i8
store %struct.ep_status* %0, %struct.ep_status** %5
store i8* %1, i8** %6
store i8 %2, i8* %7
%10 = load i8, i8* %7
%11 = zext i8 %10 to i32
%12 = icmp slt i32 %11, 6
br i1 %12, label %13, label %14
13: ; preds = %3
store i8 0, i8* %4
br label %44
14: ; preds = %3
%15 = load i8, i8* inttoptr (i64 4418 to i8*)
store i8 %15, i8* %8
store i8 0, i8* %9
br label %16
16: ; preds = %35, %14
%17 = load i8, i8* %9
%18 = zext i8 %17 to i32
%19 = icmp slt i32 %18, 8
br i1 %19, label %20, label %38
20: ; preds = %16
%21 = load i8*, i8** %6
%22 = load i8, i8* %9
%23 = zext i8 %22 to i64
%24 = getelementptr inbounds i8, i8* %21, i64 %23
%25 = load i8, i8* %24
%26 = load i8, i8* %8
%27 = zext i8 %26 to i32
%28 = mul nsw i32 8, %27
%29 = load i8, i8* %9
%30 = zext i8 %29 to i32
%31 = add nsw i32 %28, %30
%32 = add nsw i32 4419, %31
%33 = sext i32 %32 to i64
%34 = inttoptr i64 %33 to i8*
store i8 %25, i8* %34
br label %35
35: ; preds = %20
%36 = load i8, i8* %9
%37 = add i8 %36, 1
store i8 %37, i8* %9
br label %16
38: ; preds = %16
%39 = load i8, i8* %8
%40 = zext i8 %39 to i32
%41 = add nsw i32 %40, 1
%42 = and i32 %41, 7
%43 = trunc i32 %42 to i8
store i8 %43, i8* inttoptr (i64 4418 to i8*)
store i8 1, i8* %4
br label %44
44: ; preds = %38, %13
%45 = load i8, i8* %4
ret i8 %45
}

LLVM IR (-O2):
%struct.ep_status = type opaque
define signext i8 @process_keyboard(%struct.ep_status* nocapture readnone %0, i8* nocapture %1, i8 zeroext %2) {
%4 = icmp ult i8 %2, 6
br i1 %4, label %42, label %5
5: ; preds = %3
%6 = load i8, i8* inttoptr (i64 4418 to i8*)
%7 = zext i8 %6 to i64
%8 = shl nuw nsw i64 %7, 3
%9 = add nuw nsw i64 %8, 4419
%10 = load i8, i8* %1
%11 = inttoptr i64 %9 to i8*
store i8 %10, i8* %11
%12 = getelementptr inbounds i8, i8* %1, i64 1
%13 = load i8, i8* %12
%14 = add nuw nsw i64 %8, 4420
%15 = inttoptr i64 %14 to i8*
store i8 %13, i8* %15
%16 = getelementptr inbounds i8, i8* %1, i64 2
%17 = load i8, i8* %16
%18 = add nuw nsw i64 %8, 4421
%19 = inttoptr i64 %18 to i8*
store i8 %17, i8* %19
%20 = getelementptr inbounds i8, i8* %1, i64 3
%21 = load i8, i8* %20
%22 = add nuw nsw i64 %8, 4422
%23 = inttoptr i64 %22 to i8*
store i8 %21, i8* %23
%24 = getelementptr inbounds i8, i8* %1, i64 4
%25 = load i8, i8* %24
%26 = add nuw nsw i64 %8, 4423
%27 = inttoptr i64 %26 to i8*
store i8 %25, i8* %27
%28 = getelementptr inbounds i8, i8* %1, i64 5
%29 = load i8, i8* %28
%30 = add nuw nsw i64 %8, 4424
%31 = inttoptr i64 %30 to i8*
store i8 %29, i8* %31
%32 = getelementptr inbounds i8, i8* %1, i64 6
%33 = load i8, i8* %32
%34 = add nuw nsw i64 %8, 4425
%35 = inttoptr i64 %34 to i8*
store i8 %33, i8* %35
%36 = getelementptr inbounds i8, i8* %1, i64 7
%37 = load i8, i8* %36
%38 = add nuw nsw i64 %8, 4426
%39 = inttoptr i64 %38 to i8*
store i8 %37, i8* %39
%40 = add i8 %6, 1
%41 = and i8 %40, 7
store i8 %41, i8* inttoptr (i64 4418 to i8*)
br label %42
42: ; preds = %3, %5
%43 = phi i8 [ 1, %5 ], [ 0, %3 ]
ret i8 %43
}