1*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-neon | FileCheck --check-prefix=CHECK-NONEON %s 3*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s 4*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64_be-none-linux-gnu | FileCheck --check-prefix=CHECK-BE %s 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker%myStruct = type { i64 , i8, i32 } 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker@var8 = global i8 0 9*9880d681SAndroid Build Coastguard Worker@var8_2 = global i8 0 10*9880d681SAndroid Build Coastguard Worker@var32 = global i32 0 11*9880d681SAndroid Build Coastguard Worker@var64 = global i64 0 12*9880d681SAndroid Build Coastguard Worker@var128 = global i128 0 13*9880d681SAndroid Build Coastguard Worker@varfloat = global float 0.0 14*9880d681SAndroid Build Coastguard Worker@varfloat_2 = global float 0.0 15*9880d681SAndroid Build Coastguard Worker@vardouble = global double 0.0 16*9880d681SAndroid Build Coastguard Worker@varstruct = global %myStruct zeroinitializer 17*9880d681SAndroid Build Coastguard Worker@varsmallstruct = global [2 x i64] zeroinitializer 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Workerdeclare void @take_i8s(i8 %val1, i8 %val2) 20*9880d681SAndroid Build Coastguard Workerdeclare void @take_floats(float %val1, float %val2) 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Workerdefine void @simple_args() { 23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: simple_args: 24*9880d681SAndroid Build Coastguard Worker %char1 = load i8, i8* @var8 25*9880d681SAndroid Build Coastguard Worker %char2 = load i8, i8* @var8_2 26*9880d681SAndroid Build Coastguard Worker call void @take_i8s(i8 %char1, i8 %char2) 27*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: ldrb w0, [{{x[0-9]+}}, {{#?}}:lo12:var8] 28*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: ldrb w1, [{{x[0-9]+}}, {{#?}}:lo12:var8_2] 29*9880d681SAndroid Build Coastguard Worker; CHECK: bl take_i8s 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker %float1 = load float, float* @varfloat 32*9880d681SAndroid Build Coastguard Worker %float2 = load float, float* @varfloat_2 33*9880d681SAndroid Build Coastguard Worker call void @take_floats(float %float1, float %float2) 34*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: ldr s1, [{{x[0-9]+}}, {{#?}}:lo12:varfloat_2] 35*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: ldr s0, [{{x[0-9]+}}, {{#?}}:lo12:varfloat] 36*9880d681SAndroid Build Coastguard Worker; CHECK: bl take_floats 37*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: ldr s1, 38*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: ldr s0, 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker ret void 41*9880d681SAndroid Build Coastguard Worker} 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workerdeclare i32 @return_int() 44*9880d681SAndroid Build Coastguard Workerdeclare double @return_double() 45*9880d681SAndroid Build Coastguard Workerdeclare [2 x i64] @return_smallstruct() 46*9880d681SAndroid Build Coastguard Workerdeclare void @return_large_struct(%myStruct* sret %retval) 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Workerdefine void @simple_rets() { 49*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: simple_rets: 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker %int = call i32 @return_int() 52*9880d681SAndroid Build Coastguard Worker store i32 %int, i32* @var32 53*9880d681SAndroid Build Coastguard Worker; CHECK: bl return_int 54*9880d681SAndroid Build Coastguard Worker; CHECK: str w0, [{{x[0-9]+}}, {{#?}}:lo12:var32] 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker %dbl = call double @return_double() 57*9880d681SAndroid Build Coastguard Worker store double %dbl, double* @vardouble 58*9880d681SAndroid Build Coastguard Worker; CHECK: bl return_double 59*9880d681SAndroid Build Coastguard Worker; CHECK: str d0, [{{x[0-9]+}}, {{#?}}:lo12:vardouble] 60*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: str d0, 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker %arr = call [2 x i64] @return_smallstruct() 63*9880d681SAndroid Build Coastguard Worker store [2 x i64] %arr, [2 x i64]* @varsmallstruct 64*9880d681SAndroid Build Coastguard Worker; CHECK: bl return_smallstruct 65*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[VARSMALLSTRUCT:[0-9]+]], {{x[0-9]+}}, :lo12:varsmallstruct 66*9880d681SAndroid Build Coastguard Worker; CHECK: stp x0, x1, [x[[VARSMALLSTRUCT]]] 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker call void @return_large_struct(%myStruct* sret @varstruct) 69*9880d681SAndroid Build Coastguard Worker; CHECK: add x8, {{x[0-9]+}}, {{#?}}:lo12:varstruct 70*9880d681SAndroid Build Coastguard Worker; CHECK: bl return_large_struct 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker ret void 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Workerdeclare i32 @struct_on_stack(i8 %var0, i16 %var1, i32 %var2, i64 %var3, i128 %var45, 77*9880d681SAndroid Build Coastguard Worker i32* %var6, %myStruct* byval %struct, i32 %stacked, 78*9880d681SAndroid Build Coastguard Worker double %notstacked) 79*9880d681SAndroid Build Coastguard Workerdeclare void @stacked_fpu(float %var0, double %var1, float %var2, float %var3, 80*9880d681SAndroid Build Coastguard Worker float %var4, float %var5, float %var6, float %var7, 81*9880d681SAndroid Build Coastguard Worker float %var8) 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workerdefine void @check_stack_args() { 84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: check_stack_args: 85*9880d681SAndroid Build Coastguard Worker call i32 @struct_on_stack(i8 0, i16 12, i32 42, i64 99, i128 1, 86*9880d681SAndroid Build Coastguard Worker i32* @var32, %myStruct* byval @varstruct, 87*9880d681SAndroid Build Coastguard Worker i32 999, double 1.0) 88*9880d681SAndroid Build Coastguard Worker ; Want to check that the final double is passed in registers and 89*9880d681SAndroid Build Coastguard Worker ; that varstruct is passed on the stack. Rather dependent on how a 90*9880d681SAndroid Build Coastguard Worker ; memcpy gets created, but the following works for now. 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: str {{q[0-9]+}}, [sp] 93*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: fmov d[[FINAL_DOUBLE:[0-9]+]], #1.0 94*9880d681SAndroid Build Coastguard Worker; CHECK: mov v0.16b, v[[FINAL_DOUBLE]].16b 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker; CHECK-NONEON-DAG: str {{q[0-9]+}}, [sp] 97*9880d681SAndroid Build Coastguard Worker; CHECK-NONEON-DAG: fmov d[[FINAL_DOUBLE:[0-9]+]], #1.0 98*9880d681SAndroid Build Coastguard Worker; CHECK-NONEON: fmov d0, d[[FINAL_DOUBLE]] 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker; CHECK: bl struct_on_stack 101*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: fmov 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker call void @stacked_fpu(float -1.0, double 1.0, float 4.0, float 2.0, 104*9880d681SAndroid Build Coastguard Worker float -2.0, float -8.0, float 16.0, float 1.0, 105*9880d681SAndroid Build Coastguard Worker float 64.0) 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[SIXTY_FOUR:w[0-9]+]], #1115684864 108*9880d681SAndroid Build Coastguard Worker; CHECK: str [[SIXTY_FOUR]], [sp] 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Worker; CHECK-NONEON: mov [[SIXTY_FOUR:w[0-9]+]], #1115684864 111*9880d681SAndroid Build Coastguard Worker; CHECK-NONEON: str [[SIXTY_FOUR]], [sp] 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Worker; CHECK: bl stacked_fpu 114*9880d681SAndroid Build Coastguard Worker ret void 115*9880d681SAndroid Build Coastguard Worker} 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Workerdeclare void @check_i128_stackalign(i32 %val0, i32 %val1, i32 %val2, i32 %val3, 119*9880d681SAndroid Build Coastguard Worker i32 %val4, i32 %val5, i32 %val6, i32 %val7, 120*9880d681SAndroid Build Coastguard Worker i32 %stack1, i128 %stack2) 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerdeclare void @check_i128_regalign(i32 %val0, i128 %val1) 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Workerdefine void @check_i128_align() { 126*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: check_i128_align: 127*9880d681SAndroid Build Coastguard Worker %val = load i128, i128* @var128 128*9880d681SAndroid Build Coastguard Worker call void @check_i128_stackalign(i32 0, i32 1, i32 2, i32 3, 129*9880d681SAndroid Build Coastguard Worker i32 4, i32 5, i32 6, i32 7, 130*9880d681SAndroid Build Coastguard Worker i32 42, i128 %val) 131*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[VAR128:[0-9]+]], {{x[0-9]+}}, :lo12:var128 132*9880d681SAndroid Build Coastguard Worker; CHECK: ldp [[I128LO:x[0-9]+]], [[I128HI:x[0-9]+]], [x[[VAR128]]] 133*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[I128LO]], [[I128HI]], [sp, #16] 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker; CHECK-NONEON: add x[[VAR128:[0-9]+]], {{x[0-9]+}}, :lo12:var128 136*9880d681SAndroid Build Coastguard Worker; CHECK-NONEON: ldp [[I128LO:x[0-9]+]], [[I128HI:x[0-9]+]], [x[[VAR128]]] 137*9880d681SAndroid Build Coastguard Worker; CHECK-NONEON: stp [[I128LO]], [[I128HI]], [sp, #16] 138*9880d681SAndroid Build Coastguard Worker; CHECK: bl check_i128_stackalign 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker call void @check_i128_regalign(i32 0, i128 42) 141*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mov x1 142*9880d681SAndroid Build Coastguard Worker; CHECK-LE: mov x2, #{{0x2a|42}} 143*9880d681SAndroid Build Coastguard Worker; CHECK-LE: mov x3, xzr 144*9880d681SAndroid Build Coastguard Worker; CHECK-BE: mov {{x|w}}3, #{{0x2a|42}} 145*9880d681SAndroid Build Coastguard Worker; CHECK-BE: mov x2, xzr 146*9880d681SAndroid Build Coastguard Worker; CHECK: bl check_i128_regalign 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker ret void 149*9880d681SAndroid Build Coastguard Worker} 150*9880d681SAndroid Build Coastguard Worker 151*9880d681SAndroid Build Coastguard Worker@fptr = global void()* null 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Workerdefine void @check_indirect_call() { 154*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: check_indirect_call: 155*9880d681SAndroid Build Coastguard Worker %func = load void()*, void()** @fptr 156*9880d681SAndroid Build Coastguard Worker call void %func() 157*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[FPTR:x[0-9]+]], [{{x[0-9]+}}, {{#?}}:lo12:fptr] 158*9880d681SAndroid Build Coastguard Worker; CHECK: blr [[FPTR]] 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker ret void 161*9880d681SAndroid Build Coastguard Worker} 162