#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*/ outb(int, scalar_t__);
void write_reg_high(short port, unsigned char reg, unsigned char value) {
  unsigned char outval = 0xE0 | 0x10 | reg;
  outb(outval, port + 0);
  outval &= 0x40 | 0x10 | 0x0f;
  outb(outval, port + 0);
  outb(outval, port + 0);
  outval = 0x40 | 0x10 | value;
  outb(outval, port + 0);
  outval &= 0x10 | 0x0f;
  outb(outval, port + 0);
  outb(outval, port + 0);
  outb(0xE0 | 0x10 | outval, port + 0);
}


x86 assembly (clang, -O0):
<write_reg_high>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %dl,%al
mov    %sil,%cl
mov    %di,%dx
mov    %dx,-0x2(%rbp)
mov    %cl,-0x3(%rbp)
mov    %al,-0x4(%rbp)
movzbl -0x3(%rbp),%eax
or     $0xf0,%eax
mov    %al,-0x5(%rbp)
movzbl -0x5(%rbp),%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x5(%rbp),%eax
and    $0x5f,%eax
mov    %al,-0x5(%rbp)
movzbl -0x5(%rbp),%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x5(%rbp),%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x4(%rbp),%eax
or     $0x50,%eax
mov    %al,-0x5(%rbp)
movzbl -0x5(%rbp),%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x5(%rbp),%eax
and    $0x1f,%eax
mov    %al,-0x5(%rbp)
movzbl -0x5(%rbp),%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x5(%rbp),%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
movzbl -0x5(%rbp),%edi
or     $0xf0,%edi
movswl -0x2(%rbp),%eax
add    $0x0,%eax
movslq %eax,%rsi
call   1030 <outb@plt>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<write_reg_high>:
push   %rbp
push   %r14
push   %rbx
mov    %edx,%r14d
or     $0xf0,%sil
movzbl %sil,%ebp
movslq %edi,%rbx
mov    %ebp,%edi
mov    %rbx,%rsi
call   1030 <outb@plt>
and    $0x5f,%bpl
movzbl %bpl,%ebp
mov    %ebp,%edi
mov    %rbx,%rsi
call   1030 <outb@plt>
mov    %ebp,%edi
mov    %rbx,%rsi
call   1030 <outb@plt>
or     $0x50,%r14b
movzbl %r14b,%ebp
mov    %ebp,%edi
mov    %rbx,%rsi
call   1030 <outb@plt>
and    $0x1f,%bpl
movzbl %bpl,%ebp
mov    %ebp,%edi
mov    %rbx,%rsi
call   1030 <outb@plt>
mov    %ebp,%edi
mov    %rbx,%rsi
call   1030 <outb@plt>
or     $0xf0,%ebp
mov    %ebp,%edi
mov    %rbx,%rsi
pop    %rbx
pop    %r14
pop    %rbp
jmp    1030 <outb@plt>

LLVM IR (-O0):
define void @write_reg_high(i16 signext %0, i8 zeroext %1, i8 zeroext %2) {
%4 = alloca i16
%5 = alloca i8
%6 = alloca i8
%7 = alloca i8
store i16 %0, i16* %4
store i8 %1, i8* %5
store i8 %2, i8* %6
%8 = load i8, i8* %5
%9 = zext i8 %8 to i32
%10 = or i32 240, %9
%11 = trunc i32 %10 to i8
store i8 %11, i8* %7
%12 = load i8, i8* %7
%13 = zext i8 %12 to i32
%14 = load i16, i16* %4
%15 = sext i16 %14 to i32
%16 = add nsw i32 %15, 0
%17 = sext i32 %16 to i64
%18 = call i32 @outb(i32 %13, i64 %17)
%19 = load i8, i8* %7
%20 = zext i8 %19 to i32
%21 = and i32 %20, 95
%22 = trunc i32 %21 to i8
store i8 %22, i8* %7
%23 = load i8, i8* %7
%24 = zext i8 %23 to i32
%25 = load i16, i16* %4
%26 = sext i16 %25 to i32
%27 = add nsw i32 %26, 0
%28 = sext i32 %27 to i64
%29 = call i32 @outb(i32 %24, i64 %28)
%30 = load i8, i8* %7
%31 = zext i8 %30 to i32
%32 = load i16, i16* %4
%33 = sext i16 %32 to i32
%34 = add nsw i32 %33, 0
%35 = sext i32 %34 to i64
%36 = call i32 @outb(i32 %31, i64 %35)
%37 = load i8, i8* %6
%38 = zext i8 %37 to i32
%39 = or i32 80, %38
%40 = trunc i32 %39 to i8
store i8 %40, i8* %7
%41 = load i8, i8* %7
%42 = zext i8 %41 to i32
%43 = load i16, i16* %4
%44 = sext i16 %43 to i32
%45 = add nsw i32 %44, 0
%46 = sext i32 %45 to i64
%47 = call i32 @outb(i32 %42, i64 %46)
%48 = load i8, i8* %7
%49 = zext i8 %48 to i32
%50 = and i32 %49, 31
%51 = trunc i32 %50 to i8
store i8 %51, i8* %7
%52 = load i8, i8* %7
%53 = zext i8 %52 to i32
%54 = load i16, i16* %4
%55 = sext i16 %54 to i32
%56 = add nsw i32 %55, 0
%57 = sext i32 %56 to i64
%58 = call i32 @outb(i32 %53, i64 %57)
%59 = load i8, i8* %7
%60 = zext i8 %59 to i32
%61 = load i16, i16* %4
%62 = sext i16 %61 to i32
%63 = add nsw i32 %62, 0
%64 = sext i32 %63 to i64
%65 = call i32 @outb(i32 %60, i64 %64)
%66 = load i8, i8* %7
%67 = zext i8 %66 to i32
%68 = or i32 240, %67
%69 = load i16, i16* %4
%70 = sext i16 %69 to i32
%71 = add nsw i32 %70, 0
%72 = sext i32 %71 to i64
%73 = call i32 @outb(i32 %68, i64 %72)
ret void
}

LLVM IR (-O2):
define void @write_reg_high(i16 signext %0, i8 zeroext %1, i8 zeroext %2) {
%4 = or i8 %1, -16
%5 = zext i8 %4 to i32
%6 = sext i16 %0 to i64
%7 = tail call i32 @outb(i32 %5, i64 %6)
%8 = and i8 %4, 95
%9 = zext i8 %8 to i32
%10 = tail call i32 @outb(i32 %9, i64 %6)
%11 = tail call i32 @outb(i32 %9, i64 %6)
%12 = or i8 %2, 80
%13 = zext i8 %12 to i32
%14 = tail call i32 @outb(i32 %13, i64 %6)
%15 = and i8 %12, 31
%16 = zext i8 %15 to i32
%17 = tail call i32 @outb(i32 %16, i64 %6)
%18 = tail call i32 @outb(i32 %16, i64 %6)
%19 = or i32 %16, 240
%20 = tail call i32 @outb(i32 %19, i64 %6)
ret void
}