void setPaletteRegister(unsigned char index, unsigned char red,
                        unsigned char green, unsigned char blue) {
  asm("cli");
  outb(0x3C6, 0xFF);
  outb(0x3C8, index);
  outb(0x3C9, red >> 2);
  outb(0x3C9, green >> 2);
  outb(0x3C9, blue >> 2);
  asm("sti");
}


x86 assembly (clang, -O0):
<setPaletteRegister>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %cl,%al
mov    %dl,%cl
mov    %sil,%dl
mov    %dil,%sil
mov    %sil,-0x1(%rbp)
mov    %dl,-0x2(%rbp)
mov    %cl,-0x3(%rbp)
mov    %al,-0x4(%rbp)
cli
mov    $0x3c6,%edi
mov    $0xff,%esi
mov    $0x0,%al
call   1030 <outb@plt>
movzbl -0x1(%rbp),%esi
mov    $0x3c8,%edi
mov    $0x0,%al
call   1030 <outb@plt>
movzbl -0x2(%rbp),%esi
sar    $0x2,%esi
mov    $0x3c9,%edi
mov    $0x0,%al
call   1030 <outb@plt>
movzbl -0x3(%rbp),%esi
sar    $0x2,%esi
mov    $0x3c9,%edi
mov    $0x0,%al
call   1030 <outb@plt>
movzbl -0x4(%rbp),%esi
sar    $0x2,%esi
mov    $0x3c9,%edi
mov    $0x0,%al
call   1030 <outb@plt>
sti
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<setPaletteRegister>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %ecx,%r14d
mov    %edx,%ebp
mov    %esi,%ebx
mov    %edi,%r15d
cli
mov    $0x3c6,%edi
mov    $0xff,%esi
xor    %eax,%eax
call   1030 <outb@plt>
mov    $0x3c8,%edi
mov    %r15d,%esi
xor    %eax,%eax
call   1030 <outb@plt>
shr    $0x2,%bl
movzbl %bl,%esi
mov    $0x3c9,%edi
xor    %eax,%eax
call   1030 <outb@plt>
shr    $0x2,%bpl
movzbl %bpl,%esi
mov    $0x3c9,%edi
xor    %eax,%eax
call   1030 <outb@plt>
shr    $0x2,%r14b
movzbl %r14b,%esi
mov    $0x3c9,%edi
xor    %eax,%eax
call   1030 <outb@plt>
sti
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @setPaletteRegister(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, i8 zeroext %3) {
%5 = alloca i8
%6 = alloca i8
%7 = alloca i8
%8 = alloca i8
store i8 %0, i8* %5
store i8 %1, i8* %6
store i8 %2, i8* %7
store i8 %3, i8* %8
%9 = call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 966, i32 255)
%10 = load i8, i8* %5
%11 = zext i8 %10 to i32
%12 = call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 968, i32 %11)
%13 = load i8, i8* %6
%14 = zext i8 %13 to i32
%15 = ashr i32 %14, 2
%16 = call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 969, i32 %15)
%17 = load i8, i8* %7
%18 = zext i8 %17 to i32
%19 = ashr i32 %18, 2
%20 = call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 969, i32 %19)
%21 = load i8, i8* %8
%22 = zext i8 %21 to i32
%23 = ashr i32 %22, 2
%24 = call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 969, i32 %23)
ret void
}

LLVM IR (-O2):
define void @setPaletteRegister(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, i8 zeroext %3) {
tail call void asm sideeffect "cli", "~{dirflag},~{fpsr},~{flags}"()
%5 = tail call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 966, i32 255)
%6 = zext i8 %0 to i32
%7 = tail call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 968, i32 %6)
%8 = lshr i8 %1, 2
%9 = zext i8 %8 to i32
%10 = tail call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 969, i32 %9)
%11 = lshr i8 %2, 2
%12 = zext i8 %11 to i32
%13 = tail call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 969, i32 %12)
%14 = lshr i8 %3, 2
%15 = zext i8 %14 to i32
%16 = tail call i32 (i32, i32, ...) bitcast (i32 (...)* @outb to i32 (i32, i32, ...)*)(i32 969, i32 %15)
tail call void asm sideeffect "sti", "~{dirflag},~{fpsr},~{flags}"()
ret void
}