#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*/ outportb(int, unsigned char);
void unmaskIRQ(unsigned char irq) {
  if (irq == 0xFF) {
    outportb(0x21, 0x00);
    outportb(0xA1, 0x00);
  } else {
    irq = irq & (1 << irq);
    if (irq < 8)
      outportb(0x21, irq & 0x00);
    else
      outportb(0xA1, irq >> 8);
  }
}


x86 assembly (clang, -O0):
<unmaskIRQ>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %dil,%al
mov    %al,-0x1(%rbp)
movzbl -0x1(%rbp),%eax
cmp    $0xff,%eax
jne    114a <unmaskIRQ+0x3a>
mov    $0x21,%edi
xor    %esi,%esi
call   1030 <outportb@plt>
mov    $0xa1,%edi
xor    %esi,%esi
call   1030 <outportb@plt>
jmp    119f <unmaskIRQ+0x8f>
movzbl -0x1(%rbp),%eax
movzbl -0x1(%rbp),%ecx
mov    $0x1,%edx
shl    %cl,%edx
mov    %edx,%ecx
and    %ecx,%eax
mov    %al,-0x1(%rbp)
movzbl -0x1(%rbp),%eax
cmp    $0x8,%eax
jge    1186 <unmaskIRQ+0x76>
movzbl -0x1(%rbp),%eax
and    $0x0,%eax
mov    $0x21,%edi
movzbl %al,%esi
call   1030 <outportb@plt>
jmp    119a <unmaskIRQ+0x8a>
movzbl -0x1(%rbp),%eax
sar    $0x8,%eax
mov    $0xa1,%edi
movzbl %al,%esi
call   1030 <outportb@plt>
jmp    119f <unmaskIRQ+0x8f>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<unmaskIRQ>:
cmp    $0xff,%dil
je     1137 <unmaskIRQ+0x27>
mov    $0x1,%eax
mov    %edi,%ecx
shl    %cl,%eax
and    %dil,%al
xor    %edi,%edi
cmp    $0x8,%al
setae  %dil
shl    $0x7,%edi
or     $0x21,%edi
xor    %esi,%esi
jmp    1030 <outportb@plt>
push   %rax
mov    $0x21,%edi
xor    %esi,%esi
call   1030 <outportb@plt>
mov    $0xa1,%edi
add    $0x8,%rsp
xor    %esi,%esi
jmp    1030 <outportb@plt>

LLVM IR (-O0):
define void @unmaskIRQ(i8 zeroext %0) {
%2 = alloca i8
store i8 %0, i8* %2
%3 = load i8, i8* %2
%4 = zext i8 %3 to i32
%5 = icmp eq i32 %4, 255
br i1 %5, label %6, label %9
6: ; preds = %1
%7 = call i32 @outportb(i32 33, i8 zeroext 0)
%8 = call i32 @outportb(i32 161, i8 zeroext 0)
br label %33
9: ; preds = %1
%10 = load i8, i8* %2
%11 = zext i8 %10 to i32
%12 = load i8, i8* %2
%13 = zext i8 %12 to i32
%14 = shl i32 1, %13
%15 = and i32 %11, %14
%16 = trunc i32 %15 to i8
store i8 %16, i8* %2
%17 = load i8, i8* %2
%18 = zext i8 %17 to i32
%19 = icmp slt i32 %18, 8
br i1 %19, label %20, label %26
20: ; preds = %9
%21 = load i8, i8* %2
%22 = zext i8 %21 to i32
%23 = and i32 %22, 0
%24 = trunc i32 %23 to i8
%25 = call i32 @outportb(i32 33, i8 zeroext %24)
br label %32
26: ; preds = %9
%27 = load i8, i8* %2
%28 = zext i8 %27 to i32
%29 = ashr i32 %28, 8
%30 = trunc i32 %29 to i8
%31 = call i32 @outportb(i32 161, i8 zeroext %30)
br label %32
32: ; preds = %26, %20
br label %33
33: ; preds = %32, %6
ret void
}

LLVM IR (-O2):
define void @unmaskIRQ(i8 zeroext %0) {
%2 = icmp eq i8 %0, -1
br i1 %2, label %3, label %5
3: ; preds = %1
%4 = tail call i32 @outportb(i32 33, i8 zeroext 0)
br label %12
5: ; preds = %1
%6 = zext i8 %0 to i32
%7 = shl nuw i32 1, %6
%8 = trunc i32 %7 to i8
%9 = and i8 %8, %0
%10 = icmp ult i8 %9, 8
%11 = select i1 %10, i32 33, i32 161
br label %12
12: ; preds = %5, %3
%13 = phi i32 [ 161, %3 ], [ %11, %5 ]
%14 = tail call i32 @outportb(i32 %13, i8 zeroext 0)
ret void
}