#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 */
typedef int uint8_t;

/* Variables and functions */
int /*<<< orphan*/ CLEAR_TDI();
int /*<<< orphan*/ JTAG_CLEAR_CLOCK();
int /*<<< orphan*/ JTAG_SET_CLOCK();
int /*<<< orphan*/ JTAG_SPEED();
int /*<<< orphan*/ SET_TDI();
void bit_out(uint8_t byte, int length) {
  for (length; length > 0; length--) {
    JTAG_SET_CLOCK();
    if (byte & 1)
      SET_TDI();
    else
      CLEAR_TDI();
    byte = byte >> 1;
    JTAG_SPEED();
    JTAG_CLEAR_CLOCK();
    JTAG_SPEED();
  }
}


x86 assembly (clang, -O0):
<bit_out>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
cmpl   $0x0,-0x8(%rbp)
jle    11bd <bit_out+0x6d>
mov    $0x0,%al
call   1060 <JTAG_SET_CLOCK@plt>
mov    -0x4(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     118a <bit_out+0x3a>
mov    $0x0,%al
call   1040 <SET_TDI@plt>
jmp    1191 <bit_out+0x41>
mov    $0x0,%al
call   1070 <CLEAR_TDI@plt>
mov    -0x4(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x4(%rbp)
mov    $0x0,%al
call   1030 <JTAG_SPEED@plt>
mov    $0x0,%al
call   1050 <JTAG_CLEAR_CLOCK@plt>
mov    $0x0,%al
call   1030 <JTAG_SPEED@plt>
mov    -0x8(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x8(%rbp)
jmp    115e <bit_out+0xe>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<bit_out>:
push   %rbp
push   %rbx
push   %rax
test   %esi,%esi
jle    119a <bit_out+0x4a>
mov    %esi,%ebx
mov    %edi,%ebp
add    $0x1,%ebx
jmp    1184 <bit_out+0x34>
call   1070 <CLEAR_TDI@plt>
sar    %ebp
xor    %eax,%eax
call   1030 <JTAG_SPEED@plt>
xor    %eax,%eax
call   1050 <JTAG_CLEAR_CLOCK@plt>
xor    %eax,%eax
call   1030 <JTAG_SPEED@plt>
add    $0xffffffff,%ebx
cmp    $0x1,%ebx
jle    119a <bit_out+0x4a>
xor    %eax,%eax
call   1060 <JTAG_SET_CLOCK@plt>
xor    %eax,%eax
test   $0x1,%bpl
je     1160 <bit_out+0x10>
call   1040 <SET_TDI@plt>
jmp    1165 <bit_out+0x15>
add    $0x8,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
define void @bit_out(i32 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32
store i32 %0, i32* %3
store i32 %1, i32* %4
%5 = load i32, i32* %4
br label %6
6: ; preds = %24, %2
%7 = load i32, i32* %4
%8 = icmp sgt i32 %7, 0
br i1 %8, label %9, label %27
9: ; preds = %6
%10 = call i32 (...) @JTAG_SET_CLOCK()
%11 = load i32, i32* %3
%12 = and i32 %11, 1
%13 = icmp ne i32 %12, 0
br i1 %13, label %14, label %16
14: ; preds = %9
%15 = call i32 (...) @SET_TDI()
br label %18
16: ; preds = %9
%17 = call i32 (...) @CLEAR_TDI()
br label %18
18: ; preds = %16, %14
%19 = load i32, i32* %3
%20 = ashr i32 %19, 1
store i32 %20, i32* %3
%21 = call i32 (...) @JTAG_SPEED()
%22 = call i32 (...) @JTAG_CLEAR_CLOCK()
%23 = call i32 (...) @JTAG_SPEED()
br label %24
24: ; preds = %18
%25 = load i32, i32* %4
%26 = add nsw i32 %25, -1
store i32 %26, i32* %4
br label %6
27: ; preds = %6
ret void
}

LLVM IR (-O2):
define void @bit_out(i32 %0, i32 %1) {
%3 = icmp sgt i32 %1, 0
br i1 %3, label %4, label %21
4: ; preds = %2, %14
%5 = phi i32 [ %19, %14 ], [ %1, %2 ]
%6 = phi i32 [ %15, %14 ], [ %0, %2 ]
%7 = tail call i32 (...) @JTAG_SET_CLOCK()
%8 = and i32 %6, 1
%9 = icmp eq i32 %8, 0
br i1 %9, label %12, label %10
10: ; preds = %4
%11 = tail call i32 (...) @SET_TDI()
br label %14
12: ; preds = %4
%13 = tail call i32 (...) @CLEAR_TDI()
br label %14
14: ; preds = %12, %10
%15 = ashr i32 %6, 1
%16 = tail call i32 (...) @JTAG_SPEED()
%17 = tail call i32 (...) @JTAG_CLEAR_CLOCK()
%18 = tail call i32 (...) @JTAG_SPEED()
%19 = add nsw i32 %5, -1
%20 = icmp sgt i32 %5, 1
br i1 %20, label %4, label %21
21: ; preds = %14, %2
ret void
}