1 ; Test incoming GPR, FPR and stack arguments when no extension type is given. 2 ; This type of argument is used for passing structures, etc. 3 ; 4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -verify-machineinstrs | FileCheck %s 5 6 ; Do some arithmetic so that we can see the register being used. 7 define i8 @f1(i8 %r2) { 8 ; CHECK-LABEL: f1: 9 ; CHECK: ahi %r2, 1 10 ; CHECK: br %r14 11 %y = add i8 %r2, 1 12 ret i8 %y 13 } 14 15 define i16 @f2(i8 %r2, i16 %r3) { 16 ; CHECK-LABEL: f2: 17 ; CHECK: {{lr|lgr}} %r2, %r3 18 ; CHECK: br %r14 19 ret i16 %r3 20 } 21 22 define i32 @f3(i8 %r2, i16 %r3, i32 %r4) { 23 ; CHECK-LABEL: f3: 24 ; CHECK: {{lr|lgr}} %r2, %r4 25 ; CHECK: br %r14 26 ret i32 %r4 27 } 28 29 define i64 @f4(i8 %r2, i16 %r3, i32 %r4, i64 %r5) { 30 ; CHECK-LABEL: f4: 31 ; CHECK: {{lr|lgr}} %r2, %r5 32 ; CHECK: br %r14 33 ret i64 %r5 34 } 35 36 ; Do some arithmetic so that we can see the register being used. 37 define float @f5(i8 %r2, i16 %r3, i32 %r4, i64 %r5, float %f0) { 38 ; CHECK-LABEL: f5: 39 ; CHECK: aebr %f0, %f0 40 ; CHECK: br %r14 41 %y = fadd float %f0, %f0 42 ret float %y 43 } 44 45 define double @f6(i8 %r2, i16 %r3, i32 %r4, i64 %r5, float %f0, double %f2) { 46 ; CHECK-LABEL: f6: 47 ; CHECK: ldr %f0, %f2 48 ; CHECK: br %r14 49 ret double %f2 50 } 51 52 ; fp128s are passed indirectly. Do some arithmetic so that the value 53 ; must be interpreted as a float, rather than as a block of memory to 54 ; be copied. 55 define void @f7(fp128 *%r2, i16 %r3, i32 %r4, i64 %r5, float %f0, double %f2, 56 fp128 %r6) { 57 ; CHECK-LABEL: f7: 58 ; CHECK: ld %f0, 0(%r6) 59 ; CHECK: ld %f2, 8(%r6) 60 ; CHECK: axbr %f0, %f0 61 ; CHECK: std %f0, 0(%r2) 62 ; CHECK: std %f2, 8(%r2) 63 ; CHECK: br %r14 64 %y = fadd fp128 %r6, %r6 65 store fp128 %y, fp128 *%r2 66 ret void 67 } 68 69 define i64 @f8(i8 %r2, i16 %r3, i32 %r4, i64 %r5, float %f0, double %f2, 70 fp128 %r6, i64 %s1) { 71 ; CHECK-LABEL: f8: 72 ; CHECK: lg %r2, 160(%r15) 73 ; CHECK: br %r14 74 ret i64 %s1 75 } 76 77 define float @f9(i8 %r2, i16 %r3, i32 %r4, i64 %r5, float %f0, double %f2, 78 fp128 %r6, i64 %s1, float %f4) { 79 ; CHECK-LABEL: f9: 80 ; CHECK: ler %f0, %f4 81 ; CHECK: br %r14 82 ret float %f4 83 } 84 85 define double @f10(i8 %r2, i16 %r3, i32 %r4, i64 %r5, float %f0, double %f2, 86 fp128 %r6, i64 %s1, float %f4, double %f6) { 87 ; CHECK-LABEL: f10: 88 ; CHECK: ldr %f0, %f6 89 ; CHECK: br %r14 90 ret double %f6 91 } 92 93 define i64 @f11(i8 %r2, i16 %r3, i32 %r4, i64 %r5, float %f0, double %f2, 94 fp128 %r6, i64 %s1, float %f4, double %f6, i64 %s2) { 95 ; CHECK-LABEL: f11: 96 ; CHECK: lg %r2, 168(%r15) 97 ; CHECK: br %r14 98 ret i64 %s2 99 } 100 101 ; Floats are passed right-justified. 102 define float @f12(i8 %r2, i16 %r3, i32 %r4, i64 %r5, float %f0, double %f2, 103 fp128 %r6, i64 %s1, float %f4, double %f6, i64 %s2, 104 float %s3) { 105 ; CHECK-LABEL: f12: 106 ; CHECK: le %f0, 180(%r15) 107 ; CHECK: br %r14 108 ret float %s3 109 } 110 111 ; Test a case where the fp128 address is passed on the stack. 112 define void @f13(fp128 *%r2, i16 %r3, i32 %r4, i64 %r5, float %f0, double %f2, 113 fp128 %r6, i64 %s1, float %f4, double %f6, i64 %s2, 114 float %s3, fp128 %s4) { 115 ; CHECK-LABEL: f13: 116 ; CHECK: lg [[REGISTER:%r[1-5]+]], 184(%r15) 117 ; CHECK: ld %f0, 0([[REGISTER]]) 118 ; CHECK: ld %f2, 8([[REGISTER]]) 119 ; CHECK: axbr %f0, %f0 120 ; CHECK: std %f0, 0(%r2) 121 ; CHECK: std %f2, 8(%r2) 122 ; CHECK: br %r14 123 %y = fadd fp128 %s4, %s4 124 store fp128 %y, fp128 *%r2 125 ret void 126 } 127 128 ; Explicit fp128 return values are likewise passed indirectly. 129 define fp128 @f14(fp128 %r3) { 130 ; CHECK-LABEL: f14: 131 ; CHECK: ld %f0, 0(%r3) 132 ; CHECK: ld %f2, 8(%r3) 133 ; CHECK: axbr %f0, %f0 134 ; CHECK: std %f0, 0(%r2) 135 ; CHECK: std %f2, 8(%r2) 136 ; CHECK: br %r14 137 %y = fadd fp128 %r3, %r3 138 ret fp128 %y 139 } 140 141