void GrOffScreen4BPPLineDrawV(void *pvDisplayData, int lX, int lY1, int lY2,
                              unsigned int ulValue) {
  unsigned char *pucData;
  int lBytesPerRow;
  ;
  pucData = (unsigned char *)pvDisplayData;
  lBytesPerRow = (*(unsigned short *)(pucData + 1) + 1) / 2;
  pucData += (lBytesPerRow * lY1) + (lX / 2) + 6 + (16 * 3);
  if (lX & 1) {
    while (lY1 <= lY2) {
      *pucData = (*pucData & 0xf0) | ulValue;
      pucData += lBytesPerRow;
      lY1++;
    }
  } else {
    ulValue <<= 4;
    while (lY1 <= lY2) {
      *pucData = (*pucData & 0x0f) | ulValue;
      pucData += lBytesPerRow;
      lY1++;
    }
  }
}


x86 assembly (clang, -O0):
<GrOffScreen4BPPLineDrawV>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8d,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
movzwl 0x1(%rax),%eax
add    $0x1,%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%ecx
imul   -0x10(%rbp),%ecx
mov    -0xc(%rbp),%eax
mov    $0x2,%esi
cltd
idiv   %esi
add    %eax,%ecx
add    $0x6,%ecx
add    $0x30,%ecx
mov    -0x20(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     11b6 <GrOffScreen4BPPLineDrawV+0xb6>
jmp    116f <GrOffScreen4BPPLineDrawV+0x6f>
mov    -0x10(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     11b1 <GrOffScreen4BPPLineDrawV+0xb1>
mov    -0x20(%rbp),%rax
movzbl (%rax),%eax
and    $0xf0,%eax
or     -0x18(%rbp),%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,(%rax)
mov    -0x24(%rbp),%ecx
mov    -0x20(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    116f <GrOffScreen4BPPLineDrawV+0x6f>
jmp    1204 <GrOffScreen4BPPLineDrawV+0x104>
mov    -0x18(%rbp),%eax
shl    $0x4,%eax
mov    %eax,-0x18(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     11ff <GrOffScreen4BPPLineDrawV+0xff>
mov    -0x20(%rbp),%rax
movzbl (%rax),%eax
and    $0xf,%eax
or     -0x18(%rbp),%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,(%rax)
mov    -0x24(%rbp),%ecx
mov    -0x20(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    11bf <GrOffScreen4BPPLineDrawV+0xbf>
jmp    1204 <GrOffScreen4BPPLineDrawV+0x104>
pop    %rbp
ret

x86 assembly (clang, -O2):
<GrOffScreen4BPPLineDrawV>:
movzwl 0x1(%rdi),%r9d
add    $0x1,%r9
shr    %r9
mov    %r9d,%r10d
imul   %edx,%r10d
mov    %esi,%eax
shr    $0x1f,%eax
add    %esi,%eax
sar    %eax
add    %r10d,%eax
add    $0x36,%eax
movslq %eax,%r11
add    %rdi,%r11
mov    %ecx,%r10d
test   $0x1,%sil
jne    11cc <GrOffScreen4BPPLineDrawV+0xcc>
sub    %edx,%r10d
jl     1267 <GrOffScreen4BPPLineDrawV+0x167>
shl    $0x4,%r8b
lea    0x1(%r10),%edi
and    $0x3,%edi
je     1168 <GrOffScreen4BPPLineDrawV+0x68>
neg    %edi
xor    %esi,%esi
nop
movzbl (%r11),%eax
and    $0xf,%al
or     %r8b,%al
mov    %al,(%r11)
add    %r9,%r11
add    $0xffffffff,%esi
cmp    %esi,%edi
jne    1150 <GrOffScreen4BPPLineDrawV+0x50>
sub    %esi,%edx
cmp    $0x3,%r10d
jb     1267 <GrOffScreen4BPPLineDrawV+0x167>
sub    %edx,%ecx
add    $0x1,%ecx
lea    (%r9,%r9,2),%rdx
nopl   0x0(%rax,%rax,1)
movzbl (%r11),%eax
and    $0xf,%al
or     %r8b,%al
mov    %al,(%r11)
movzbl (%r11,%r9,1),%eax
and    $0xf,%al
or     %r8b,%al
mov    %al,(%r11,%r9,1)
movzbl (%r11,%r9,2),%eax
and    $0xf,%al
or     %r8b,%al
mov    %al,(%r11,%r9,2)
movzbl (%r11,%rdx,1),%eax
and    $0xf,%al
or     %r8b,%al
mov    %al,(%r11,%rdx,1)
add    %r9,%r11
add    %r9,%r11
add    %r9,%r11
add    %r9,%r11
add    $0xfffffffc,%ecx
jne    1180 <GrOffScreen4BPPLineDrawV+0x80>
jmp    1267 <GrOffScreen4BPPLineDrawV+0x167>
sub    %edx,%r10d
jl     1267 <GrOffScreen4BPPLineDrawV+0x167>
lea    0x1(%r10),%edi
and    $0x3,%edi
je     1208 <GrOffScreen4BPPLineDrawV+0x108>
neg    %edi
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movzbl (%r11),%eax
and    $0xf0,%al
or     %r8b,%al
mov    %al,(%r11)
add    %r9,%r11
add    $0xffffffff,%esi
cmp    %esi,%edi
jne    11f0 <GrOffScreen4BPPLineDrawV+0xf0>
sub    %esi,%edx
cmp    $0x3,%r10d
jb     1267 <GrOffScreen4BPPLineDrawV+0x167>
sub    %edx,%ecx
add    $0x1,%ecx
lea    (%r9,%r9,2),%rdx
nopw   0x0(%rax,%rax,1)
movzbl (%r11),%eax
and    $0xf0,%al
or     %r8b,%al
mov    %al,(%r11)
movzbl (%r11,%r9,1),%eax
and    $0xf0,%al
or     %r8b,%al
mov    %al,(%r11,%r9,1)
movzbl (%r11,%r9,2),%eax
and    $0xf0,%al
or     %r8b,%al
mov    %al,(%r11,%r9,2)
movzbl (%r11,%rdx,1),%eax
and    $0xf0,%al
or     %r8b,%al
mov    %al,(%r11,%rdx,1)
add    %r9,%r11
add    %r9,%r11
add    %r9,%r11
add    %r9,%r11
add    $0xfffffffc,%ecx
jne    1220 <GrOffScreen4BPPLineDrawV+0x120>
ret

LLVM IR (-O0):
define void @GrOffScreen4BPPLineDrawV(i8* %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i8*
%12 = alloca i32
store i8* %0, i8** %6
store i32 %1, i32* %7
store i32 %2, i32* %8
store i32 %3, i32* %9
store i32 %4, i32* %10
%13 = load i8*, i8** %6
store i8* %13, i8** %11
%14 = load i8*, i8** %11
%15 = getelementptr inbounds i8, i8* %14, i64 1
%16 = bitcast i8* %15 to i16*
%17 = load i16, i16* %16
%18 = zext i16 %17 to i32
%19 = add nsw i32 %18, 1
%20 = sdiv i32 %19, 2
store i32 %20, i32* %12
%21 = load i32, i32* %12
%22 = load i32, i32* %8
%23 = mul nsw i32 %21, %22
%24 = load i32, i32* %7
%25 = sdiv i32 %24, 2
%26 = add nsw i32 %23, %25
%27 = add nsw i32 %26, 6
%28 = add nsw i32 %27, 48
%29 = load i8*, i8** %11
%30 = sext i32 %28 to i64
%31 = getelementptr inbounds i8, i8* %29, i64 %30
store i8* %31, i8** %11
%32 = load i32, i32* %7
%33 = and i32 %32, 1
%34 = icmp ne i32 %33, 0
br i1 %34, label %35, label %56
35: ; preds = %5
br label %36
36: ; preds = %40, %35
%37 = load i32, i32* %8
%38 = load i32, i32* %9
%39 = icmp sle i32 %37, %38
br i1 %39, label %40, label %55
40: ; preds = %36
%41 = load i8*, i8** %11
%42 = load i8, i8* %41
%43 = zext i8 %42 to i32
%44 = and i32 %43, 240
%45 = load i32, i32* %10
%46 = or i32 %44, %45
%47 = trunc i32 %46 to i8
%48 = load i8*, i8** %11
store i8 %47, i8* %48
%49 = load i32, i32* %12
%50 = load i8*, i8** %11
%51 = sext i32 %49 to i64
%52 = getelementptr inbounds i8, i8* %50, i64 %51
store i8* %52, i8** %11
%53 = load i32, i32* %8
%54 = add nsw i32 %53, 1
store i32 %54, i32* %8
br label %36
55: ; preds = %36
br label %79
56: ; preds = %5
%57 = load i32, i32* %10
%58 = shl i32 %57, 4
store i32 %58, i32* %10
br label %59
59: ; preds = %63, %56
%60 = load i32, i32* %8
%61 = load i32, i32* %9
%62 = icmp sle i32 %60, %61
br i1 %62, label %63, label %78
63: ; preds = %59
%64 = load i8*, i8** %11
%65 = load i8, i8* %64
%66 = zext i8 %65 to i32
%67 = and i32 %66, 15
%68 = load i32, i32* %10
%69 = or i32 %67, %68
%70 = trunc i32 %69 to i8
%71 = load i8*, i8** %11
store i8 %70, i8* %71
%72 = load i32, i32* %12
%73 = load i8*, i8** %11
%74 = sext i32 %72 to i64
%75 = getelementptr inbounds i8, i8* %73, i64 %74
store i8* %75, i8** %11
%76 = load i32, i32* %8
%77 = add nsw i32 %76, 1
store i32 %77, i32* %8
br label %59
78: ; preds = %59
br label %79
79: ; preds = %78, %55
ret void
}

LLVM IR (-O2):
define void @GrOffScreen4BPPLineDrawV(i8* nocapture %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = getelementptr inbounds i8, i8* %0, i64 1
%7 = bitcast i8* %6 to i16*
%8 = load i16, i16* %7
%9 = zext i16 %8 to i32
%10 = add nuw nsw i32 %9, 1
%11 = lshr i32 %10, 1
%12 = mul nsw i32 %11, %2
%13 = sdiv i32 %1, 2
%14 = add nsw i32 %13, 54
%15 = add i32 %14, %12
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds i8, i8* %0, i64 %16
%18 = and i32 %1, 1
%19 = icmp eq i32 %18, 0
%20 = icmp slt i32 %3, %2
br i1 %19, label %45, label %21
21: ; preds = %5
br i1 %20, label %114, label %22
22: ; preds = %21
%23 = trunc i32 %4 to i8
%24 = zext i32 %11 to i64
%25 = add i32 %3, 1
%26 = sub i32 %25, %2
%27 = sub i32 %3, %2
%28 = and i32 %26, 3
%29 = icmp eq i32 %28, 0
br i1 %29, label %41, label %30
30: ; preds = %22, %30
%31 = phi i32 [ %38, %30 ], [ %2, %22 ]
%32 = phi i8* [ %37, %30 ], [ %17, %22 ]
%33 = phi i32 [ %39, %30 ], [ 0, %22 ]
%34 = load i8, i8* %32
%35 = and i8 %34, -16
%36 = or i8 %35, %23
store i8 %36, i8* %32
%37 = getelementptr inbounds i8, i8* %32, i64 %24
%38 = add i32 %31, 1
%39 = add i32 %33, 1
%40 = icmp eq i32 %39, %28
br i1 %40, label %41, label %30
41: ; preds = %30, %22
%42 = phi i32 [ %2, %22 ], [ %38, %30 ]
%43 = phi i8* [ %17, %22 ], [ %37, %30 ]
%44 = icmp ult i32 %27, 3
br i1 %44, label %114, label %70
45: ; preds = %5
br i1 %20, label %114, label %46
46: ; preds = %45
%47 = trunc i32 %4 to i8
%48 = shl i8 %47, 4
%49 = zext i32 %11 to i64
%50 = add i32 %3, 1
%51 = sub i32 %50, %2
%52 = sub i32 %3, %2
%53 = and i32 %51, 3
%54 = icmp eq i32 %53, 0
br i1 %54, label %66, label %55
55: ; preds = %46, %55
%56 = phi i32 [ %63, %55 ], [ %2, %46 ]
%57 = phi i8* [ %62, %55 ], [ %17, %46 ]
%58 = phi i32 [ %64, %55 ], [ 0, %46 ]
%59 = load i8, i8* %57
%60 = and i8 %59, 15
%61 = or i8 %60, %48
store i8 %61, i8* %57
%62 = getelementptr inbounds i8, i8* %57, i64 %49
%63 = add i32 %56, 1
%64 = add i32 %58, 1
%65 = icmp eq i32 %64, %53
br i1 %65, label %66, label %55
66: ; preds = %55, %46
%67 = phi i32 [ %2, %46 ], [ %63, %55 ]
%68 = phi i8* [ %17, %46 ], [ %62, %55 ]
%69 = icmp ult i32 %52, 3
br i1 %69, label %114, label %92
70: ; preds = %41, %70
%71 = phi i32 [ %90, %70 ], [ %42, %41 ]
%72 = phi i8* [ %89, %70 ], [ %43, %41 ]
%73 = load i8, i8* %72
%74 = and i8 %73, -16
%75 = or i8 %74, %23
store i8 %75, i8* %72
%76 = getelementptr inbounds i8, i8* %72, i64 %24
%77 = load i8, i8* %76
%78 = and i8 %77, -16
%79 = or i8 %78, %23
store i8 %79, i8* %76
%80 = getelementptr inbounds i8, i8* %76, i64 %24
%81 = load i8, i8* %80
%82 = and i8 %81, -16
%83 = or i8 %82, %23
store i8 %83, i8* %80
%84 = getelementptr inbounds i8, i8* %80, i64 %24
%85 = add i32 %71, 3
%86 = load i8, i8* %84
%87 = and i8 %86, -16
%88 = or i8 %87, %23
store i8 %88, i8* %84
%89 = getelementptr inbounds i8, i8* %84, i64 %24
%90 = add i32 %71, 4
%91 = icmp eq i32 %85, %3
br i1 %91, label %114, label %70
92: ; preds = %66, %92
%93 = phi i32 [ %112, %92 ], [ %67, %66 ]
%94 = phi i8* [ %111, %92 ], [ %68, %66 ]
%95 = load i8, i8* %94
%96 = and i8 %95, 15
%97 = or i8 %96, %48
store i8 %97, i8* %94
%98 = getelementptr inbounds i8, i8* %94, i64 %49
%99 = load i8, i8* %98
%100 = and i8 %99, 15
%101 = or i8 %100, %48
store i8 %101, i8* %98
%102 = getelementptr inbounds i8, i8* %98, i64 %49
%103 = load i8, i8* %102
%104 = and i8 %103, 15
%105 = or i8 %104, %48
store i8 %105, i8* %102
%106 = getelementptr inbounds i8, i8* %102, i64 %49
%107 = add i32 %93, 3
%108 = load i8, i8* %106
%109 = and i8 %108, 15
%110 = or i8 %109, %48
store i8 %110, i8* %106
%111 = getelementptr inbounds i8, i8* %106, i64 %49
%112 = add i32 %93, 4
%113 = icmp eq i32 %107, %3
br i1 %113, label %114, label %92
114: ; preds = %41, %70, %66, %92, %21, %45
ret void
}