1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 2; RUN: llc -mtriple armv7 -target-abi aapcs -float-abi soft -O0 -o - < %s \ 3; RUN: | FileCheck %s -check-prefix CHECK-SOFT 4; RUN: llc -mtriple armv7 -target-abi aapcs -float-abi hard -O0 -o - < %s \ 5; RUN: | FileCheck %s -check-prefix CHECK-HARD 6 7; Tests for passing floating-point regs. Variadic functions will always use 8; general-purpose registers. Standard functions will use the floating-point 9; registers if there is hardware FP available. 10 11declare i1 @non_variadic(float, float, float, float) 12declare i1 @non_variadic_big(float, float, float, float, float, float) 13declare i1 @variadic(float, ...) 14 15define void @non_variadic_fp(float %x, float %y) { 16; CHECK-SOFT-LABEL: non_variadic_fp: 17; CHECK-SOFT: @ %bb.0: @ %entry 18; CHECK-SOFT-NEXT: mov r3, r1 19; CHECK-SOFT-NEXT: mov r2, r0 20; CHECK-SOFT-NEXT: mov r0, r3 21; CHECK-SOFT-NEXT: mov r1, r2 22; CHECK-SOFT-NEXT: b non_variadic 23; 24; CHECK-HARD-LABEL: non_variadic_fp: 25; CHECK-HARD: @ %bb.0: @ %entry 26; CHECK-HARD-NEXT: vmov.f32 s3, s1 27; CHECK-HARD-NEXT: vmov.f32 s2, s0 28; CHECK-HARD-NEXT: vmov.f32 s0, s3 29; CHECK-HARD-NEXT: vmov.f32 s1, s2 30; CHECK-HARD-NEXT: b non_variadic 31entry: 32 %call = tail call i1 (float, float, float, float) @non_variadic(float %y, float %x, float %x, float %y) 33 ret void 34} 35 36define void @variadic_fp(float %x, float %y) { 37; CHECK-SOFT-LABEL: variadic_fp: 38; CHECK-SOFT: @ %bb.0: @ %entry 39; CHECK-SOFT-NEXT: mov r3, r1 40; CHECK-SOFT-NEXT: mov r2, r0 41; CHECK-SOFT-NEXT: mov r0, r3 42; CHECK-SOFT-NEXT: mov r1, r2 43; CHECK-SOFT-NEXT: b variadic 44; 45; CHECK-HARD-LABEL: variadic_fp: 46; CHECK-HARD: @ %bb.0: @ %entry 47; CHECK-HARD-NEXT: vmov r2, s0 48; CHECK-HARD-NEXT: vmov r3, s1 49; CHECK-HARD-NEXT: mov r0, r3 50; CHECK-HARD-NEXT: mov r1, r2 51; CHECK-HARD-NEXT: b variadic 52entry: 53 %call = tail call i1 (float, ...) @variadic(float %y, float %x, float %x, float %y) 54 ret void 55} 56 57; With soft-float, general-purpose registers are used and there are not enough 58; of them to handle the 6 arguments. With hard-float, we have plenty of regs 59; (s0-s15) to pass FP arguments. 60define void @non_variadic_fp_big(float %x, float %y) { 61; CHECK-SOFT-LABEL: non_variadic_fp_big: 62; CHECK-SOFT: @ %bb.0: @ %entry 63; CHECK-SOFT-NEXT: push {r11, lr} 64; CHECK-SOFT-NEXT: sub sp, sp, #8 65; CHECK-SOFT-NEXT: mov r3, r1 66; CHECK-SOFT-NEXT: mov r2, r0 67; CHECK-SOFT-NEXT: vmov s0, r3 68; CHECK-SOFT-NEXT: vmov s0, r2 69; CHECK-SOFT-NEXT: mov r0, sp 70; CHECK-SOFT-NEXT: str r3, [r0, #4] 71; CHECK-SOFT-NEXT: str r2, [r0] 72; CHECK-SOFT-NEXT: mov r0, r3 73; CHECK-SOFT-NEXT: mov r1, r2 74; CHECK-SOFT-NEXT: bl non_variadic_big 75; CHECK-SOFT-NEXT: add sp, sp, #8 76; CHECK-SOFT-NEXT: pop {r11, pc} 77; 78; CHECK-HARD-LABEL: non_variadic_fp_big: 79; CHECK-HARD: @ %bb.0: @ %entry 80; CHECK-HARD-NEXT: vmov.f32 s5, s1 81; CHECK-HARD-NEXT: vmov.f32 s4, s0 82; CHECK-HARD-NEXT: vmov.f32 s0, s5 83; CHECK-HARD-NEXT: vmov.f32 s1, s4 84; CHECK-HARD-NEXT: vmov.f32 s2, s4 85; CHECK-HARD-NEXT: vmov.f32 s3, s5 86; CHECK-HARD-NEXT: b non_variadic_big 87entry: 88 %call = tail call i1 (float, float, float, float, float, float) @non_variadic_big(float %y, float %x, float %x, float %y, float %x, float %y) 89 ret void 90} 91 92; Variadic functions cannot use FP regs to pass arguments; only GP regs. 93define void @variadic_fp_big(float %x, float %y) { 94; CHECK-SOFT-LABEL: variadic_fp_big: 95; CHECK-SOFT: @ %bb.0: @ %entry 96; CHECK-SOFT-NEXT: push {r11, lr} 97; CHECK-SOFT-NEXT: sub sp, sp, #8 98; CHECK-SOFT-NEXT: mov r3, r1 99; CHECK-SOFT-NEXT: mov r2, r0 100; CHECK-SOFT-NEXT: vmov s0, r3 101; CHECK-SOFT-NEXT: vmov s0, r2 102; CHECK-SOFT-NEXT: mov r0, sp 103; CHECK-SOFT-NEXT: str r3, [r0, #4] 104; CHECK-SOFT-NEXT: str r2, [r0] 105; CHECK-SOFT-NEXT: mov r0, r3 106; CHECK-SOFT-NEXT: mov r1, r2 107; CHECK-SOFT-NEXT: bl variadic 108; CHECK-SOFT-NEXT: add sp, sp, #8 109; CHECK-SOFT-NEXT: pop {r11, pc} 110; 111; CHECK-HARD-LABEL: variadic_fp_big: 112; CHECK-HARD: @ %bb.0: @ %entry 113; CHECK-HARD-NEXT: push {r11, lr} 114; CHECK-HARD-NEXT: sub sp, sp, #8 115; CHECK-HARD-NEXT: mov r0, sp 116; CHECK-HARD-NEXT: vstr s1, [r0, #4] 117; CHECK-HARD-NEXT: vstr s0, [r0] 118; CHECK-HARD-NEXT: vmov r2, s0 119; CHECK-HARD-NEXT: vmov r3, s1 120; CHECK-HARD-NEXT: mov r0, r3 121; CHECK-HARD-NEXT: mov r1, r2 122; CHECK-HARD-NEXT: bl variadic 123; CHECK-HARD-NEXT: add sp, sp, #8 124; CHECK-HARD-NEXT: pop {r11, pc} 125entry: 126 %call = tail call i1 (float, ...) @variadic(float %y, float %x, float %x, float %y, float %x, float %y) 127 ret void 128} 129;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: 130; CHECK: {{.*}} 131