llvm.org GIT mirror llvm / 97d9f08
Implement MipsTargetLowering::CanLowerReturn. Patch by Sasa Stankovic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165585 91177308-0d34-0410-b5e6-96231b3b80d8 Akira Hatanaka 8 years ago
3 changed file(s) with 266 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
25962596 llvm_unreachable("Cannot handle this ValVT.");
25972597
25982598 unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
2599 unsigned Offset = State.AllocateStack(SizeInBytes, OrigAlign);
2599 unsigned Offset;
2600 if (!ArgFlags.isSRet())
2601 Offset = State.AllocateStack(SizeInBytes, OrigAlign);
2602 else
2603 Offset = State.AllocateStack(SizeInBytes, SizeInBytes);
26002604
26012605 if (!Reg)
26022606 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
34383442 //===----------------------------------------------------------------------===//
34393443 // Return Value Calling Convention Implementation
34403444 //===----------------------------------------------------------------------===//
3445
3446 bool
3447 MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
3448 MachineFunction &MF, bool isVarArg,
3449 const SmallVectorImpl &Outs,
3450 LLVMContext &Context) const {
3451 SmallVector RVLocs;
3452 CCState CCInfo(CallConv, isVarArg, MF, getTargetMachine(),
3453 RVLocs, Context);
3454 return CCInfo.CheckReturn(Outs, RetCC_Mips);
3455 }
34413456
34423457 SDValue
34433458 MipsTargetLowering::LowerReturn(SDValue Chain,
215215 LowerCall(TargetLowering::CallLoweringInfo &CLI,
216216 SmallVectorImpl &InVals) const;
217217
218 virtual bool
219 CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
220 bool isVarArg,
221 const SmallVectorImpl &Outs,
222 LLVMContext &Context) const;
223
218224 virtual SDValue
219225 LowerReturn(SDValue Chain,
220226 CallingConv::ID CallConv, bool isVarArg,
0 ; RUN: llc -march=mipsel < %s | FileCheck %s
1
2
3 ; Check that function accesses vector return value from stack in cases when
4 ; vector can't be returned in registers. Also check that caller passes in
5 ; register $4 stack address where the vector should be placed.
6
7
8 declare <8 x i32> @i8(...)
9 declare <4 x float> @f4(...)
10 declare <4 x double> @d4(...)
11
12 define i32 @call_i8() {
13 entry:
14 %call = call <8 x i32> (...)* @i8()
15 %v0 = extractelement <8 x i32> %call, i32 0
16 %v1 = extractelement <8 x i32> %call, i32 1
17 %v2 = extractelement <8 x i32> %call, i32 2
18 %v3 = extractelement <8 x i32> %call, i32 3
19 %v4 = extractelement <8 x i32> %call, i32 4
20 %v5 = extractelement <8 x i32> %call, i32 5
21 %v6 = extractelement <8 x i32> %call, i32 6
22 %v7 = extractelement <8 x i32> %call, i32 7
23 %add1 = add i32 %v0, %v1
24 %add2 = add i32 %v2, %v3
25 %add3 = add i32 %v4, %v5
26 %add4 = add i32 %v6, %v7
27 %add5 = add i32 %add1, %add2
28 %add6 = add i32 %add3, %add4
29 %add7 = add i32 %add5, %add6
30 ret i32 %add7
31
32 ; CHECK: call_i8:
33 ; CHECK: call16(i8)
34 ; CHECK: addiu $4, $sp, 32
35 ; CHECK: lw $[[R0:[a-z0-9]+]], 60($sp)
36 ; CHECK: lw $[[R1:[a-z0-9]+]], 56($sp)
37 ; CHECK: lw $[[R2:[a-z0-9]+]], 52($sp)
38 ; CHECK: lw $[[R3:[a-z0-9]+]], 48($sp)
39 ; CHECK: lw $[[R4:[a-z0-9]+]], 44($sp)
40 ; CHECK: lw $[[R5:[a-z0-9]+]], 40($sp)
41 ; CHECK: lw $[[R6:[a-z0-9]+]], 36($sp)
42 ; CHECK: lw $[[R7:[a-z0-9]+]], 32($sp)
43 }
44
45
46 define float @call_f4() {
47 entry:
48 %call = call <4 x float> (...)* @f4()
49 %v0 = extractelement <4 x float> %call, i32 0
50 %v1 = extractelement <4 x float> %call, i32 1
51 %v2 = extractelement <4 x float> %call, i32 2
52 %v3 = extractelement <4 x float> %call, i32 3
53 %add1 = fadd float %v0, %v1
54 %add2 = fadd float %v2, %v3
55 %add3 = fadd float %add1, %add2
56 ret float %add3
57
58 ; CHECK: call_f4:
59 ; CHECK: call16(f4)
60 ; CHECK: addiu $4, $sp, 16
61 ; CHECK: lwc1 $[[R0:[a-z0-9]+]], 28($sp)
62 ; CHECK: lwc1 $[[R1:[a-z0-9]+]], 24($sp)
63 ; CHECK: lwc1 $[[R3:[a-z0-9]+]], 20($sp)
64 ; CHECK: lwc1 $[[R4:[a-z0-9]+]], 16($sp)
65 }
66
67
68 define double @call_d4() {
69 entry:
70 %call = call <4 x double> (...)* @d4()
71 %v0 = extractelement <4 x double> %call, i32 0
72 %v1 = extractelement <4 x double> %call, i32 1
73 %v2 = extractelement <4 x double> %call, i32 2
74 %v3 = extractelement <4 x double> %call, i32 3
75 %add1 = fadd double %v0, %v1
76 %add2 = fadd double %v2, %v3
77 %add3 = fadd double %add1, %add2
78 ret double %add3
79
80 ; CHECK: call_d4:
81 ; CHECK: call16(d4)
82 ; CHECK: addiu $4, $sp, 32
83 ; CHECK: ldc1 $[[R0:[a-z0-9]+]], 56($sp)
84 ; CHECK: ldc1 $[[R1:[a-z0-9]+]], 48($sp)
85 ; CHECK: ldc1 $[[R3:[a-z0-9]+]], 40($sp)
86 ; CHECK: ldc1 $[[R4:[a-z0-9]+]], 32($sp)
87 }
88
89
90
91 ; Check that function accesses vector return value from registers in cases when
92 ; vector can be returned in registers
93
94
95 declare <4 x i32> @i4(...)
96 declare <2 x float> @f2(...)
97 declare <2 x double> @d2(...)
98
99 define i32 @call_i4() {
100 entry:
101 %call = call <4 x i32> (...)* @i4()
102 %v0 = extractelement <4 x i32> %call, i32 0
103 %v1 = extractelement <4 x i32> %call, i32 1
104 %v2 = extractelement <4 x i32> %call, i32 2
105 %v3 = extractelement <4 x i32> %call, i32 3
106 %add1 = add i32 %v0, %v1
107 %add2 = add i32 %v2, %v3
108 %add3 = add i32 %add1, %add2
109 ret i32 %add3
110
111 ; CHECK: call_i4:
112 ; CHECK: call16(i4)
113 ; CHECK-NOT: lw
114 ; CHECK: addu $[[R2:[a-z0-9]+]], $[[R0:[a-z0-9]+]], $[[R1:[a-z0-9]+]]
115 ; CHECK: addu $[[R5:[a-z0-9]+]], $[[R3:[a-z0-9]+]], $[[R4:[a-z0-9]+]]
116 ; CHECK: addu $[[R6:[a-z0-9]+]], $[[R5]], $[[R2]]
117 }
118
119
120 define float @call_f2() {
121 entry:
122 %call = call <2 x float> (...)* @f2()
123 %v0 = extractelement <2 x float> %call, i32 0
124 %v1 = extractelement <2 x float> %call, i32 1
125 %add1 = fadd float %v0, %v1
126 ret float %add1
127
128 ; CHECK: call_f2:
129 ; CHECK: call16(f2)
130 ; CHECK-NOT: lwc1
131 ; CHECK: add.s $[[R2:[a-z0-9]+]], $[[R0:[a-z0-9]+]], $[[R1:[a-z0-9]+]]
132 }
133
134
135 define double @call_d2() {
136 entry:
137 %call = call <2 x double> (...)* @d2()
138 %v0 = extractelement <2 x double> %call, i32 0
139 %v1 = extractelement <2 x double> %call, i32 1
140 %add1 = fadd double %v0, %v1
141 ret double %add1
142
143 ; CHECK: call_d2:
144 ; CHECK: call16(d2)
145 ; CHECK-NOT: ldc1
146 ; CHECK: add.d $[[R2:[a-z0-9]+]], $[[R0:[a-z0-9]+]], $[[R1:[a-z0-9]+]]
147 }
148
149
150
151 ; Check that function returns vector on stack in cases when vector can't be
152 ; returned in registers. Also check that vector is placed on stack starting
153 ; from the address in register $4.
154
155
156 define <8 x i32> @return_i8() {
157 entry:
158 ret <8 x i32>
159
160 ; CHECK: return_i8:
161 ; CHECK: sw $[[R0:[a-z0-9]+]], 28($4)
162 ; CHECK: sw $[[R1:[a-z0-9]+]], 24($4)
163 ; CHECK: sw $[[R2:[a-z0-9]+]], 20($4)
164 ; CHECK: sw $[[R3:[a-z0-9]+]], 16($4)
165 ; CHECK: sw $[[R4:[a-z0-9]+]], 12($4)
166 ; CHECK: sw $[[R5:[a-z0-9]+]], 8($4)
167 ; CHECK: sw $[[R6:[a-z0-9]+]], 4($4)
168 ; CHECK: sw $[[R7:[a-z0-9]+]], 0($4)
169 }
170
171
172 define <4 x float> @return_f4(float %a, float %b, float %c, float %d) {
173 entry:
174 %vecins1 = insertelement <4 x float> undef, float %a, i32 0
175 %vecins2 = insertelement <4 x float> %vecins1, float %b, i32 1
176 %vecins3 = insertelement <4 x float> %vecins2, float %c, i32 2
177 %vecins4 = insertelement <4 x float> %vecins3, float %d, i32 3
178 ret <4 x float> %vecins4
179
180 ; CHECK: return_f4:
181 ; CHECK: lwc1 $[[R0:[a-z0-9]+]], 16($sp)
182 ; CHECK: swc1 $[[R0]], 12($4)
183 ; CHECK: sw $7, 8($4)
184 ; CHECK: sw $6, 4($4)
185 ; CHECK: sw $5, 0($4)
186 }
187
188
189 define <4 x double> @return_d4(double %a, double %b, double %c, double %d) {
190 entry:
191 %vecins1 = insertelement <4 x double> undef, double %a, i32 0
192 %vecins2 = insertelement <4 x double> %vecins1, double %b, i32 1
193 %vecins3 = insertelement <4 x double> %vecins2, double %c, i32 2
194 %vecins4 = insertelement <4 x double> %vecins3, double %d, i32 3
195 ret <4 x double> %vecins4
196
197 ; CHECK: return_d4:
198 ; CHECK: sdc1 $[[R0:[a-z0-9]+]], 24($4)
199 ; CHECK: sdc1 $[[R1:[a-z0-9]+]], 16($4)
200 ; CHECK: sdc1 $[[R2:[a-z0-9]+]], 8($4)
201 ; CHECK: sdc1 $[[R3:[a-z0-9]+]], 0($4)
202 }
203
204
205
206 ; Check that function returns vector in registers in cases when vector can be
207 ; returned in registers.
208
209
210 define <4 x i32> @return_i4() {
211 entry:
212 ret <4 x i32>
213
214 ; CHECK: return_i4:
215 ; CHECK: addiu $2, $zero, 0
216 ; CHECK: addiu $3, $zero, 1
217 ; CHECK: addiu $4, $zero, 2
218 ; CHECK: addiu $5, $zero, 3
219 }
220
221
222 define <2 x float> @return_f2(float %a, float %b) {
223 entry:
224 %vecins1 = insertelement <2 x float> undef, float %a, i32 0
225 %vecins2 = insertelement <2 x float> %vecins1, float %b, i32 1
226 ret <2 x float> %vecins2
227
228 ; CHECK: return_f2:
229 ; CHECK: mov.s $f0, $f12
230 ; CHECK: mov.s $f2, $f14
231 }
232
233
234 define <2 x double> @return_d2(double %a, double %b) {
235 entry:
236 %vecins1 = insertelement <2 x double> undef, double %a, i32 0
237 %vecins2 = insertelement <2 x double> %vecins1, double %b, i32 1
238 ret <2 x double> %vecins2
239
240 ; CHECK: return_d2:
241 ; CHECK: mov.d $f0, $f12
242 ; CHECK: mov.d $f2, $f14
243 }