unsigned long CANMessageGetRx(unsigned char *pucData, unsigned long *pulMsgID) {
  unsigned short usCmdMaskReg;
  unsigned short usArbReg0, usArbReg1;
  unsigned short usMsgCtrl;
  unsigned long ulBytes;
  unsigned short *pusData;
  usCmdMaskReg =
      (0x00000002 | 0x00000001 | 0x00000010 | 0x00000008 | 0x00000020);
  (*((volatile unsigned long *)(0x40040000 + 0x00000084))) = usCmdMaskReg;
  (*((volatile unsigned long *)(0x40040000 + 0x00000080))) = 1 & 0x0000003F;
  while ((*((volatile unsigned long *)(0x40040000 + 0x00000080))) &
         0x00008000) {
  }
  usArbReg0 = (*((volatile unsigned long *)(0x40040000 + 0x00000090)));
  usArbReg1 = (*((volatile unsigned long *)(0x40040000 + 0x00000094)));
  usMsgCtrl = (*((volatile unsigned long *)(0x40040000 + 0x00000098)));
  *pulMsgID = ((usArbReg1 & 0x00001FFF) << 16) | usArbReg0;
  if ((usMsgCtrl & (0x00008000 | 0x00004000)) == 0x00008000) {
    ulBytes = usMsgCtrl & 0x0000000F;
    pusData = (unsigned short *)pucData;
    pusData[0] = (*((volatile unsigned long *)(0x40040000 + 0x0000009C)));
    pusData[1] = (*((volatile unsigned long *)(0x40040000 + 0x000000A0)));
    pusData[2] = (*((volatile unsigned long *)(0x40040000 + 0x000000A4)));
    pusData[3] = (*((volatile unsigned long *)(0x40040000 + 0x000000A8)));
    (*((volatile unsigned long *)(0x40040000 + 0x00000084))) = 0x00000004;
    (*((volatile unsigned long *)(0x40040000 + 0x00000080))) = 1;
    while ((*((volatile unsigned long *)(0x40040000 + 0x00000080))) &
           0x00008000) {
    }
  } else {
    ulBytes = 0xffffffff;
  }
  return (ulBytes);
}


x86 assembly (clang, -O0):
<CANMessageGetRx>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movw   $0x3b,-0x12(%rbp)
movzwl -0x12(%rbp),%eax
mov    %eax,%ecx
mov    $0x40040084,%eax
mov    %rcx,(%rax)
mov    $0x40040080,%eax
movq   $0x1,(%rax)
mov    $0x40040080,%eax
mov    (%rax),%rax
and    $0x8000,%rax
cmp    $0x0,%rax
je     1149 <CANMessageGetRx+0x49>
jmp    112c <CANMessageGetRx+0x2c>
mov    $0x40040090,%eax
mov    (%rax),%rax
mov    %ax,-0x14(%rbp)
mov    $0x40040094,%eax
mov    (%rax),%rax
mov    %ax,-0x16(%rbp)
mov    $0x40040098,%eax
mov    (%rax),%rax
mov    %ax,-0x18(%rbp)
movzwl -0x16(%rbp),%eax
and    $0x1fff,%eax
shl    $0x10,%eax
movzwl -0x14(%rbp),%ecx
or     %ecx,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
movzwl -0x18(%rbp),%eax
and    $0xc000,%eax
cmp    $0x8000,%eax
jne    1237 <CANMessageGetRx+0x137>
movzwl -0x18(%rbp),%eax
and    $0xf,%eax
cltq
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    $0x4004009c,%eax
mov    (%rax),%rax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,(%rax)
mov    $0x400400a0,%eax
mov    (%rax),%rax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,0x2(%rax)
mov    $0x400400a4,%eax
mov    (%rax),%rax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,0x4(%rax)
mov    $0x400400a8,%eax
mov    (%rax),%rax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,0x6(%rax)
mov    $0x40040084,%eax
movq   $0x4,(%rax)
mov    $0x40040080,%eax
movq   $0x1,(%rax)
mov    $0x40040080,%eax
mov    (%rax),%rax
and    $0x8000,%rax
cmp    $0x0,%rax
je     1232 <CANMessageGetRx+0x132>
jmp    1215 <CANMessageGetRx+0x115>
jmp    1240 <CANMessageGetRx+0x140>
mov    $0xffffffff,%eax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<CANMessageGetRx>:
movq   $0x3b,0x40040084
movq   $0x1,0x40040080
nopl   0x0(%rax,%rax,1)
testq  $0x8000,0x40040080
jne    1120 <CANMessageGetRx+0x20>
mov    0x40040090,%rax
40
mov    0x40040094,%rdx
40
mov    0x40040098,%rcx
40
shl    $0x10,%edx
and    $0x1fff0000,%edx
movzwl %ax,%eax
or     %rdx,%rax
mov    %rax,(%rsi)
mov    %ecx,%edx
and    $0xc000,%edx
mov    $0xffffffff,%eax
cmp    $0x8000,%edx
jne    11d4 <CANMessageGetRx+0xd4>
mov    0x4004009c,%rax
40
mov    %ax,(%rdi)
mov    0x400400a0,%rax
40
mov    %ax,0x2(%rdi)
mov    0x400400a4,%rax
40
mov    %ax,0x4(%rdi)
mov    0x400400a8,%rax
40
mov    %ax,0x6(%rdi)
movq   $0x4,0x40040084
movq   $0x1,0x40040080
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
testq  $0x8000,0x40040080
jne    11c0 <CANMessageGetRx+0xc0>
and    $0xf,%ecx
mov    %rcx,%rax
ret

