// #target: macos-x64
module test;
import std::io;

bitstruct Test : int @bigendian
{
	ushort a : 0..15;
	ushort b : 16..31;
}

bitstruct Test2 : char[4] @bigendian
{
	ushort a : 0..15;
	ushort b : 16..31;
}

fn void main()
{
	IntBE x;
	x.val = 123;

	io::printf("BE 123 => %d (%d)\n", (int)x, x.val);
	Test abc = { .a = 0x1234, .b = 0x5678 };
	Test2 abc2 = { .a = 0x1234, .b = 0x5678 };
	char[4]* z = (char[4]*)&abc;
	char[4]* z2 = (char[4]*)&abc2;
	foreach (d : z2) io::printf(" %x", d);
	io::printn("");
	foreach (d : z) io::printf(" %x", d);
	io::printn("");
	io::printfn("abc.a = %x", abc.a);
	abc.a = 0x1234;
	abc.b = 0x5678;
	io::printfn("->abc.a = %x", abc.a);
	foreach (d : z) io::printf(" %x", d);
	io::printn("");

	IntLE y;
	y.val = 123;
	io::printf("LE 123 => %d (%d)\n", (int)y, y.val);

}

/* #expect: test.ll

  %0 = load i32, ptr %x, align 4
  %1 = call i32 @llvm.bswap.i32(i32 %0)
  store i32 2063597568, ptr %x, align 4
  %2 = insertvalue %any undef, ptr %x, 0
  %3 = insertvalue %any %2, i64 ptrtoint (ptr @"$ct.int" to i64), 1
  store %any %3, ptr %varargslots, align 16
  %4 = load i32, ptr %x, align 4
  %5 = call i32 @llvm.bswap.i32(i32 %4)
  store i32 %5, ptr %taddr, align 4
  %6 = insertvalue %any undef, ptr %taddr, 0
  %7 = insertvalue %any %6, i64 ptrtoint (ptr @"$ct.int" to i64), 1
  %ptradd = getelementptr inbounds i8, ptr %varargslots, i64 16
  store %any %7, ptr %ptradd, align 16
  %8 = call i64 @std.io.printf(ptr %retparam, ptr @.str, i64 18, ptr %varargslots, i64 2)
  store i32 873625686, ptr %abc, align 4
  store [4 x i8] c"\124Vx", ptr %abc2, align 1
  store ptr %abc, ptr %z, align 8
  store ptr %abc2, ptr %z2, align 8
  %9 = load ptr, ptr %z2, align 8
  store i64 0, ptr %.anon, align 8
  br label %loop.cond

loop.cond:                                        ; preds = %loop.body, %entry
  %10 = load i64, ptr %.anon, align 8
  %gt = icmp ugt i64 4, %10
  br i1 %gt, label %loop.body, label %loop.exit

loop.body:                                        ; preds = %loop.cond
  %11 = load i64, ptr %.anon, align 8
  %ptradd1 = getelementptr inbounds i8, ptr %9, i64 %11
  %12 = load i8, ptr %ptradd1, align 1
  store i8 %12, ptr %d, align 1
  %13 = insertvalue %any undef, ptr %d, 0
  %14 = insertvalue %any %13, i64 ptrtoint (ptr @"$ct.char" to i64), 1
  store %any %14, ptr %varargslots2, align 16
  %15 = call i64 @std.io.printf(ptr %retparam3, ptr @.str.1, i64 3, ptr %varargslots2, i64 1)
  %16 = load i64, ptr %.anon, align 8
  %addnuw = add nuw i64 %16, 1
  store i64 %addnuw, ptr %.anon, align 8
  br label %loop.cond

loop.exit:                                        ; preds = %loop.cond
  %17 = call ptr @std.io.stdout()
  %18 = call i64 @std.io.File.write(ptr %retparam5, ptr %17, ptr @.emptystr, i64 0)
  %not_err = icmp eq i64 %18, 0
  %19 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
  br i1 %19, label %after_check, label %assign_optional

assign_optional:                                  ; preds = %loop.exit
  store i64 %18, ptr %error_var, align 8
  br label %guard_block

after_check:                                      ; preds = %loop.exit
  br label %noerr_block

guard_block:                                      ; preds = %assign_optional
  br label %voiderr

noerr_block:                                      ; preds = %after_check
  %20 = load i64, ptr %retparam5, align 8
  store i64 %20, ptr %len, align 8
  %21 = call i64 @std.io.File.write_byte(ptr %17, i8 zeroext 10)
  %not_err7 = icmp eq i64 %21, 0
  %22 = call i1 @llvm.expect.i1(i1 %not_err7, i1 true)
  br i1 %22, label %after_check9, label %assign_optional8

assign_optional8:                                 ; preds = %noerr_block
  store i64 %21, ptr %error_var6, align 8
  br label %guard_block10

after_check9:                                     ; preds = %noerr_block
  br label %noerr_block11

guard_block10:                                    ; preds = %assign_optional8
  br label %voiderr

noerr_block11:                                    ; preds = %after_check9
  %23 = call i64 @std.io.File.flush(ptr %17)
  %not_err13 = icmp eq i64 %23, 0
  %24 = call i1 @llvm.expect.i1(i1 %not_err13, i1 true)
  br i1 %24, label %after_check15, label %assign_optional14

assign_optional14:                                ; preds = %noerr_block11
  store i64 %23, ptr %error_var12, align 8
  br label %guard_block16

after_check15:                                    ; preds = %noerr_block11
  br label %noerr_block17

guard_block16:                                    ; preds = %assign_optional14
  br label %voiderr

noerr_block17:                                    ; preds = %after_check15
  %25 = load i64, ptr %len, align 8
  %add = add i64 %25, 1
  br label %voiderr

voiderr:                                          ; preds = %noerr_block17, %guard_block16, %guard_block10, %guard_block
  %26 = load ptr, ptr %z, align 8
  store i64 0, ptr %.anon18, align 8
  br label %loop.cond19

loop.cond19:                                      ; preds = %loop.body21, %voiderr
  %27 = load i64, ptr %.anon18, align 8
  %gt20 = icmp ugt i64 4, %27
  br i1 %gt20, label %loop.body21, label %loop.exit29

loop.body21:                                      ; preds = %loop.cond19
  %28 = load i64, ptr %.anon18, align 8
  %ptradd23 = getelementptr inbounds i8, ptr %26, i64 %28
  %29 = load i8, ptr %ptradd23, align 1
  store i8 %29, ptr %d22, align 1
  %30 = insertvalue %any undef, ptr %d22, 0
  %31 = insertvalue %any %30, i64 ptrtoint (ptr @"$ct.char" to i64), 1
  store %any %31, ptr %varargslots24, align 16
  %32 = call i64 @std.io.printf(ptr %retparam25, ptr @.str.2, i64 3, ptr %varargslots24, i64 1)
  %33 = load i64, ptr %.anon18, align 8
  %addnuw28 = add nuw i64 %33, 1
  store i64 %addnuw28, ptr %.anon18, align 8
  br label %loop.cond19

loop.exit29:                                      ; preds = %loop.cond19
  %34 = call ptr @std.io.stdout()
  %35 = call i64 @std.io.File.write(ptr %retparam33, ptr %34, ptr @.emptystr, i64 0)
  %not_err34 = icmp eq i64 %35, 0
  %36 = call i1 @llvm.expect.i1(i1 %not_err34, i1 true)
  br i1 %36, label %after_check36, label %assign_optional35

assign_optional35:                                ; preds = %loop.exit29
  store i64 %35, ptr %error_var31, align 8
  br label %guard_block37

after_check36:                                    ; preds = %loop.exit29
  br label %noerr_block38

guard_block37:                                    ; preds = %assign_optional35
  br label %voiderr52

noerr_block38:                                    ; preds = %after_check36
  %37 = load i64, ptr %retparam33, align 8
  store i64 %37, ptr %len30, align 8
  %38 = call i64 @std.io.File.write_byte(ptr %34, i8 zeroext 10)
  %not_err40 = icmp eq i64 %38, 0
  %39 = call i1 @llvm.expect.i1(i1 %not_err40, i1 true)
  br i1 %39, label %after_check42, label %assign_optional41

assign_optional41:                                ; preds = %noerr_block38
  store i64 %38, ptr %error_var39, align 8
  br label %guard_block43

after_check42:                                    ; preds = %noerr_block38
  br label %noerr_block44

guard_block43:                                    ; preds = %assign_optional41
  br label %voiderr52

noerr_block44:                                    ; preds = %after_check42
  %40 = call i64 @std.io.File.flush(ptr %34)
  %not_err46 = icmp eq i64 %40, 0
  %41 = call i1 @llvm.expect.i1(i1 %not_err46, i1 true)
  br i1 %41, label %after_check48, label %assign_optional47

assign_optional47:                                ; preds = %noerr_block44
  store i64 %40, ptr %error_var45, align 8
  br label %guard_block49

after_check48:                                    ; preds = %noerr_block44
  br label %noerr_block50

guard_block49:                                    ; preds = %assign_optional47
  br label %voiderr52

noerr_block50:                                    ; preds = %after_check48
  %42 = load i64, ptr %len30, align 8
  %add51 = add i64 %42, 1
  br label %voiderr52

voiderr52:                                        ; preds = %noerr_block50, %guard_block49, %guard_block43, %guard_block37
  %43 = load i32, ptr %abc, align 4
  %44 = call i32 @llvm.bswap.i32(i32 %43)
  %45 = and i32 65535, %44
  %trunc = trunc i32 %45 to i16
  store i16 %trunc, ptr %taddr54, align 2
  %46 = insertvalue %any undef, ptr %taddr54, 0
  %47 = insertvalue %any %46, i64 ptrtoint (ptr @"$ct.ushort" to i64), 1
  store %any %47, ptr %varargslots53, align 16
  %48 = call i64 @std.io.printfn(ptr %retparam55, ptr @.str.3, i64 10, ptr %varargslots53, i64 1)
  %49 = load i32, ptr %abc, align 4
  %50 = call i32 @llvm.bswap.i32(i32 %49)
  %51 = and i32 %50, -65536
  %52 = or i32 %51, 4660
  %53 = call i32 @llvm.bswap.i32(i32 %52)
  store i32 %53, ptr %abc, align 4
  %54 = load i32, ptr %abc, align 4
  %55 = call i32 @llvm.bswap.i32(i32 %54)
  %56 = and i32 %55, 65535
  %57 = or i32 %56, 1450704896
  %58 = call i32 @llvm.bswap.i32(i32 %57)
  store i32 %58, ptr %abc, align 4
  %59 = load i32, ptr %abc, align 4
  %60 = call i32 @llvm.bswap.i32(i32 %59)
  %61 = and i32 65535, %60
  %trunc59 = trunc i32 %61 to i16
  store i16 %trunc59, ptr %taddr60, align 2
  %62 = insertvalue %any undef, ptr %taddr60, 0
  %63 = insertvalue %any %62, i64 ptrtoint (ptr @"$ct.ushort" to i64), 1
  store %any %63, ptr %varargslots58, align 16
  %64 = call i64 @std.io.printfn(ptr %retparam61, ptr @.str.4, i64 12, ptr %varargslots58, i64 1)
  %65 = load ptr, ptr %z, align 8
  store i64 0, ptr %.anon64, align 8
  br label %loop.cond65

loop.cond65:                                      ; preds = %loop.body67, %voiderr52
  %66 = load i64, ptr %.anon64, align 8
  %gt66 = icmp ugt i64 4, %66
  br i1 %gt66, label %loop.body67, label %loop.exit75

loop.body67:                                      ; preds = %loop.cond65
  %67 = load i64, ptr %.anon64, align 8
  %ptradd69 = getelementptr inbounds i8, ptr %65, i64 %67
  %68 = load i8, ptr %ptradd69, align 1
  store i8 %68, ptr %d68, align 1
  %69 = insertvalue %any undef, ptr %d68, 0
  %70 = insertvalue %any %69, i64 ptrtoint (ptr @"$ct.char" to i64), 1
  store %any %70, ptr %varargslots70, align 16
  %71 = call i64 @std.io.printf(ptr %retparam71, ptr @.str.5, i64 3, ptr %varargslots70, i64 1)
  %72 = load i64, ptr %.anon64, align 8
  %addnuw74 = add nuw i64 %72, 1
  store i64 %addnuw74, ptr %.anon64, align 8
  br label %loop.cond65

loop.exit75:                                      ; preds = %loop.cond65
  %73 = call ptr @std.io.stdout()
  %74 = call i64 @std.io.File.write(ptr %retparam79, ptr %73, ptr @.emptystr, i64 0)
  %not_err80 = icmp eq i64 %74, 0
  %75 = call i1 @llvm.expect.i1(i1 %not_err80, i1 true)
  br i1 %75, label %after_check82, label %assign_optional81

assign_optional81:                                ; preds = %loop.exit75
  store i64 %74, ptr %error_var77, align 8
  br label %guard_block83

after_check82:                                    ; preds = %loop.exit75
  br label %noerr_block84

guard_block83:                                    ; preds = %assign_optional81
  br label %voiderr98

noerr_block84:                                    ; preds = %after_check82
  %76 = load i64, ptr %retparam79, align 8
  store i64 %76, ptr %len76, align 8
  %77 = call i64 @std.io.File.write_byte(ptr %73, i8 zeroext 10)
  %not_err86 = icmp eq i64 %77, 0
  %78 = call i1 @llvm.expect.i1(i1 %not_err86, i1 true)
  br i1 %78, label %after_check88, label %assign_optional87

assign_optional87:                                ; preds = %noerr_block84
  store i64 %77, ptr %error_var85, align 8
  br label %guard_block89

after_check88:                                    ; preds = %noerr_block84
  br label %noerr_block90

guard_block89:                                    ; preds = %assign_optional87
  br label %voiderr98

noerr_block90:                                    ; preds = %after_check88
  %79 = call i64 @std.io.File.flush(ptr %73)
  %not_err92 = icmp eq i64 %79, 0
  %80 = call i1 @llvm.expect.i1(i1 %not_err92, i1 true)
  br i1 %80, label %after_check94, label %assign_optional93

assign_optional93:                                ; preds = %noerr_block90
  store i64 %79, ptr %error_var91, align 8
  br label %guard_block95

after_check94:                                    ; preds = %noerr_block90
  br label %noerr_block96

guard_block95:                                    ; preds = %assign_optional93
  br label %voiderr98

noerr_block96:                                    ; preds = %after_check94
  %81 = load i64, ptr %len76, align 8
  %add97 = add i64 %81, 1
  br label %voiderr98

voiderr98:                                        ; preds = %noerr_block96, %guard_block95, %guard_block89, %guard_block83
  store i32 0, ptr %y, align 4
  %82 = load i32, ptr %y, align 4
  store i32 123, ptr %y, align 4
  %83 = insertvalue %any undef, ptr %y, 0
  %84 = insertvalue %any %83, i64 ptrtoint (ptr @"$ct.int" to i64), 1
  store %any %84, ptr %varargslots99, align 16
  %85 = load i32, ptr %y, align 4
  store i32 %85, ptr %taddr100, align 4
  %86 = insertvalue %any undef, ptr %taddr100, 0
  %87 = insertvalue %any %86, i64 ptrtoint (ptr @"$ct.int" to i64), 1
  %ptradd101 = getelementptr inbounds i8, ptr %varargslots99, i64 16
  store %any %87, ptr %ptradd101, align 16
  %88 = call i64 @std.io.printf(ptr %retparam102, ptr @.str.6, i64 18, ptr %varargslots99, i64 2)
  ret void
}