// #target: macos-x64

module foo;

bitstruct BitFieldCross : uint
{
    uint d : 0..4;
    int a : 5..22;
    uint c : 23..31;
}

bitstruct BitFieldCrossU : int
{
    uint d : 0..4;
    uint a : 5..22;
    uint c : 23..31;
}

bitstruct BitFieldCrossUL : long
{
    uint d : 0..4;
    uint a : 5..22;
    uint c : 23..40;
    uint e : 41..61;
}

bitstruct BitFieldCrossULBE : long @bigendian
{
    uint d : 0..4;
    uint a : 5..22;
    uint c : 23..40;
    uint e : 41..61;
}
extern fn void printf(char*, ...);

fn void main()
{
    BitFieldCross xx = { 0, -15, 0 };
    printf("%d\n", xx.a);
    xx = { 0x1f, -15, 0x7f };
    printf("%d\n", xx.a);
    BitFieldCrossU xxu = { 0x1f, 0x25678, 0x1ff };
    printf("%x\n", xxu.a);
    BitFieldCrossUL xxy = { 0x1f, 0x25678, 0xeffe, 0xa9597 };
    printf("%x, %x, %x\n", xxy.a, xxy.c, xxy.e);
    BitFieldCrossULBE xxybe = { 0x1f, 0x25678, 0xeffe, 0xa9597 };
    printf("%x, %x, %x\n", xxybe.a, xxybe.c, xxybe.e);
}


/* #expect: foo.ll

entry:
  %xx = alloca i32, align 4
  %xxu = alloca i32, align 4
  %xxy = alloca i64, align 8
  %xxybe = alloca i64, align 8
  store i32 8388128, ptr %xx, align 4
  %0 = load i32, ptr %xx, align 4
  %shl = shl i32 %0, 9
  %ashr = ashr i32 %shl, 14
  call void (ptr, ...) @printf(ptr @.str, i32 %ashr)
  store i32 1073741375, ptr %xx, align 4
  %1 = load i32, ptr %xx, align 4
  %shl1 = shl i32 %1, 9
  %ashr2 = ashr i32 %shl1, 14
  call void (ptr, ...) @printf(ptr @.str.1, i32 %ashr2)
  store i32 -3485921, ptr %xxu, align 4
  %2 = load i32, ptr %xxu, align 4
  %lshrl = lshr i32 %2, 5
  %3 = and i32 262143, %lshrl
  call void (ptr, ...) @printf(ptr @.str.2, i32 %3)
  store i64 1525363991714123551, ptr %xxy, align 8
  %4 = load i64, ptr %xxy, align 8
  %lshrl3 = lshr i64 %4, 5
  %5 = and i64 262143, %lshrl3
  %trunc = trunc i64 %5 to i32
  %6 = load i64, ptr %xxy, align 8
  %lshrl4 = lshr i64 %6, 23
  %7 = and i64 262143, %lshrl4
  %trunc5 = trunc i64 %7 to i32
  %8 = load i64, ptr %xxy, align 8
  %lshrl6 = lshr i64 %8, 41
  %9 = and i64 2097151, %lshrl6
  %trunc7 = trunc i64 %9 to i32
  call void (ptr, ...) @printf(ptr @.str.3, i32 %trunc, i32 %trunc5, i32 %trunc7)
  store i64 2292133196431502101, ptr %xxybe, align 8
  %10 = load i64, ptr %xxybe, align 8
  %11 = call i64 @llvm.bswap.i64(i64 %10)
  %lshrl8 = lshr i64 %11, 5
  %12 = and i64 262143, %lshrl8
  %trunc9 = trunc i64 %12 to i32
  %13 = load i64, ptr %xxybe, align 8
  %14 = call i64 @llvm.bswap.i64(i64 %13)
  %lshrl10 = lshr i64 %14, 23
  %15 = and i64 262143, %lshrl10
  %trunc11 = trunc i64 %15 to i32
  %16 = load i64, ptr %xxybe, align 8
  %17 = call i64 @llvm.bswap.i64(i64 %16)
  %lshrl12 = lshr i64 %17, 41
  %18 = and i64 2097151, %lshrl12
  %trunc13 = trunc i64 %18 to i32
  call void (ptr, ...) @printf(ptr @.str.4, i32 %trunc9, i32 %trunc11, i32 %trunc13)
  ret void
}