LLVM IR (-O0):
define i64 @CANMessageGetRx(i8* %0, i64* %1) {
%3 = alloca i8*
%4 = alloca i64*
%5 = alloca i16
%6 = alloca i16
%7 = alloca i16
%8 = alloca i16
%9 = alloca i64
%10 = alloca i16*
store i8* %0, i8** %3
store i64* %1, i64** %4
store i16 59, i16* %5
%11 = load i16, i16* %5
%12 = zext i16 %11 to i64
store volatile i64 %12, i64* inttoptr (i64 1074004100 to i64*)
store volatile i64 1, i64* inttoptr (i64 1074004096 to i64*)
br label %13
13: ; preds = %17, %2
%14 = load volatile i64, i64* inttoptr (i64 1074004096 to i64*)
%15 = and i64 %14, 32768
%16 = icmp ne i64 %15, 0
br i1 %16, label %17, label %18
17: ; preds = %13
br label %13
18: ; preds = %13
%19 = load volatile i64, i64* inttoptr (i64 1074004112 to i64*)
%20 = trunc i64 %19 to i16
store i16 %20, i16* %6
%21 = load volatile i64, i64* inttoptr (i64 1074004116 to i64*)
%22 = trunc i64 %21 to i16
store i16 %22, i16* %7
%23 = load volatile i64, i64* inttoptr (i64 1074004120 to i64*)
%24 = trunc i64 %23 to i16
store i16 %24, i16* %8
%25 = load i16, i16* %7
%26 = zext i16 %25 to i32
%27 = and i32 %26, 8191
%28 = shl i32 %27, 16
%29 = load i16, i16* %6
%30 = zext i16 %29 to i32
%31 = or i32 %28, %30
%32 = sext i32 %31 to i64
%33 = load i64*, i64** %4
store i64 %32, i64* %33
%34 = load i16, i16* %8
%35 = zext i16 %34 to i32
%36 = and i32 %35, 49152
%37 = icmp eq i32 %36, 32768
br i1 %37, label %38, label %67
38: ; preds = %18
%39 = load i16, i16* %8
%40 = zext i16 %39 to i32
%41 = and i32 %40, 15
%42 = sext i32 %41 to i64
store i64 %42, i64* %9
%43 = load i8*, i8** %3
%44 = bitcast i8* %43 to i16*
store i16* %44, i16** %10
%45 = load volatile i64, i64* inttoptr (i64 1074004124 to i64*)
%46 = trunc i64 %45 to i16
%47 = load i16*, i16** %10
%48 = getelementptr inbounds i16, i16* %47, i64 0
store i16 %46, i16* %48
%49 = load volatile i64, i64* inttoptr (i64 1074004128 to i64*)
%50 = trunc i64 %49 to i16
%51 = load i16*, i16** %10
%52 = getelementptr inbounds i16, i16* %51, i64 1
store i16 %50, i16* %52
%53 = load volatile i64, i64* inttoptr (i64 1074004132 to i64*)
%54 = trunc i64 %53 to i16
%55 = load i16*, i16** %10
%56 = getelementptr inbounds i16, i16* %55, i64 2
store i16 %54, i16* %56
%57 = load volatile i64, i64* inttoptr (i64 1074004136 to i64*)
%58 = trunc i64 %57 to i16
%59 = load i16*, i16** %10
%60 = getelementptr inbounds i16, i16* %59, i64 3
store i16 %58, i16* %60
store volatile i64 4, i64* inttoptr (i64 1074004100 to i64*)
store volatile i64 1, i64* inttoptr (i64 1074004096 to i64*)
br label %61
61: ; preds = %65, %38
%62 = load volatile i64, i64* inttoptr (i64 1074004096 to i64*)
%63 = and i64 %62, 32768
%64 = icmp ne i64 %63, 0
br i1 %64, label %65, label %66
65: ; preds = %61
br label %61
66: ; preds = %61
br label %68
67: ; preds = %18
store i64 4294967295, i64* %9
br label %68
68: ; preds = %67, %66
%69 = load i64, i64* %9
ret i64 %69
}

LLVM IR (-O2):
define i64 @CANMessageGetRx(i8* nocapture writeonly %0, i64* nocapture writeonly %1) {
store volatile i64 59, i64* inttoptr (i64 1074004100 to i64*)
store volatile i64 1, i64* inttoptr (i64 1074004096 to i64*)
br label %3
3: ; preds = %3, %2
%4 = load volatile i64, i64* inttoptr (i64 1074004096 to i64*)
%5 = and i64 %4, 32768
%6 = icmp eq i64 %5, 0
br i1 %6, label %7, label %3
7: ; preds = %3
%8 = load volatile i64, i64* inttoptr (i64 1074004112 to i64*)
%9 = load volatile i64, i64* inttoptr (i64 1074004116 to i64*)
%10 = load volatile i64, i64* inttoptr (i64 1074004120 to i64*)
%11 = shl i64 %9, 16
%12 = and i64 %11, 536805376
%13 = and i64 %8, 65535
%14 = or i64 %12, %13
store i64 %14, i64* %1
%15 = and i64 %10, 49152
%16 = icmp eq i64 %15, 32768
br i1 %16, label %17, label %39
17: ; preds = %7
%18 = bitcast i8* %0 to i16*
%19 = load volatile i64, i64* inttoptr (i64 1074004124 to i64*)
%20 = trunc i64 %19 to i16
store i16 %20, i16* %18
%21 = load volatile i64, i64* inttoptr (i64 1074004128 to i64*)
%22 = trunc i64 %21 to i16
%23 = getelementptr inbounds i8, i8* %0, i64 2
%24 = bitcast i8* %23 to i16*
store i16 %22, i16* %24
%25 = load volatile i64, i64* inttoptr (i64 1074004132 to i64*)
%26 = trunc i64 %25 to i16
%27 = getelementptr inbounds i8, i8* %0, i64 4
%28 = bitcast i8* %27 to i16*
store i16 %26, i16* %28
%29 = load volatile i64, i64* inttoptr (i64 1074004136 to i64*)
%30 = trunc i64 %29 to i16
%31 = getelementptr inbounds i8, i8* %0, i64 6
%32 = bitcast i8* %31 to i16*
store i16 %30, i16* %32
store volatile i64 4, i64* inttoptr (i64 1074004100 to i64*)
store volatile i64 1, i64* inttoptr (i64 1074004096 to i64*)
br label %33
33: ; preds = %33, %17
%34 = load volatile i64, i64* inttoptr (i64 1074004096 to i64*)
%35 = and i64 %34, 32768
%36 = icmp eq i64 %35, 0
br i1 %36, label %37, label %33
37: ; preds = %33
%38 = and i64 %10, 15
br label %39
39: ; preds = %37, %7
%40 = phi i64 [ 4294967295, %7 ], [ %38, %37 ]
ret i64 %40
}