Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 //===-- ARMISelLowering.cpp - ARM DAG Lowering Implementation -------------===// | 1 //===-- ARMISelLowering.cpp - ARM DAG Lowering Implementation -------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines the interfaces that ARM uses to lower LLVM code into a | 10 // This file defines the interfaces that ARM uses to lower LLVM code into a |
11 // selection DAG. | 11 // selection DAG. |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #include "ARM.h" | 15 #include "ARM.h" |
16 #include "ARMAddressingModes.h" | 16 #include "ARMAddressingModes.h" |
17 #include "ARMConstantPoolValue.h" | 17 #include "ARMConstantPoolValue.h" |
18 #include "ARMISelLowering.h" | 18 #include "ARMISelLowering.h" |
19 #include "ARMMachineFunctionInfo.h" | 19 #include "ARMMachineFunctionInfo.h" |
20 #include "ARMRegisterInfo.h" | 20 #include "ARMRegisterInfo.h" |
21 #include "ARMSubtarget.h" | 21 #include "ARMSubtarget.h" |
22 #include "ARMTargetMachine.h" | 22 #include "ARMTargetMachine.h" |
23 #include "ARMTargetObjectFile.h" | |
23 #include "llvm/CallingConv.h" | 24 #include "llvm/CallingConv.h" |
24 #include "llvm/Constants.h" | 25 #include "llvm/Constants.h" |
25 #include "llvm/Function.h" | 26 #include "llvm/Function.h" |
26 #include "llvm/Instruction.h" | 27 #include "llvm/Instruction.h" |
27 #include "llvm/Intrinsics.h" | 28 #include "llvm/Intrinsics.h" |
28 #include "llvm/GlobalValue.h" | 29 #include "llvm/GlobalValue.h" |
29 #include "llvm/CodeGen/CallingConvLower.h" | 30 #include "llvm/CodeGen/CallingConvLower.h" |
30 #include "llvm/CodeGen/MachineBasicBlock.h" | 31 #include "llvm/CodeGen/MachineBasicBlock.h" |
31 #include "llvm/CodeGen/MachineFrameInfo.h" | 32 #include "llvm/CodeGen/MachineFrameInfo.h" |
32 #include "llvm/CodeGen/MachineFunction.h" | 33 #include "llvm/CodeGen/MachineFunction.h" |
33 #include "llvm/CodeGen/MachineInstrBuilder.h" | 34 #include "llvm/CodeGen/MachineInstrBuilder.h" |
34 #include "llvm/CodeGen/MachineRegisterInfo.h" | 35 #include "llvm/CodeGen/MachineRegisterInfo.h" |
35 #include "llvm/CodeGen/PseudoSourceValue.h" | 36 #include "llvm/CodeGen/PseudoSourceValue.h" |
36 #include "llvm/CodeGen/SelectionDAG.h" | 37 #include "llvm/CodeGen/SelectionDAG.h" |
37 #include "llvm/Target/TargetOptions.h" | 38 #include "llvm/Target/TargetOptions.h" |
38 #include "llvm/ADT/VectorExtras.h" | 39 #include "llvm/ADT/VectorExtras.h" |
40 #include "llvm/Support/ErrorHandling.h" | |
39 #include "llvm/Support/MathExtras.h" | 41 #include "llvm/Support/MathExtras.h" |
40 using namespace llvm; | 42 using namespace llvm; |
41 | 43 |
42 static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, | 44 static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, |
43 CCValAssign::LocInfo &LocInfo, | 45 CCValAssign::LocInfo &LocInfo, |
44 ISD::ArgFlagsTy &ArgFlags, | 46 ISD::ArgFlagsTy &ArgFlags, |
45 CCState &State); | 47 CCState &State); |
46 static bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, | 48 static bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, |
47 CCValAssign::LocInfo &LocInfo, | 49 CCValAssign::LocInfo &LocInfo, |
48 ISD::ArgFlagsTy &ArgFlags, | 50 ISD::ArgFlagsTy &ArgFlags, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 void ARMTargetLowering::addDRTypeForNEON(MVT VT) { | 97 void ARMTargetLowering::addDRTypeForNEON(MVT VT) { |
96 addRegisterClass(VT, ARM::DPRRegisterClass); | 98 addRegisterClass(VT, ARM::DPRRegisterClass); |
97 addTypeForNEON(VT, MVT::f64, MVT::v2i32); | 99 addTypeForNEON(VT, MVT::f64, MVT::v2i32); |
98 } | 100 } |
99 | 101 |
100 void ARMTargetLowering::addQRTypeForNEON(MVT VT) { | 102 void ARMTargetLowering::addQRTypeForNEON(MVT VT) { |
101 addRegisterClass(VT, ARM::QPRRegisterClass); | 103 addRegisterClass(VT, ARM::QPRRegisterClass); |
102 addTypeForNEON(VT, MVT::v2f64, MVT::v4i32); | 104 addTypeForNEON(VT, MVT::v2f64, MVT::v4i32); |
103 } | 105 } |
104 | 106 |
107 static TargetLoweringObjectFile *createTLOF(TargetMachine &TM) { | |
108 if (TM.getSubtarget<ARMSubtarget>().isTargetDarwin()) | |
109 return new TargetLoweringObjectFileMachO(); | |
110 return new ARMElfTargetObjectFile(); | |
111 } | |
112 | |
105 ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) | 113 ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) |
106 : TargetLowering(TM), ARMPCLabelIndex(0) { | 114 : TargetLowering(TM, createTLOF(TM)), ARMPCLabelIndex(0) { |
107 Subtarget = &TM.getSubtarget<ARMSubtarget>(); | 115 Subtarget = &TM.getSubtarget<ARMSubtarget>(); |
108 | 116 |
109 if (Subtarget->isTargetDarwin()) { | 117 if (Subtarget->isTargetDarwin()) { |
110 // Uses VFP for Thumb libfuncs if available. | 118 // Uses VFP for Thumb libfuncs if available. |
111 if (Subtarget->isThumb() && Subtarget->hasVFP2()) { | 119 if (Subtarget->isThumb() && Subtarget->hasVFP2()) { |
112 // Single-precision floating-point arithmetic. | 120 // Single-precision floating-point arithmetic. |
113 setLibcallName(RTLIB::ADD_F32, "__addsf3vfp"); | 121 setLibcallName(RTLIB::ADD_F32, "__addsf3vfp"); |
114 setLibcallName(RTLIB::SUB_F32, "__subsf3vfp"); | 122 setLibcallName(RTLIB::SUB_F32, "__subsf3vfp"); |
115 setLibcallName(RTLIB::MUL_F32, "__mulsf3vfp"); | 123 setLibcallName(RTLIB::MUL_F32, "__mulsf3vfp"); |
116 setLibcallName(RTLIB::DIV_F32, "__divsf3vfp"); | 124 setLibcallName(RTLIB::DIV_F32, "__divsf3vfp"); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 setLibcallName(RTLIB::SINTTOFP_I32_F32, "__floatsisfvfp"); | 189 setLibcallName(RTLIB::SINTTOFP_I32_F32, "__floatsisfvfp"); |
182 setLibcallName(RTLIB::UINTTOFP_I32_F32, "__floatunssisfvfp"); | 190 setLibcallName(RTLIB::UINTTOFP_I32_F32, "__floatunssisfvfp"); |
183 } | 191 } |
184 } | 192 } |
185 | 193 |
186 // These libcalls are not available in 32-bit. | 194 // These libcalls are not available in 32-bit. |
187 setLibcallName(RTLIB::SHL_I128, 0); | 195 setLibcallName(RTLIB::SHL_I128, 0); |
188 setLibcallName(RTLIB::SRL_I128, 0); | 196 setLibcallName(RTLIB::SRL_I128, 0); |
189 setLibcallName(RTLIB::SRA_I128, 0); | 197 setLibcallName(RTLIB::SRA_I128, 0); |
190 | 198 |
191 if (Subtarget->isThumb()) | 199 if (Subtarget->isThumb1Only()) |
192 addRegisterClass(MVT::i32, ARM::tGPRRegisterClass); | 200 addRegisterClass(MVT::i32, ARM::tGPRRegisterClass); |
193 else | 201 else |
194 addRegisterClass(MVT::i32, ARM::GPRRegisterClass); | 202 addRegisterClass(MVT::i32, ARM::GPRRegisterClass); |
195 if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb()) { | 203 if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) { |
196 addRegisterClass(MVT::f32, ARM::SPRRegisterClass); | 204 addRegisterClass(MVT::f32, ARM::SPRRegisterClass); |
197 addRegisterClass(MVT::f64, ARM::DPRRegisterClass); | 205 addRegisterClass(MVT::f64, ARM::DPRRegisterClass); |
198 | 206 |
199 setTruncStoreAction(MVT::f64, MVT::f32, Expand); | 207 setTruncStoreAction(MVT::f64, MVT::f32, Expand); |
200 } | 208 } |
201 | 209 |
202 if (Subtarget->hasNEON()) { | 210 if (Subtarget->hasNEON()) { |
203 addDRTypeForNEON(MVT::v2f32); | 211 addDRTypeForNEON(MVT::v2f32); |
204 addDRTypeForNEON(MVT::v8i8); | 212 addDRTypeForNEON(MVT::v8i8); |
205 addDRTypeForNEON(MVT::v4i16); | 213 addDRTypeForNEON(MVT::v4i16); |
(...skipping 18 matching lines...) Expand all Loading... | |
224 | 232 |
225 computeRegisterProperties(); | 233 computeRegisterProperties(); |
226 | 234 |
227 // ARM does not have f32 extending load. | 235 // ARM does not have f32 extending load. |
228 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); | 236 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); |
229 | 237 |
230 // ARM does not have i1 sign extending load. | 238 // ARM does not have i1 sign extending load. |
231 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); | 239 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); |
232 | 240 |
233 // ARM supports all 4 flavors of integer indexed load / store. | 241 // ARM supports all 4 flavors of integer indexed load / store. |
234 for (unsigned im = (unsigned)ISD::PRE_INC; | 242 if (!Subtarget->isThumb1Only()) { |
235 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) { | 243 for (unsigned im = (unsigned)ISD::PRE_INC; |
236 setIndexedLoadAction(im, MVT::i1, Legal); | 244 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) { |
237 setIndexedLoadAction(im, MVT::i8, Legal); | 245 setIndexedLoadAction(im, MVT::i1, Legal); |
238 setIndexedLoadAction(im, MVT::i16, Legal); | 246 setIndexedLoadAction(im, MVT::i8, Legal); |
239 setIndexedLoadAction(im, MVT::i32, Legal); | 247 setIndexedLoadAction(im, MVT::i16, Legal); |
240 setIndexedStoreAction(im, MVT::i1, Legal); | 248 setIndexedLoadAction(im, MVT::i32, Legal); |
241 setIndexedStoreAction(im, MVT::i8, Legal); | 249 setIndexedStoreAction(im, MVT::i1, Legal); |
242 setIndexedStoreAction(im, MVT::i16, Legal); | 250 setIndexedStoreAction(im, MVT::i8, Legal); |
243 setIndexedStoreAction(im, MVT::i32, Legal); | 251 setIndexedStoreAction(im, MVT::i16, Legal); |
252 setIndexedStoreAction(im, MVT::i32, Legal); | |
253 } | |
244 } | 254 } |
245 | 255 |
246 // i64 operation support. | 256 // i64 operation support. |
247 if (Subtarget->isThumb()) { | 257 if (Subtarget->isThumb1Only()) { |
248 setOperationAction(ISD::MUL, MVT::i64, Expand); | 258 setOperationAction(ISD::MUL, MVT::i64, Expand); |
249 setOperationAction(ISD::MULHU, MVT::i32, Expand); | 259 setOperationAction(ISD::MULHU, MVT::i32, Expand); |
250 setOperationAction(ISD::MULHS, MVT::i32, Expand); | 260 setOperationAction(ISD::MULHS, MVT::i32, Expand); |
251 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); | 261 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); |
252 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); | 262 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); |
253 } else { | 263 } else { |
254 setOperationAction(ISD::MUL, MVT::i64, Expand); | 264 setOperationAction(ISD::MUL, MVT::i64, Expand); |
255 setOperationAction(ISD::MULHU, MVT::i32, Expand); | 265 setOperationAction(ISD::MULHU, MVT::i32, Expand); |
256 if (!Subtarget->hasV6Ops()) | 266 if (!Subtarget->hasV6Ops()) |
257 setOperationAction(ISD::MULHS, MVT::i32, Expand); | 267 setOperationAction(ISD::MULHS, MVT::i32, Expand); |
258 } | 268 } |
259 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); | 269 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); |
260 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); | 270 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); |
261 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); | 271 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); |
262 setOperationAction(ISD::SRL, MVT::i64, Custom); | 272 setOperationAction(ISD::SRL, MVT::i64, Custom); |
263 setOperationAction(ISD::SRA, MVT::i64, Custom); | 273 setOperationAction(ISD::SRA, MVT::i64, Custom); |
264 | 274 |
265 // ARM does not have ROTL. | 275 // ARM does not have ROTL. |
266 setOperationAction(ISD::ROTL, MVT::i32, Expand); | 276 setOperationAction(ISD::ROTL, MVT::i32, Expand); |
267 setOperationAction(ISD::CTTZ, MVT::i32, Expand); | 277 setOperationAction(ISD::CTTZ, MVT::i32, Expand); |
268 setOperationAction(ISD::CTPOP, MVT::i32, Expand); | 278 setOperationAction(ISD::CTPOP, MVT::i32, Expand); |
269 if (!Subtarget->hasV5TOps() || Subtarget->isThumb()) | 279 if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) |
270 setOperationAction(ISD::CTLZ, MVT::i32, Expand); | 280 setOperationAction(ISD::CTLZ, MVT::i32, Expand); |
271 | 281 |
272 // Only ARMv6 has BSWAP. | 282 // Only ARMv6 has BSWAP. |
273 if (!Subtarget->hasV6Ops()) | 283 if (!Subtarget->hasV6Ops()) |
274 setOperationAction(ISD::BSWAP, MVT::i32, Expand); | 284 setOperationAction(ISD::BSWAP, MVT::i32, Expand); |
275 | 285 |
276 // These are expanded into libcalls. | 286 // These are expanded into libcalls. |
277 setOperationAction(ISD::SDIV, MVT::i32, Expand); | 287 setOperationAction(ISD::SDIV, MVT::i32, Expand); |
278 setOperationAction(ISD::UDIV, MVT::i32, Expand); | 288 setOperationAction(ISD::UDIV, MVT::i32, Expand); |
279 setOperationAction(ISD::SREM, MVT::i32, Expand); | 289 setOperationAction(ISD::SREM, MVT::i32, Expand); |
280 setOperationAction(ISD::UREM, MVT::i32, Expand); | 290 setOperationAction(ISD::UREM, MVT::i32, Expand); |
281 setOperationAction(ISD::SDIVREM, MVT::i32, Expand); | 291 setOperationAction(ISD::SDIVREM, MVT::i32, Expand); |
282 setOperationAction(ISD::UDIVREM, MVT::i32, Expand); | 292 setOperationAction(ISD::UDIVREM, MVT::i32, Expand); |
283 | 293 |
284 // Support label based line numbers. | 294 // Support label based line numbers. |
285 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand); | 295 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand); |
286 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); | 296 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); |
287 | 297 |
288 setOperationAction(ISD::RET, MVT::Other, Custom); | |
289 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); | 298 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); |
290 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); | 299 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); |
291 if (!Subtarget->useInlineJumpTables()) | 300 if (!Subtarget->useInlineJumpTables()) |
292 setOperationAction(ISD::JumpTable, MVT::i32, Custom); | 301 setOperationAction(ISD::JumpTable, MVT::i32, Custom); |
293 setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); | 302 setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); |
294 setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); | 303 setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); |
295 | 304 |
296 // Use the default implementation. | 305 // Use the default implementation. |
297 setOperationAction(ISD::VASTART, MVT::Other, Custom); | 306 setOperationAction(ISD::VASTART, MVT::Other, Custom); |
298 setOperationAction(ISD::VAARG, MVT::Other, Expand); | 307 setOperationAction(ISD::VAARG, MVT::Other, Expand); |
299 setOperationAction(ISD::VACOPY, MVT::Other, Expand); | 308 setOperationAction(ISD::VACOPY, MVT::Other, Expand); |
300 setOperationAction(ISD::VAEND, MVT::Other, Expand); | 309 setOperationAction(ISD::VAEND, MVT::Other, Expand); |
301 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); | 310 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); |
302 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); | 311 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); |
303 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); | 312 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); |
304 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); | 313 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); |
305 | 314 |
306 if (!Subtarget->hasV6Ops()) { | 315 if (!Subtarget->hasV6Ops() && !Subtarget->isThumb2()) { |
307 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); | 316 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); |
308 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand); | 317 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand); |
309 } | 318 } |
310 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); | 319 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); |
311 | 320 |
312 if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb()) | 321 if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) |
313 // Turn f64->i64 into FMRRD, i64 -> f64 to FMDRR iff target supports vfp2. | 322 // Turn f64->i64 into FMRRD, i64 -> f64 to FMDRR iff target supports vfp2. |
314 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Custom); | 323 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Custom); |
315 | 324 |
316 // We want to custom lower some of our intrinsics. | 325 // We want to custom lower some of our intrinsics. |
317 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); | 326 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); |
327 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); | |
318 | 328 |
319 setOperationAction(ISD::SETCC, MVT::i32, Expand); | 329 setOperationAction(ISD::SETCC, MVT::i32, Expand); |
320 setOperationAction(ISD::SETCC, MVT::f32, Expand); | 330 setOperationAction(ISD::SETCC, MVT::f32, Expand); |
321 setOperationAction(ISD::SETCC, MVT::f64, Expand); | 331 setOperationAction(ISD::SETCC, MVT::f64, Expand); |
322 setOperationAction(ISD::SELECT, MVT::i32, Expand); | 332 setOperationAction(ISD::SELECT, MVT::i32, Expand); |
323 setOperationAction(ISD::SELECT, MVT::f32, Expand); | 333 setOperationAction(ISD::SELECT, MVT::f32, Expand); |
324 setOperationAction(ISD::SELECT, MVT::f64, Expand); | 334 setOperationAction(ISD::SELECT, MVT::f64, Expand); |
325 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); | 335 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); |
326 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); | 336 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); |
327 setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); | 337 setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); |
328 | 338 |
329 setOperationAction(ISD::BRCOND, MVT::Other, Expand); | 339 setOperationAction(ISD::BRCOND, MVT::Other, Expand); |
330 setOperationAction(ISD::BR_CC, MVT::i32, Custom); | 340 setOperationAction(ISD::BR_CC, MVT::i32, Custom); |
331 setOperationAction(ISD::BR_CC, MVT::f32, Custom); | 341 setOperationAction(ISD::BR_CC, MVT::f32, Custom); |
332 setOperationAction(ISD::BR_CC, MVT::f64, Custom); | 342 setOperationAction(ISD::BR_CC, MVT::f64, Custom); |
333 setOperationAction(ISD::BR_JT, MVT::Other, | 343 setOperationAction(ISD::BR_JT, MVT::Other, |
334 Subtarget->useInlineJumpTables() ? Custom : Expand); | 344 Subtarget->useInlineJumpTables() ? Custom : Expand); |
335 | 345 |
336 // We don't support sin/cos/fmod/copysign/pow | 346 // We don't support sin/cos/fmod/copysign/pow |
337 setOperationAction(ISD::FSIN, MVT::f64, Expand); | 347 setOperationAction(ISD::FSIN, MVT::f64, Expand); |
338 setOperationAction(ISD::FSIN, MVT::f32, Expand); | 348 setOperationAction(ISD::FSIN, MVT::f32, Expand); |
339 setOperationAction(ISD::FCOS, MVT::f32, Expand); | 349 setOperationAction(ISD::FCOS, MVT::f32, Expand); |
340 setOperationAction(ISD::FCOS, MVT::f64, Expand); | 350 setOperationAction(ISD::FCOS, MVT::f64, Expand); |
341 setOperationAction(ISD::FREM, MVT::f64, Expand); | 351 setOperationAction(ISD::FREM, MVT::f64, Expand); |
342 setOperationAction(ISD::FREM, MVT::f32, Expand); | 352 setOperationAction(ISD::FREM, MVT::f32, Expand); |
343 if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb()) { | 353 if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) { |
344 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); | 354 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); |
345 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); | 355 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); |
346 } | 356 } |
347 setOperationAction(ISD::FPOW, MVT::f64, Expand); | 357 setOperationAction(ISD::FPOW, MVT::f64, Expand); |
348 setOperationAction(ISD::FPOW, MVT::f32, Expand); | 358 setOperationAction(ISD::FPOW, MVT::f32, Expand); |
349 | 359 |
350 // int <-> fp are custom expanded into bit_convert + ARMISD ops. | 360 // int <-> fp are custom expanded into bit_convert + ARMISD ops. |
351 if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb()) { | 361 if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) { |
352 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); | 362 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); |
353 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom); | 363 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom); |
354 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); | 364 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); |
355 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); | 365 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); |
356 } | 366 } |
357 | 367 |
358 // We have target-specific dag combine patterns for the following nodes: | 368 // We have target-specific dag combine patterns for the following nodes: |
359 // ARMISD::FMRRD - No need to call setTargetDAGCombine | 369 // ARMISD::FMRRD - No need to call setTargetDAGCombine |
360 setTargetDAGCombine(ISD::ADD); | 370 setTargetDAGCombine(ISD::ADD); |
361 setTargetDAGCombine(ISD::SUB); | 371 setTargetDAGCombine(ISD::SUB); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
395 switch (Opcode) { | 405 switch (Opcode) { |
396 default: return 0; | 406 default: return 0; |
397 case ARMISD::Wrapper: return "ARMISD::Wrapper"; | 407 case ARMISD::Wrapper: return "ARMISD::Wrapper"; |
398 case ARMISD::WrapperJT: return "ARMISD::WrapperJT"; | 408 case ARMISD::WrapperJT: return "ARMISD::WrapperJT"; |
399 case ARMISD::CALL: return "ARMISD::CALL"; | 409 case ARMISD::CALL: return "ARMISD::CALL"; |
400 case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED"; | 410 case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED"; |
401 case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK"; | 411 case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK"; |
402 case ARMISD::tCALL: return "ARMISD::tCALL"; | 412 case ARMISD::tCALL: return "ARMISD::tCALL"; |
403 case ARMISD::BRCOND: return "ARMISD::BRCOND"; | 413 case ARMISD::BRCOND: return "ARMISD::BRCOND"; |
404 case ARMISD::BR_JT: return "ARMISD::BR_JT"; | 414 case ARMISD::BR_JT: return "ARMISD::BR_JT"; |
415 case ARMISD::BR2_JT: return "ARMISD::BR2_JT"; | |
405 case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG"; | 416 case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG"; |
406 case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD"; | 417 case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD"; |
407 case ARMISD::CMP: return "ARMISD::CMP"; | 418 case ARMISD::CMP: return "ARMISD::CMP"; |
408 case ARMISD::CMPNZ: return "ARMISD::CMPNZ"; | 419 case ARMISD::CMPZ: return "ARMISD::CMPZ"; |
409 case ARMISD::CMPFP: return "ARMISD::CMPFP"; | 420 case ARMISD::CMPFP: return "ARMISD::CMPFP"; |
410 case ARMISD::CMPFPw0: return "ARMISD::CMPFPw0"; | 421 case ARMISD::CMPFPw0: return "ARMISD::CMPFPw0"; |
411 case ARMISD::FMSTAT: return "ARMISD::FMSTAT"; | 422 case ARMISD::FMSTAT: return "ARMISD::FMSTAT"; |
412 case ARMISD::CMOV: return "ARMISD::CMOV"; | 423 case ARMISD::CMOV: return "ARMISD::CMOV"; |
413 case ARMISD::CNEG: return "ARMISD::CNEG"; | 424 case ARMISD::CNEG: return "ARMISD::CNEG"; |
414 | 425 |
415 case ARMISD::FTOSI: return "ARMISD::FTOSI"; | 426 case ARMISD::FTOSI: return "ARMISD::FTOSI"; |
416 case ARMISD::FTOUI: return "ARMISD::FTOUI"; | 427 case ARMISD::FTOUI: return "ARMISD::FTOUI"; |
417 case ARMISD::SITOF: return "ARMISD::SITOF"; | 428 case ARMISD::SITOF: return "ARMISD::SITOF"; |
418 case ARMISD::UITOF: return "ARMISD::UITOF"; | 429 case ARMISD::UITOF: return "ARMISD::UITOF"; |
(...skipping 29 matching lines...) Expand all Loading... | |
448 case ARMISD::VQSHLsu: return "ARMISD::VQSHLsu"; | 459 case ARMISD::VQSHLsu: return "ARMISD::VQSHLsu"; |
449 case ARMISD::VQSHRNs: return "ARMISD::VQSHRNs"; | 460 case ARMISD::VQSHRNs: return "ARMISD::VQSHRNs"; |
450 case ARMISD::VQSHRNu: return "ARMISD::VQSHRNu"; | 461 case ARMISD::VQSHRNu: return "ARMISD::VQSHRNu"; |
451 case ARMISD::VQSHRNsu: return "ARMISD::VQSHRNsu"; | 462 case ARMISD::VQSHRNsu: return "ARMISD::VQSHRNsu"; |
452 case ARMISD::VQRSHRNs: return "ARMISD::VQRSHRNs"; | 463 case ARMISD::VQRSHRNs: return "ARMISD::VQRSHRNs"; |
453 case ARMISD::VQRSHRNu: return "ARMISD::VQRSHRNu"; | 464 case ARMISD::VQRSHRNu: return "ARMISD::VQRSHRNu"; |
454 case ARMISD::VQRSHRNsu: return "ARMISD::VQRSHRNsu"; | 465 case ARMISD::VQRSHRNsu: return "ARMISD::VQRSHRNsu"; |
455 case ARMISD::VGETLANEu: return "ARMISD::VGETLANEu"; | 466 case ARMISD::VGETLANEu: return "ARMISD::VGETLANEu"; |
456 case ARMISD::VGETLANEs: return "ARMISD::VGETLANEs"; | 467 case ARMISD::VGETLANEs: return "ARMISD::VGETLANEs"; |
457 case ARMISD::VDUPLANEQ: return "ARMISD::VDUPLANEQ"; | 468 case ARMISD::VDUPLANEQ: return "ARMISD::VDUPLANEQ"; |
458 } | 469 case ARMISD::VLD2D: return "ARMISD::VLD2D"; |
470 case ARMISD::VLD3D: return "ARMISD::VLD3D"; | |
471 case ARMISD::VLD4D: return "ARMISD::VLD4D"; | |
472 } | |
473 } | |
474 | |
475 /// getFunctionAlignment - Return the Log2 alignment of this function. | |
476 unsigned ARMTargetLowering::getFunctionAlignment(const Function *F) const { | |
477 return getTargetMachine().getSubtarget<ARMSubtarget>().isThumb() ? 1 : 2; | |
459 } | 478 } |
460 | 479 |
461 //===----------------------------------------------------------------------===// | 480 //===----------------------------------------------------------------------===// |
462 // Lowering Code | 481 // Lowering Code |
463 //===----------------------------------------------------------------------===// | 482 //===----------------------------------------------------------------------===// |
464 | 483 |
465 /// IntCCToARMCC - Convert a DAG integer condition code to an ARM CC | 484 /// IntCCToARMCC - Convert a DAG integer condition code to an ARM CC |
466 static ARMCC::CondCodes IntCCToARMCC(ISD::CondCode CC) { | 485 static ARMCC::CondCodes IntCCToARMCC(ISD::CondCode CC) { |
467 switch (CC) { | 486 switch (CC) { |
468 default: assert(0 && "Unknown condition code!"); | 487 default: llvm_unreachable("Unknown condition code!"); |
469 case ISD::SETNE: return ARMCC::NE; | 488 case ISD::SETNE: return ARMCC::NE; |
470 case ISD::SETEQ: return ARMCC::EQ; | 489 case ISD::SETEQ: return ARMCC::EQ; |
471 case ISD::SETGT: return ARMCC::GT; | 490 case ISD::SETGT: return ARMCC::GT; |
472 case ISD::SETGE: return ARMCC::GE; | 491 case ISD::SETGE: return ARMCC::GE; |
473 case ISD::SETLT: return ARMCC::LT; | 492 case ISD::SETLT: return ARMCC::LT; |
474 case ISD::SETLE: return ARMCC::LE; | 493 case ISD::SETLE: return ARMCC::LE; |
475 case ISD::SETUGT: return ARMCC::HI; | 494 case ISD::SETUGT: return ARMCC::HI; |
476 case ISD::SETUGE: return ARMCC::HS; | 495 case ISD::SETUGE: return ARMCC::HS; |
477 case ISD::SETULT: return ARMCC::LO; | 496 case ISD::SETULT: return ARMCC::LO; |
478 case ISD::SETULE: return ARMCC::LS; | 497 case ISD::SETULE: return ARMCC::LS; |
479 } | 498 } |
480 } | 499 } |
481 | 500 |
482 /// FPCCToARMCC - Convert a DAG fp condition code to an ARM CC. It | 501 /// FPCCToARMCC - Convert a DAG fp condition code to an ARM CC. It |
483 /// returns true if the operands should be inverted to form the proper | 502 /// returns true if the operands should be inverted to form the proper |
484 /// comparison. | 503 /// comparison. |
485 static bool FPCCToARMCC(ISD::CondCode CC, ARMCC::CondCodes &CondCode, | 504 static bool FPCCToARMCC(ISD::CondCode CC, ARMCC::CondCodes &CondCode, |
486 ARMCC::CondCodes &CondCode2) { | 505 ARMCC::CondCodes &CondCode2) { |
487 bool Invert = false; | 506 bool Invert = false; |
488 CondCode2 = ARMCC::AL; | 507 CondCode2 = ARMCC::AL; |
489 switch (CC) { | 508 switch (CC) { |
490 default: assert(0 && "Unknown FP condition!"); | 509 default: llvm_unreachable("Unknown FP condition!"); |
491 case ISD::SETEQ: | 510 case ISD::SETEQ: |
492 case ISD::SETOEQ: CondCode = ARMCC::EQ; break; | 511 case ISD::SETOEQ: CondCode = ARMCC::EQ; break; |
493 case ISD::SETGT: | 512 case ISD::SETGT: |
494 case ISD::SETOGT: CondCode = ARMCC::GT; break; | 513 case ISD::SETOGT: CondCode = ARMCC::GT; break; |
495 case ISD::SETGE: | 514 case ISD::SETGE: |
496 case ISD::SETOGE: CondCode = ARMCC::GE; break; | 515 case ISD::SETOGE: CondCode = ARMCC::GE; break; |
497 case ISD::SETOLT: CondCode = ARMCC::MI; break; | 516 case ISD::SETOLT: CondCode = ARMCC::MI; break; |
498 case ISD::SETOLE: CondCode = ARMCC::GT; Invert = true; break; | 517 case ISD::SETOLE: CondCode = ARMCC::GT; Invert = true; break; |
499 case ISD::SETONE: CondCode = ARMCC::MI; CondCode2 = ARMCC::GT; break; | 518 case ISD::SETONE: CondCode = ARMCC::MI; CondCode2 = ARMCC::GT; break; |
500 case ISD::SETO: CondCode = ARMCC::VC; break; | 519 case ISD::SETO: CondCode = ARMCC::VC; break; |
501 case ISD::SETUO: CondCode = ARMCC::VS; break; | 520 case ISD::SETUO: CondCode = ARMCC::VS; break; |
502 case ISD::SETUEQ: CondCode = ARMCC::EQ; CondCode2 = ARMCC::VS; break; | 521 case ISD::SETUEQ: CondCode = ARMCC::EQ; CondCode2 = ARMCC::VS; break; |
503 case ISD::SETUGT: CondCode = ARMCC::HI; break; | 522 case ISD::SETUGT: CondCode = ARMCC::HI; break; |
504 case ISD::SETUGE: CondCode = ARMCC::PL; break; | 523 case ISD::SETUGE: CondCode = ARMCC::PL; break; |
505 case ISD::SETLT: | 524 case ISD::SETLT: |
506 case ISD::SETULT: CondCode = ARMCC::LT; break; | 525 case ISD::SETULT: CondCode = ARMCC::LT; break; |
507 case ISD::SETLE: | 526 case ISD::SETLE: |
508 case ISD::SETULE: CondCode = ARMCC::LE; break; | 527 case ISD::SETULE: CondCode = ARMCC::LE; break; |
509 case ISD::SETNE: | 528 case ISD::SETNE: |
510 case ISD::SETUNE: CondCode = ARMCC::NE; break; | 529 case ISD::SETUNE: CondCode = ARMCC::NE; break; |
511 } | 530 } |
512 return Invert; | 531 return Invert; |
513 } | 532 } |
514 | 533 |
515 //===----------------------------------------------------------------------===// | 534 //===----------------------------------------------------------------------===// |
516 // Calling Convention Implementation | 535 // Calling Convention Implementation |
517 // | |
518 // The lower operations present on calling convention works on this order: | |
519 // LowerCALL (virt regs --> phys regs, virt regs --> stack) | |
520 // LowerFORMAL_ARGUMENTS (phys --> virt regs, stack --> virt regs) | |
521 // LowerRET (virt regs --> phys regs) | |
522 // LowerCALL (phys regs --> virt regs) | |
523 // | |
524 //===----------------------------------------------------------------------===// | 536 //===----------------------------------------------------------------------===// |
525 | 537 |
526 #include "ARMGenCallingConv.inc" | 538 #include "ARMGenCallingConv.inc" |
527 | 539 |
528 // APCS f64 is in register pairs, possibly split to stack | 540 // APCS f64 is in register pairs, possibly split to stack |
529 static bool f64AssignAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT, | 541 static bool f64AssignAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT, |
530 CCValAssign::LocInfo &LocInfo, | 542 CCValAssign::LocInfo &LocInfo, |
531 CCState &State, bool CanFail) { | 543 CCState &State, bool CanFail) { |
532 static const unsigned RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 }; | 544 static const unsigned RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 }; |
533 | 545 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
649 return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags, | 661 return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags, |
650 State); | 662 State); |
651 } | 663 } |
652 | 664 |
653 /// CCAssignFnForNode - Selects the correct CCAssignFn for a the | 665 /// CCAssignFnForNode - Selects the correct CCAssignFn for a the |
654 /// given CallingConvention value. | 666 /// given CallingConvention value. |
655 CCAssignFn *ARMTargetLowering::CCAssignFnForNode(unsigned CC, | 667 CCAssignFn *ARMTargetLowering::CCAssignFnForNode(unsigned CC, |
656 bool Return) const { | 668 bool Return) const { |
657 switch (CC) { | 669 switch (CC) { |
658 default: | 670 default: |
659 assert(0 && "Unsupported calling convention"); | 671 llvm_unreachable("Unsupported calling convention"); |
660 case CallingConv::C: | 672 case CallingConv::C: |
661 case CallingConv::Fast: | 673 case CallingConv::Fast: |
662 // Use target triple & subtarget features to do actual dispatch. | 674 // Use target triple & subtarget features to do actual dispatch. |
663 if (Subtarget->isAAPCS_ABI()) { | 675 if (Subtarget->isAAPCS_ABI()) { |
664 if (Subtarget->hasVFP2() && | 676 if (Subtarget->hasVFP2() && |
665 FloatABIType == FloatABI::Hard) | 677 FloatABIType == FloatABI::Hard) |
666 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); | 678 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); |
667 else | 679 else |
668 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); | 680 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); |
669 } else | 681 } else |
670 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); | 682 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); |
671 case CallingConv::ARM_AAPCS_VFP: | 683 case CallingConv::ARM_AAPCS_VFP: |
672 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); | 684 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); |
673 case CallingConv::ARM_AAPCS: | 685 case CallingConv::ARM_AAPCS: |
674 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); | 686 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); |
675 case CallingConv::ARM_APCS: | 687 case CallingConv::ARM_APCS: |
676 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); | 688 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); |
677 } | 689 } |
678 } | 690 } |
679 | 691 |
680 /// LowerCallResult - Lower the result values of an ISD::CALL into the | 692 /// LowerCallResult - Lower the result values of a call into the |
681 /// appropriate copies out of appropriate physical registers. This assumes that | 693 /// appropriate copies out of appropriate physical registers. |
682 /// Chain/InFlag are the input chain/flag to use, and that TheCall is the call | 694 SDValue |
683 /// being lowered. The returns a SDNode with the same number of values as the | 695 ARMTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, |
684 /// ISD::CALL. | 696 unsigned CallConv, bool isVarArg, |
685 SDNode *ARMTargetLowering:: | 697 const SmallVectorImpl<ISD::InputArg> &Ins, |
686 LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, | 698 DebugLoc dl, SelectionDAG &DAG, |
687 unsigned CallingConv, SelectionDAG &DAG) { | 699 SmallVectorImpl<SDValue> &InVals) { |
688 | 700 |
689 DebugLoc dl = TheCall->getDebugLoc(); | |
690 // Assign locations to each value returned by this call. | 701 // Assign locations to each value returned by this call. |
691 SmallVector<CCValAssign, 16> RVLocs; | 702 SmallVector<CCValAssign, 16> RVLocs; |
692 bool isVarArg = TheCall->isVarArg(); | 703 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), |
693 CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs); | 704 RVLocs, *DAG.getContext()); |
694 CCInfo.AnalyzeCallResult(TheCall, | 705 CCInfo.AnalyzeCallResult(Ins, |
695 CCAssignFnForNode(CallingConv, /* Return*/ true)); | 706 CCAssignFnForNode(CallConv, /* Return*/ true)); |
696 | |
697 SmallVector<SDValue, 8> ResultVals; | |
698 | 707 |
699 // Copy all of the result registers out of their specified physreg. | 708 // Copy all of the result registers out of their specified physreg. |
700 for (unsigned i = 0; i != RVLocs.size(); ++i) { | 709 for (unsigned i = 0; i != RVLocs.size(); ++i) { |
701 CCValAssign VA = RVLocs[i]; | 710 CCValAssign VA = RVLocs[i]; |
702 | 711 |
703 SDValue Val; | 712 SDValue Val; |
704 if (VA.needsCustom()) { | 713 if (VA.needsCustom()) { |
705 // Handle f64 or half of a v2f64. | 714 // Handle f64 or half of a v2f64. |
706 SDValue Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, | 715 SDValue Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, |
707 InFlag); | 716 InFlag); |
(...skipping 24 matching lines...) Expand all Loading... | |
732 DAG.getConstant(1, MVT::i32)); | 741 DAG.getConstant(1, MVT::i32)); |
733 } | 742 } |
734 } else { | 743 } else { |
735 Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(), | 744 Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(), |
736 InFlag); | 745 InFlag); |
737 Chain = Val.getValue(1); | 746 Chain = Val.getValue(1); |
738 InFlag = Val.getValue(2); | 747 InFlag = Val.getValue(2); |
739 } | 748 } |
740 | 749 |
741 switch (VA.getLocInfo()) { | 750 switch (VA.getLocInfo()) { |
742 default: assert(0 && "Unknown loc info!"); | 751 default: llvm_unreachable("Unknown loc info!"); |
743 case CCValAssign::Full: break; | 752 case CCValAssign::Full: break; |
744 case CCValAssign::BCvt: | 753 case CCValAssign::BCvt: |
745 Val = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getValVT(), Val); | 754 Val = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getValVT(), Val); |
746 break; | 755 break; |
747 } | 756 } |
748 | 757 |
749 ResultVals.push_back(Val); | 758 InVals.push_back(Val); |
750 } | 759 } |
751 | 760 |
752 // Merge everything together with a MERGE_VALUES node. | 761 return Chain; |
753 ResultVals.push_back(Chain); | |
754 return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), | |
755 &ResultVals[0], ResultVals.size()).getNode(); | |
756 } | 762 } |
757 | 763 |
758 /// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified | 764 /// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified |
759 /// by "Src" to address "Dst" of size "Size". Alignment information is | 765 /// by "Src" to address "Dst" of size "Size". Alignment information is |
760 /// specified by the specific parameter attribute. The copy will be passed as | 766 /// specified by the specific parameter attribute. The copy will be passed as |
761 /// a byval function parameter. | 767 /// a byval function parameter. |
762 /// Sometimes what we are copying is the end of a larger object, the part that | 768 /// Sometimes what we are copying is the end of a larger object, the part that |
763 /// does not fit in registers. | 769 /// does not fit in registers. |
764 static SDValue | 770 static SDValue |
765 CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, | 771 CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, |
766 ISD::ArgFlagsTy Flags, SelectionDAG &DAG, | 772 ISD::ArgFlagsTy Flags, SelectionDAG &DAG, |
767 DebugLoc dl) { | 773 DebugLoc dl) { |
768 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32); | 774 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32); |
769 return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(), | 775 return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(), |
770 /*AlwaysInline=*/false, NULL, 0, NULL, 0); | 776 /*AlwaysInline=*/false, NULL, 0, NULL, 0); |
771 } | 777 } |
772 | 778 |
773 /// LowerMemOpCallTo - Store the argument to the stack. | 779 /// LowerMemOpCallTo - Store the argument to the stack. |
774 SDValue | 780 SDValue |
775 ARMTargetLowering::LowerMemOpCallTo(CallSDNode *TheCall, SelectionDAG &DAG, | 781 ARMTargetLowering::LowerMemOpCallTo(SDValue Chain, |
776 const SDValue &StackPtr, | 782 SDValue StackPtr, SDValue Arg, |
777 const CCValAssign &VA, SDValue Chain, | 783 DebugLoc dl, SelectionDAG &DAG, |
778 SDValue Arg, ISD::ArgFlagsTy Flags) { | 784 const CCValAssign &VA, |
779 DebugLoc dl = TheCall->getDebugLoc(); | 785 ISD::ArgFlagsTy Flags) { |
780 unsigned LocMemOffset = VA.getLocMemOffset(); | 786 unsigned LocMemOffset = VA.getLocMemOffset(); |
781 SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset); | 787 SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset); |
782 PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, PtrOff); | 788 PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, PtrOff); |
783 if (Flags.isByVal()) { | 789 if (Flags.isByVal()) { |
784 return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, dl); | 790 return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, dl); |
785 } | 791 } |
786 return DAG.getStore(Chain, dl, Arg, PtrOff, | 792 return DAG.getStore(Chain, dl, Arg, PtrOff, |
787 PseudoSourceValue::getStack(), LocMemOffset); | 793 PseudoSourceValue::getStack(), LocMemOffset); |
788 } | 794 } |
789 | 795 |
790 void ARMTargetLowering::PassF64ArgInRegs(CallSDNode *TheCall, SelectionDAG &DAG, | 796 void ARMTargetLowering::PassF64ArgInRegs(DebugLoc dl, SelectionDAG &DAG, |
791 SDValue Chain, SDValue &Arg, | 797 SDValue Chain, SDValue &Arg, |
792 RegsToPassVector &RegsToPass, | 798 RegsToPassVector &RegsToPass, |
793 CCValAssign &VA, CCValAssign &NextVA, | 799 CCValAssign &VA, CCValAssign &NextVA, |
794 SDValue &StackPtr, | 800 SDValue &StackPtr, |
795 SmallVector<SDValue, 8> &MemOpChains, | 801 SmallVector<SDValue, 8> &MemOpChains, |
796 ISD::ArgFlagsTy Flags) { | 802 ISD::ArgFlagsTy Flags) { |
797 DebugLoc dl = TheCall->getDebugLoc(); | |
798 | 803 |
799 SDValue fmrrd = DAG.getNode(ARMISD::FMRRD, dl, | 804 SDValue fmrrd = DAG.getNode(ARMISD::FMRRD, dl, |
800 DAG.getVTList(MVT::i32, MVT::i32), Arg); | 805 DAG.getVTList(MVT::i32, MVT::i32), Arg); |
801 RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd)); | 806 RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd)); |
802 | 807 |
803 if (NextVA.isRegLoc()) | 808 if (NextVA.isRegLoc()) |
804 RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1))); | 809 RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1))); |
805 else { | 810 else { |
806 assert(NextVA.isMemLoc()); | 811 assert(NextVA.isMemLoc()); |
807 if (StackPtr.getNode() == 0) | 812 if (StackPtr.getNode() == 0) |
808 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); | 813 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); |
809 | 814 |
810 MemOpChains.push_back(LowerMemOpCallTo(TheCall, DAG, StackPtr, NextVA, | 815 MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, fmrrd.getValue(1), |
811 Chain, fmrrd.getValue(1), Flags)); | 816 dl, DAG, NextVA, |
812 } | 817 Flags)); |
813 } | 818 } |
814 | 819 } |
815 /// LowerCALL - Lowering a ISD::CALL node into a callseq_start <- | 820 |
821 /// LowerCall - Lowering a call into a callseq_start <- | |
816 /// ARMISD:CALL <- callseq_end chain. Also add input and output parameter | 822 /// ARMISD:CALL <- callseq_end chain. Also add input and output parameter |
817 /// nodes. | 823 /// nodes. |
818 SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { | 824 SDValue |
819 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); | 825 ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, |
820 MVT RetVT = TheCall->getRetValType(0); | 826 unsigned CallConv, bool isVarArg, |
821 SDValue Chain = TheCall->getChain(); | 827 bool isTailCall, |
822 unsigned CC = TheCall->getCallingConv(); | 828 const SmallVectorImpl<ISD::OutputArg> &Outs, |
823 bool isVarArg = TheCall->isVarArg(); | 829 const SmallVectorImpl<ISD::InputArg> &Ins, |
824 SDValue Callee = TheCall->getCallee(); | 830 DebugLoc dl, SelectionDAG &DAG, |
825 DebugLoc dl = TheCall->getDebugLoc(); | 831 SmallVectorImpl<SDValue> &InVals) { |
826 | 832 |
827 // Analyze operands of the call, assigning locations to each operand. | 833 // Analyze operands of the call, assigning locations to each operand. |
828 SmallVector<CCValAssign, 16> ArgLocs; | 834 SmallVector<CCValAssign, 16> ArgLocs; |
829 CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); | 835 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, |
830 CCInfo.AnalyzeCallOperands(TheCall, CCAssignFnForNode(CC, /* Return*/ false)); | 836 *DAG.getContext()); |
837 CCInfo.AnalyzeCallOperands(Outs, | |
838 CCAssignFnForNode(CallConv, /* Return*/ false)); | |
831 | 839 |
832 // Get a count of how many bytes are to be pushed on the stack. | 840 // Get a count of how many bytes are to be pushed on the stack. |
833 unsigned NumBytes = CCInfo.getNextStackOffset(); | 841 unsigned NumBytes = CCInfo.getNextStackOffset(); |
834 | 842 |
835 // Adjust the stack pointer for the new arguments... | 843 // Adjust the stack pointer for the new arguments... |
836 // These operations are automatically eliminated by the prolog/epilog pass | 844 // These operations are automatically eliminated by the prolog/epilog pass |
837 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true)); | 845 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true)); |
838 | 846 |
839 SDValue StackPtr = DAG.getRegister(ARM::SP, MVT::i32); | 847 SDValue StackPtr = DAG.getRegister(ARM::SP, MVT::i32); |
840 | 848 |
841 RegsToPassVector RegsToPass; | 849 RegsToPassVector RegsToPass; |
842 SmallVector<SDValue, 8> MemOpChains; | 850 SmallVector<SDValue, 8> MemOpChains; |
843 | 851 |
844 // Walk the register/memloc assignments, inserting copies/loads. In the case | 852 // Walk the register/memloc assignments, inserting copies/loads. In the case |
845 // of tail call optimization, arguments are handled later. | 853 // of tail call optimization, arguments are handled later. |
846 for (unsigned i = 0, realArgIdx = 0, e = ArgLocs.size(); | 854 for (unsigned i = 0, realArgIdx = 0, e = ArgLocs.size(); |
847 i != e; | 855 i != e; |
848 ++i, ++realArgIdx) { | 856 ++i, ++realArgIdx) { |
849 CCValAssign &VA = ArgLocs[i]; | 857 CCValAssign &VA = ArgLocs[i]; |
850 SDValue Arg = TheCall->getArg(realArgIdx); | 858 SDValue Arg = Outs[realArgIdx].Val; |
851 ISD::ArgFlagsTy Flags = TheCall->getArgFlags(realArgIdx); | 859 ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags; |
852 | 860 |
853 // Promote the value if needed. | 861 // Promote the value if needed. |
854 switch (VA.getLocInfo()) { | 862 switch (VA.getLocInfo()) { |
855 default: assert(0 && "Unknown loc info!"); | 863 default: llvm_unreachable("Unknown loc info!"); |
856 case CCValAssign::Full: break; | 864 case CCValAssign::Full: break; |
857 case CCValAssign::SExt: | 865 case CCValAssign::SExt: |
858 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); | 866 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); |
859 break; | 867 break; |
860 case CCValAssign::ZExt: | 868 case CCValAssign::ZExt: |
861 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); | 869 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); |
862 break; | 870 break; |
863 case CCValAssign::AExt: | 871 case CCValAssign::AExt: |
864 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); | 872 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); |
865 break; | 873 break; |
866 case CCValAssign::BCvt: | 874 case CCValAssign::BCvt: |
867 Arg = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getLocVT(), Arg); | 875 Arg = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getLocVT(), Arg); |
868 break; | 876 break; |
869 } | 877 } |
870 | 878 |
871 // f64 and v2f64 are passed in i32 pairs and must be split into pieces | 879 // f64 and v2f64 are passed in i32 pairs and must be split into pieces |
872 if (VA.needsCustom()) { | 880 if (VA.needsCustom()) { |
873 if (VA.getLocVT() == MVT::v2f64) { | 881 if (VA.getLocVT() == MVT::v2f64) { |
874 SDValue Op0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, | 882 SDValue Op0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, |
875 DAG.getConstant(0, MVT::i32)); | 883 DAG.getConstant(0, MVT::i32)); |
876 SDValue Op1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, | 884 SDValue Op1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, |
877 DAG.getConstant(1, MVT::i32)); | 885 DAG.getConstant(1, MVT::i32)); |
878 | 886 |
879 PassF64ArgInRegs(TheCall, DAG, Chain, Op0, RegsToPass, | 887 PassF64ArgInRegs(dl, DAG, Chain, Op0, RegsToPass, |
880 VA, ArgLocs[++i], StackPtr, MemOpChains, Flags); | 888 VA, ArgLocs[++i], StackPtr, MemOpChains, Flags); |
881 | 889 |
882 VA = ArgLocs[++i]; // skip ahead to next loc | 890 VA = ArgLocs[++i]; // skip ahead to next loc |
883 if (VA.isRegLoc()) { | 891 if (VA.isRegLoc()) { |
884 PassF64ArgInRegs(TheCall, DAG, Chain, Op1, RegsToPass, | 892 PassF64ArgInRegs(dl, DAG, Chain, Op1, RegsToPass, |
885 VA, ArgLocs[++i], StackPtr, MemOpChains, Flags); | 893 VA, ArgLocs[++i], StackPtr, MemOpChains, Flags); |
886 } else { | 894 } else { |
887 assert(VA.isMemLoc()); | 895 assert(VA.isMemLoc()); |
888 if (StackPtr.getNode() == 0) | 896 if (StackPtr.getNode() == 0) |
889 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); | 897 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); |
890 | 898 |
891 MemOpChains.push_back(LowerMemOpCallTo(TheCall, DAG, StackPtr, VA, | 899 MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Op1, |
892 Chain, Op1, Flags)); | 900 dl, DAG, VA, Flags)); |
893 } | 901 } |
894 } else { | 902 } else { |
895 PassF64ArgInRegs(TheCall, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i], | 903 PassF64ArgInRegs(dl, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i], |
896 StackPtr, MemOpChains, Flags); | 904 StackPtr, MemOpChains, Flags); |
897 } | 905 } |
898 } else if (VA.isRegLoc()) { | 906 } else if (VA.isRegLoc()) { |
899 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); | 907 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); |
900 } else { | 908 } else { |
901 assert(VA.isMemLoc()); | 909 assert(VA.isMemLoc()); |
902 if (StackPtr.getNode() == 0) | 910 if (StackPtr.getNode() == 0) |
903 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); | 911 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); |
904 | 912 |
905 MemOpChains.push_back(LowerMemOpCallTo(TheCall, DAG, StackPtr, VA, | 913 MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg, |
906 Chain, Arg, Flags)); | 914 dl, DAG, VA, Flags)); |
907 } | 915 } |
908 } | 916 } |
909 | 917 |
910 if (!MemOpChains.empty()) | 918 if (!MemOpChains.empty()) |
911 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, | 919 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, |
912 &MemOpChains[0], MemOpChains.size()); | 920 &MemOpChains[0], MemOpChains.size()); |
913 | 921 |
914 // Build a sequence of copy-to-reg nodes chained together with token chain | 922 // Build a sequence of copy-to-reg nodes chained together with token chain |
915 // and flag operands which copy the outgoing args into the appropriate regs. | 923 // and flag operands which copy the outgoing args into the appropriate regs. |
916 SDValue InFlag; | 924 SDValue InFlag; |
917 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { | 925 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { |
918 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, | 926 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, |
919 RegsToPass[i].second, InFlag); | 927 RegsToPass[i].second, InFlag); |
920 InFlag = Chain.getValue(1); | 928 InFlag = Chain.getValue(1); |
921 } | 929 } |
922 | 930 |
923 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every | 931 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every |
924 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol | 932 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol |
925 // node so that legalize doesn't hack it. | 933 // node so that legalize doesn't hack it. |
926 bool isDirect = false; | 934 bool isDirect = false; |
927 bool isARMFunc = false; | 935 bool isARMFunc = false; |
928 bool isLocalARMFunc = false; | 936 bool isLocalARMFunc = false; |
929 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { | 937 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { |
930 GlobalValue *GV = G->getGlobal(); | 938 GlobalValue *GV = G->getGlobal(); |
931 isDirect = true; | 939 isDirect = true; |
932 bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() || | 940 bool isExt = GV->isDeclaration() || GV->isWeakForLinker(); |
933 GV->hasLinkOnceLinkage()); | |
934 bool isStub = (isExt && Subtarget->isTargetDarwin()) && | 941 bool isStub = (isExt && Subtarget->isTargetDarwin()) && |
935 getTargetMachine().getRelocationModel() != Reloc::Static; | 942 getTargetMachine().getRelocationModel() != Reloc::Static; |
936 isARMFunc = !Subtarget->isThumb() || isStub; | 943 isARMFunc = !Subtarget->isThumb() || isStub; |
937 // ARM call to a local ARM function is predicable. | 944 // ARM call to a local ARM function is predicable. |
938 isLocalARMFunc = !Subtarget->isThumb() && !isExt; | 945 isLocalARMFunc = !Subtarget->isThumb() && !isExt; |
939 // tBX takes a register source operand. | 946 // tBX takes a register source operand. |
940 if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps()) { | 947 if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) { |
941 ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex, | 948 ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex, |
942 ARMCP::CPStub, 4); | 949 ARMCP::CPStub, 4); |
943 SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); | 950 SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); |
944 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); | 951 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); |
945 Callee = DAG.getLoad(getPointerTy(), dl, | 952 Callee = DAG.getLoad(getPointerTy(), dl, |
946 DAG.getEntryNode(), CPAddr, NULL, 0); | 953 DAG.getEntryNode(), CPAddr, NULL, 0); |
947 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); | 954 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); |
948 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, | 955 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, |
949 getPointerTy(), Callee, PICLabel); | 956 getPointerTy(), Callee, PICLabel); |
950 } else | 957 } else |
951 Callee = DAG.getTargetGlobalAddress(GV, getPointerTy()); | 958 Callee = DAG.getTargetGlobalAddress(GV, getPointerTy()); |
952 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { | 959 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { |
953 isDirect = true; | 960 isDirect = true; |
954 bool isStub = Subtarget->isTargetDarwin() && | 961 bool isStub = Subtarget->isTargetDarwin() && |
955 getTargetMachine().getRelocationModel() != Reloc::Static; | 962 getTargetMachine().getRelocationModel() != Reloc::Static; |
956 isARMFunc = !Subtarget->isThumb() || isStub; | 963 isARMFunc = !Subtarget->isThumb() || isStub; |
957 // tBX takes a register source operand. | 964 // tBX takes a register source operand. |
958 const char *Sym = S->getSymbol(); | 965 const char *Sym = S->getSymbol(); |
959 if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps()) { | 966 if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) { |
960 ARMConstantPoolValue *CPV = new ARMConstantPoolValue(Sym, ARMPCLabelIndex, | 967 ARMConstantPoolValue *CPV = new ARMConstantPoolValue(Sym, ARMPCLabelIndex, |
961 ARMCP::CPStub, 4); | 968 ARMCP::CPStub, 4); |
962 SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); | 969 SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); |
963 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); | 970 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); |
964 Callee = DAG.getLoad(getPointerTy(), dl, | 971 Callee = DAG.getLoad(getPointerTy(), dl, |
965 DAG.getEntryNode(), CPAddr, NULL, 0); | 972 DAG.getEntryNode(), CPAddr, NULL, 0); |
966 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); | 973 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); |
967 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, | 974 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, |
968 getPointerTy(), Callee, PICLabel); | 975 getPointerTy(), Callee, PICLabel); |
969 } else | 976 } else |
970 Callee = DAG.getTargetExternalSymbol(Sym, getPointerTy()); | 977 Callee = DAG.getTargetExternalSymbol(Sym, getPointerTy()); |
971 } | 978 } |
972 | 979 |
973 // FIXME: handle tail calls differently. | 980 // FIXME: handle tail calls differently. |
974 unsigned CallOpc; | 981 unsigned CallOpc; |
975 if (Subtarget->isThumb()) { | 982 if (Subtarget->isThumb()) { |
976 if (!Subtarget->hasV5TOps() && (!isDirect || isARMFunc)) | 983 if ((!isDirect || isARMFunc) && !Subtarget->hasV5TOps()) |
977 CallOpc = ARMISD::CALL_NOLINK; | 984 CallOpc = ARMISD::CALL_NOLINK; |
978 else | 985 else |
979 CallOpc = isARMFunc ? ARMISD::CALL : ARMISD::tCALL; | 986 CallOpc = isARMFunc ? ARMISD::CALL : ARMISD::tCALL; |
980 } else { | 987 } else { |
981 CallOpc = (isDirect || Subtarget->hasV5TOps()) | 988 CallOpc = (isDirect || Subtarget->hasV5TOps()) |
982 ? (isLocalARMFunc ? ARMISD::CALL_PRED : ARMISD::CALL) | 989 ? (isLocalARMFunc ? ARMISD::CALL_PRED : ARMISD::CALL) |
983 : ARMISD::CALL_NOLINK; | 990 : ARMISD::CALL_NOLINK; |
984 } | 991 } |
985 if (CallOpc == ARMISD::CALL_NOLINK && !Subtarget->isThumb()) { | 992 if (CallOpc == ARMISD::CALL_NOLINK && !Subtarget->isThumb1Only()) { |
986 // implicit def LR - LR mustn't be allocated as GRP:$dst of CALL_NOLINK | 993 // implicit def LR - LR mustn't be allocated as GRP:$dst of CALL_NOLINK |
987 Chain = DAG.getCopyToReg(Chain, dl, ARM::LR, DAG.getUNDEF(MVT::i32),InFlag); | 994 Chain = DAG.getCopyToReg(Chain, dl, ARM::LR, DAG.getUNDEF(MVT::i32),InFlag); |
988 InFlag = Chain.getValue(1); | 995 InFlag = Chain.getValue(1); |
989 } | 996 } |
990 | 997 |
991 std::vector<SDValue> Ops; | 998 std::vector<SDValue> Ops; |
992 Ops.push_back(Chain); | 999 Ops.push_back(Chain); |
993 Ops.push_back(Callee); | 1000 Ops.push_back(Callee); |
994 | 1001 |
995 // Add argument registers to the end of the list so that they are known live | 1002 // Add argument registers to the end of the list so that they are known live |
996 // into the call. | 1003 // into the call. |
997 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) | 1004 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) |
998 Ops.push_back(DAG.getRegister(RegsToPass[i].first, | 1005 Ops.push_back(DAG.getRegister(RegsToPass[i].first, |
999 RegsToPass[i].second.getValueType())); | 1006 RegsToPass[i].second.getValueType())); |
1000 | 1007 |
1001 if (InFlag.getNode()) | 1008 if (InFlag.getNode()) |
1002 Ops.push_back(InFlag); | 1009 Ops.push_back(InFlag); |
1003 // Returns a chain and a flag for retval copy to use. | 1010 // Returns a chain and a flag for retval copy to use. |
1004 Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Flag), | 1011 Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Flag), |
1005 &Ops[0], Ops.size()); | 1012 &Ops[0], Ops.size()); |
1006 InFlag = Chain.getValue(1); | 1013 InFlag = Chain.getValue(1); |
1007 | 1014 |
1008 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), | 1015 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), |
1009 DAG.getIntPtrConstant(0, true), InFlag); | 1016 DAG.getIntPtrConstant(0, true), InFlag); |
1010 if (RetVT != MVT::Other) | 1017 if (!Ins.empty()) |
1011 InFlag = Chain.getValue(1); | 1018 InFlag = Chain.getValue(1); |
1012 | 1019 |
1013 // Handle result values, copying them out of physregs into vregs that we | 1020 // Handle result values, copying them out of physregs into vregs that we |
1014 // return. | 1021 // return. |
1015 return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), | 1022 return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, |
1016 Op.getResNo()); | 1023 dl, DAG, InVals); |
1017 } | 1024 } |
1018 | 1025 |
1019 SDValue ARMTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { | 1026 SDValue |
1020 // The chain is always operand #0 | 1027 ARMTargetLowering::LowerReturn(SDValue Chain, |
1021 SDValue Chain = Op.getOperand(0); | 1028 unsigned CallConv, bool isVarArg, |
1022 DebugLoc dl = Op.getDebugLoc(); | 1029 const SmallVectorImpl<ISD::OutputArg> &Outs, |
1030 DebugLoc dl, SelectionDAG &DAG) { | |
1023 | 1031 |
1024 // CCValAssign - represent the assignment of the return value to a location. | 1032 // CCValAssign - represent the assignment of the return value to a location. |
1025 SmallVector<CCValAssign, 16> RVLocs; | 1033 SmallVector<CCValAssign, 16> RVLocs; |
1026 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); | |
1027 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); | |
1028 | 1034 |
1029 // CCState - Info about the registers and stack slots. | 1035 // CCState - Info about the registers and stack slots. |
1030 CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs); | 1036 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, |
1031 | 1037 *DAG.getContext()); |
1032 // Analyze return values of ISD::RET. | 1038 |
1033 CCInfo.AnalyzeReturn(Op.getNode(), CCAssignFnForNode(CC, /* Return */ true)); | 1039 // Analyze outgoing return values. |
1040 CCInfo.AnalyzeReturn(Outs, CCAssignFnForNode(CallConv, /* Return */ true)); | |
1034 | 1041 |
1035 // If this is the first return lowered for this function, add | 1042 // If this is the first return lowered for this function, add |
1036 // the regs to the liveout set for the function. | 1043 // the regs to the liveout set for the function. |
1037 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { | 1044 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { |
1038 for (unsigned i = 0; i != RVLocs.size(); ++i) | 1045 for (unsigned i = 0; i != RVLocs.size(); ++i) |
1039 if (RVLocs[i].isRegLoc()) | 1046 if (RVLocs[i].isRegLoc()) |
1040 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); | 1047 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); |
1041 } | 1048 } |
1042 | 1049 |
1043 SDValue Flag; | 1050 SDValue Flag; |
1044 | 1051 |
1045 // Copy the result values into the output registers. | 1052 // Copy the result values into the output registers. |
1046 for (unsigned i = 0, realRVLocIdx = 0; | 1053 for (unsigned i = 0, realRVLocIdx = 0; |
1047 i != RVLocs.size(); | 1054 i != RVLocs.size(); |
1048 ++i, ++realRVLocIdx) { | 1055 ++i, ++realRVLocIdx) { |
1049 CCValAssign &VA = RVLocs[i]; | 1056 CCValAssign &VA = RVLocs[i]; |
1050 assert(VA.isRegLoc() && "Can only return in registers!"); | 1057 assert(VA.isRegLoc() && "Can only return in registers!"); |
1051 | 1058 |
1052 // ISD::RET => ret chain, (regnum1,val1), ... | 1059 SDValue Arg = Outs[realRVLocIdx].Val; |
1053 // So i*2+1 index only the regnums | |
1054 SDValue Arg = Op.getOperand(realRVLocIdx*2+1); | |
1055 | 1060 |
1056 switch (VA.getLocInfo()) { | 1061 switch (VA.getLocInfo()) { |
1057 default: assert(0 && "Unknown loc info!"); | 1062 default: llvm_unreachable("Unknown loc info!"); |
1058 case CCValAssign::Full: break; | 1063 case CCValAssign::Full: break; |
1059 case CCValAssign::BCvt: | 1064 case CCValAssign::BCvt: |
1060 Arg = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getLocVT(), Arg); | 1065 Arg = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getLocVT(), Arg); |
1061 break; | 1066 break; |
1062 } | 1067 } |
1063 | 1068 |
1064 if (VA.needsCustom()) { | 1069 if (VA.needsCustom()) { |
1065 if (VA.getLocVT() == MVT::v2f64) { | 1070 if (VA.getLocVT() == MVT::v2f64) { |
1066 // Extract the first half and return it in two registers. | 1071 // Extract the first half and return it in two registers. |
1067 SDValue Half = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, | 1072 SDValue Half = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1101 SDValue result; | 1106 SDValue result; |
1102 if (Flag.getNode()) | 1107 if (Flag.getNode()) |
1103 result = DAG.getNode(ARMISD::RET_FLAG, dl, MVT::Other, Chain, Flag); | 1108 result = DAG.getNode(ARMISD::RET_FLAG, dl, MVT::Other, Chain, Flag); |
1104 else // Return Void | 1109 else // Return Void |
1105 result = DAG.getNode(ARMISD::RET_FLAG, dl, MVT::Other, Chain); | 1110 result = DAG.getNode(ARMISD::RET_FLAG, dl, MVT::Other, Chain); |
1106 | 1111 |
1107 return result; | 1112 return result; |
1108 } | 1113 } |
1109 | 1114 |
1110 // ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as | 1115 // ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as |
1111 // their target countpart wrapped in the ARMISD::Wrapper node. Suppose N is | 1116 // their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is |
1112 // one of the above mentioned nodes. It has to be wrapped because otherwise | 1117 // one of the above mentioned nodes. It has to be wrapped because otherwise |
1113 // Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only | 1118 // Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only |
1114 // be used to form addressing mode. These wrapped nodes will be selected | 1119 // be used to form addressing mode. These wrapped nodes will be selected |
1115 // into MOVi. | 1120 // into MOVi. |
1116 static SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) { | 1121 static SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) { |
1117 MVT PtrVT = Op.getValueType(); | 1122 MVT PtrVT = Op.getValueType(); |
1118 // FIXME there is no actual debug info here | 1123 // FIXME there is no actual debug info here |
1119 DebugLoc dl = Op.getDebugLoc(); | 1124 DebugLoc dl = Op.getDebugLoc(); |
1120 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); | 1125 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); |
1121 SDValue Res; | 1126 SDValue Res; |
1122 if (CP->isMachineConstantPoolEntry()) | 1127 if (CP->isMachineConstantPoolEntry()) |
1123 Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, | 1128 Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, |
1124 CP->getAlignment()); | 1129 CP->getAlignment()); |
1125 else | 1130 else |
1126 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, | 1131 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, |
1127 CP->getAlignment()); | 1132 CP->getAlignment()); |
1128 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res); | 1133 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res); |
1129 } | 1134 } |
1130 | 1135 |
1131 SDValue ARMTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) { | 1136 SDValue ARMTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) { |
muth02446
2009/07/17 21:02:30
this should be commented
| |
1132 assert(!Subtarget->useInlineJumpTables() && | 1137 assert(!Subtarget->useInlineJumpTables() && |
1133 "inline jump tables not custom lowered"); | 1138 "inline jump tables not custom lowered"); |
1134 MVT PTy = getPointerTy(); | 1139 const MVT PTy = getPointerTy(); |
muth02446
2009/07/17 21:02:30
It would be nice to mark everything const that is
| |
1135 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); | 1140 const JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); |
1136 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy); | 1141 const SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy); |
1137 DebugLoc dl = Op.getDebugLoc(); | 1142 const DebugLoc dl = Op.getDebugLoc(); |
1138 | 1143 |
1139 ARMConstantPoolValue *CPV = new ARMConstantPoolValue(JT->getIndex()); | 1144 ARMConstantPoolValue *CPV = new ARMConstantPoolValue(JT->getIndex()); |
1140 SDValue Result = DAG.getTargetConstantPool(CPV, PTy, 4); | 1145 // TODO: factor this idiom to load a value from a CP into a new function |
1141 Result = DAG.getNode(ARMISD::Wrapper, dl, PTy, Result); | 1146 const SDValue PoolEntry = DAG.getTargetConstantPool(CPV, PTy, 4); |
muth02446
2009/07/17 21:02:30
I find chaining of variable in this way hard to re
| |
1142 return DAG.getLoad(PTy, dl, DAG.getEntryNode(), Result, NULL, 0); | 1147 const SDValue PoolWrapper = DAG.getNode(ARMISD::Wrapper, dl, PTy, PoolEntry); |
1148 return DAG.getLoad(PTy, dl, DAG.getEntryNode(), PoolWrapper, NULL, 0); | |
1143 } | 1149 } |
1144 | 1150 |
1145 // Lower ISD::GlobalTLSAddress using the "general dynamic" model | 1151 // Lower ISD::GlobalTLSAddress using the "general dynamic" model |
1146 SDValue | 1152 SDValue |
1147 ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, | 1153 ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, |
1148 SelectionDAG &DAG) { | 1154 SelectionDAG &DAG) { |
1149 DebugLoc dl = GA->getDebugLoc(); | 1155 DebugLoc dl = GA->getDebugLoc(); |
1150 MVT PtrVT = getPointerTy(); | 1156 MVT PtrVT = getPointerTy(); |
1151 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; | 1157 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; |
1152 ARMConstantPoolValue *CPV = | 1158 ARMConstantPoolValue *CPV = |
1153 new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue, | 1159 new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue, |
1154 PCAdj, "tlsgd", true); | 1160 PCAdj, "tlsgd", true); |
1161 | |
1155 SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4); | 1162 SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4); |
1156 Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument); | 1163 Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument); |
1157 Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument, NULL, 0); | 1164 Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument, NULL, 0); |
1158 SDValue Chain = Argument.getValue(1); | 1165 SDValue Chain = Argument.getValue(1); |
1159 | 1166 |
1160 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); | 1167 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); |
1161 Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel); | 1168 Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel); |
1162 | 1169 |
1163 // call __tls_get_addr. | 1170 // call __tls_get_addr. |
1164 ArgListTy Args; | 1171 ArgListTy Args; |
1165 ArgListEntry Entry; | 1172 ArgListEntry Entry; |
1166 Entry.Node = Argument; | 1173 Entry.Node = Argument; |
1167 Entry.Ty = (const Type *) Type::Int32Ty; | 1174 Entry.Ty = (const Type *) Type::Int32Ty; |
1168 Args.push_back(Entry); | 1175 Args.push_back(Entry); |
1169 // FIXME: is there useful debug info available here? | 1176 // FIXME: is there useful debug info available here? |
1170 std::pair<SDValue, SDValue> CallResult = | 1177 std::pair<SDValue, SDValue> CallResult = |
1171 LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, false, | 1178 LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, false, |
1172 CallingConv::C, false, | 1179 0, CallingConv::C, false, /*isReturnValueUsed=*/true, |
1173 DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl); | 1180 DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl); |
1174 return CallResult.first; | 1181 return CallResult.first; |
1175 } | 1182 } |
1176 | 1183 |
1177 // Lower ISD::GlobalTLSAddress using the "initial exec" or | 1184 // Lower ISD::GlobalTLSAddress using the "initial exec" or |
1178 // "local exec" model. | 1185 // "local exec" model. |
1179 SDValue | 1186 SDValue |
1180 ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA, | 1187 ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA, |
1181 SelectionDAG &DAG) { | 1188 SelectionDAG &DAG) { |
1182 GlobalValue *GV = GA->getGlobal(); | 1189 GlobalValue *GV = GA->getGlobal(); |
1183 DebugLoc dl = GA->getDebugLoc(); | 1190 DebugLoc dl = GA->getDebugLoc(); |
1184 SDValue Offset; | 1191 SDValue Offset; |
1185 SDValue Chain = DAG.getEntryNode(); | 1192 SDValue Chain = DAG.getEntryNode(); |
1186 MVT PtrVT = getPointerTy(); | 1193 MVT PtrVT = getPointerTy(); |
1187 // Get the Thread Pointer | 1194 // Get the Thread Pointer |
1188 SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); | 1195 SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); |
1189 | 1196 |
1190 if (GV->isDeclaration()){ | 1197 if (GV->isDeclaration()) { |
1191 // initial exec model | 1198 // initial exec model |
1192 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; | 1199 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; |
1193 ARMConstantPoolValue *CPV = | 1200 ARMConstantPoolValue *CPV = |
1194 new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue, | 1201 new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue, |
1195 PCAdj, "gottpoff", true); | 1202 PCAdj, "gottpoff", true); |
1196 Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); | 1203 Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); |
1197 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); | 1204 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); |
1198 Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, NULL, 0); | 1205 Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, NULL, 0); |
1199 Chain = Offset.getValue(1); | 1206 Chain = Offset.getValue(1); |
1200 | 1207 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1255 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); | 1262 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); |
1256 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0); | 1263 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0); |
1257 } | 1264 } |
1258 } | 1265 } |
1259 | 1266 |
1260 /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol | 1267 /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol |
1261 /// even in non-static mode. | 1268 /// even in non-static mode. |
1262 static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) { | 1269 static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) { |
1263 // If symbol visibility is hidden, the extra load is not needed if | 1270 // If symbol visibility is hidden, the extra load is not needed if |
1264 // the symbol is definitely defined in the current translation unit. | 1271 // the symbol is definitely defined in the current translation unit. |
1265 bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode(); | 1272 bool isDecl = GV->isDeclaration() || GV->hasAvailableExternallyLinkage(); |
1266 if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage())) | 1273 if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage())) |
1267 return false; | 1274 return false; |
1268 return RelocM != Reloc::Static && (isDecl || GV->isWeakForLinker()); | 1275 return RelocM != Reloc::Static && (isDecl || GV->isWeakForLinker()); |
1269 } | 1276 } |
1270 | 1277 |
1271 SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op, | 1278 SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op, |
1272 SelectionDAG &DAG) { | 1279 SelectionDAG &DAG) { |
1273 MVT PtrVT = getPointerTy(); | 1280 MVT PtrVT = getPointerTy(); |
1274 DebugLoc dl = Op.getDebugLoc(); | 1281 DebugLoc dl = Op.getDebugLoc(); |
1275 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); | 1282 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1312 ARMConstantPoolValue *CPV = new ARMConstantPoolValue("_GLOBAL_OFFSET_TABLE_", | 1319 ARMConstantPoolValue *CPV = new ARMConstantPoolValue("_GLOBAL_OFFSET_TABLE_", |
1313 ARMPCLabelIndex, | 1320 ARMPCLabelIndex, |
1314 ARMCP::CPValue, PCAdj); | 1321 ARMCP::CPValue, PCAdj); |
1315 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); | 1322 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); |
1316 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); | 1323 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); |
1317 SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0); | 1324 SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0); |
1318 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); | 1325 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); |
1319 return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); | 1326 return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); |
1320 } | 1327 } |
1321 | 1328 |
1329 static SDValue LowerNeonVLDIntrinsic(SDValue Op, SelectionDAG &DAG, | |
1330 unsigned Opcode) { | |
1331 SDNode *Node = Op.getNode(); | |
1332 MVT VT = Node->getValueType(0); | |
1333 DebugLoc dl = Op.getDebugLoc(); | |
1334 | |
1335 if (!VT.is64BitVector()) | |
1336 return SDValue(); // unimplemented | |
1337 | |
1338 SDValue Ops[] = { Node->getOperand(0), | |
1339 Node->getOperand(2) }; | |
1340 return DAG.getNode(Opcode, dl, Node->getVTList(), Ops, 2); | |
1341 } | |
1342 | |
1343 SDValue | |
1344 ARMTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) { | |
1345 unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); | |
1346 switch (IntNo) { | |
1347 case Intrinsic::arm_neon_vld2i: | |
1348 case Intrinsic::arm_neon_vld2f: | |
1349 return LowerNeonVLDIntrinsic(Op, DAG, ARMISD::VLD2D); | |
1350 case Intrinsic::arm_neon_vld3i: | |
1351 case Intrinsic::arm_neon_vld3f: | |
1352 return LowerNeonVLDIntrinsic(Op, DAG, ARMISD::VLD3D); | |
1353 case Intrinsic::arm_neon_vld4i: | |
1354 case Intrinsic::arm_neon_vld4f: | |
1355 return LowerNeonVLDIntrinsic(Op, DAG, ARMISD::VLD4D); | |
1356 case Intrinsic::arm_neon_vst2i: | |
1357 case Intrinsic::arm_neon_vst2f: | |
1358 case Intrinsic::arm_neon_vst3i: | |
1359 case Intrinsic::arm_neon_vst3f: | |
1360 case Intrinsic::arm_neon_vst4i: | |
1361 case Intrinsic::arm_neon_vst4f: | |
1362 default: return SDValue(); // Don't custom lower most intrinsics. | |
1363 } | |
1364 } | |
1365 | |
1322 SDValue | 1366 SDValue |
1323 ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) { | 1367 ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) { |
1324 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); | |
1325 unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); | 1368 unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); |
1326 DebugLoc dl = Op.getDebugLoc(); | 1369 DebugLoc dl = Op.getDebugLoc(); |
1327 switch (IntNo) { | 1370 switch (IntNo) { |
1328 default: return SDValue(); // Don't custom lower most intrinsics. | 1371 default: return SDValue(); // Don't custom lower most intrinsics. |
1329 case Intrinsic::arm_thread_pointer: | 1372 case Intrinsic::arm_thread_pointer: { |
1330 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); | 1373 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); |
1374 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); | |
1375 } | |
1331 case Intrinsic::eh_sjlj_setjmp: | 1376 case Intrinsic::eh_sjlj_setjmp: |
1332 SDValue Res = DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32, | 1377 return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32, Op.getOperand(1)); |
1333 Op.getOperand(1)); | |
1334 return Res; | |
1335 } | 1378 } |
1336 } | 1379 } |
1337 | 1380 |
1338 static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, | 1381 static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, |
1339 unsigned VarArgsFrameIndex) { | 1382 unsigned VarArgsFrameIndex) { |
1340 // vastart just stores the address of the VarArgsFrameIndex slot into the | 1383 // vastart just stores the address of the VarArgsFrameIndex slot into the |
1341 // memory location argument. | 1384 // memory location argument. |
1342 DebugLoc dl = Op.getDebugLoc(); | 1385 DebugLoc dl = Op.getDebugLoc(); |
1343 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); | 1386 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); |
1344 SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); | 1387 SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); |
1345 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); | 1388 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); |
1346 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0); | 1389 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0); |
1347 } | 1390 } |
1348 | 1391 |
1349 SDValue | 1392 SDValue |
1350 ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA, | 1393 ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA, |
1351 SDValue &Root, SelectionDAG &DAG, | 1394 SDValue &Root, SelectionDAG &DAG, |
1352 DebugLoc dl) { | 1395 DebugLoc dl) { |
1353 MachineFunction &MF = DAG.getMachineFunction(); | 1396 MachineFunction &MF = DAG.getMachineFunction(); |
1354 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 1397 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
1355 | 1398 |
1356 TargetRegisterClass *RC; | 1399 TargetRegisterClass *RC; |
1357 if (AFI->isThumbFunction()) | 1400 if (AFI->isThumb1OnlyFunction()) |
1358 RC = ARM::tGPRRegisterClass; | 1401 RC = ARM::tGPRRegisterClass; |
1359 else | 1402 else |
1360 RC = ARM::GPRRegisterClass; | 1403 RC = ARM::GPRRegisterClass; |
1361 | 1404 |
1362 // Transform the arguments stored in physical registers into virtual ones. | 1405 // Transform the arguments stored in physical registers into virtual ones. |
1363 unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); | 1406 unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); |
1364 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32); | 1407 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32); |
1365 | 1408 |
1366 SDValue ArgValue2; | 1409 SDValue ArgValue2; |
1367 if (NextVA.isMemLoc()) { | 1410 if (NextVA.isMemLoc()) { |
1368 unsigned ArgSize = NextVA.getLocVT().getSizeInBits()/8; | 1411 unsigned ArgSize = NextVA.getLocVT().getSizeInBits()/8; |
1369 MachineFrameInfo *MFI = MF.getFrameInfo(); | 1412 MachineFrameInfo *MFI = MF.getFrameInfo(); |
1370 int FI = MFI->CreateFixedObject(ArgSize, NextVA.getLocMemOffset()); | 1413 int FI = MFI->CreateFixedObject(ArgSize, NextVA.getLocMemOffset()); |
1371 | 1414 |
1372 // Create load node to retrieve arguments from the stack. | 1415 // Create load node to retrieve arguments from the stack. |
1373 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); | 1416 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); |
1374 ArgValue2 = DAG.getLoad(MVT::i32, dl, Root, FIN, NULL, 0); | 1417 ArgValue2 = DAG.getLoad(MVT::i32, dl, Root, FIN, NULL, 0); |
1375 } else { | 1418 } else { |
1376 Reg = MF.addLiveIn(NextVA.getLocReg(), RC); | 1419 Reg = MF.addLiveIn(NextVA.getLocReg(), RC); |
1377 ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32); | 1420 ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32); |
1378 } | 1421 } |
1379 | 1422 |
1380 return DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, ArgValue, ArgValue2); | 1423 return DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, ArgValue, ArgValue2); |
1381 } | 1424 } |
1382 | 1425 |
1383 SDValue | 1426 SDValue |
1384 ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { | 1427 ARMTargetLowering::LowerFormalArguments(SDValue Chain, |
1428 unsigned CallConv, bool isVarArg, | |
1429 const SmallVectorImpl<ISD::InputArg> | |
1430 &Ins, | |
1431 DebugLoc dl, SelectionDAG &DAG, | |
1432 SmallVectorImpl<SDValue> &InVals) { | |
1433 | |
1385 MachineFunction &MF = DAG.getMachineFunction(); | 1434 MachineFunction &MF = DAG.getMachineFunction(); |
1386 MachineFrameInfo *MFI = MF.getFrameInfo(); | 1435 MachineFrameInfo *MFI = MF.getFrameInfo(); |
1387 | 1436 |
1388 SDValue Root = Op.getOperand(0); | |
1389 DebugLoc dl = Op.getDebugLoc(); | |
1390 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; | |
1391 unsigned CC = MF.getFunction()->getCallingConv(); | |
1392 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 1437 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
1393 | 1438 |
1394 // Assign locations to all of the incoming arguments. | 1439 // Assign locations to all of the incoming arguments. |
1395 SmallVector<CCValAssign, 16> ArgLocs; | 1440 SmallVector<CCValAssign, 16> ArgLocs; |
1396 CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); | 1441 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, |
1397 CCInfo.AnalyzeFormalArguments(Op.getNode(), | 1442 *DAG.getContext()); |
1398 CCAssignFnForNode(CC, /* Return*/ false)); | 1443 CCInfo.AnalyzeFormalArguments(Ins, |
1444 CCAssignFnForNode(CallConv, /* Return*/ false)); | |
1399 | 1445 |
1400 SmallVector<SDValue, 16> ArgValues; | 1446 SmallVector<SDValue, 16> ArgValues; |
1401 | 1447 |
1402 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { | 1448 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { |
1403 CCValAssign &VA = ArgLocs[i]; | 1449 CCValAssign &VA = ArgLocs[i]; |
1404 | 1450 |
1405 // Arguments stored in registers. | 1451 // Arguments stored in registers. |
1406 if (VA.isRegLoc()) { | 1452 if (VA.isRegLoc()) { |
1407 MVT RegVT = VA.getLocVT(); | 1453 MVT RegVT = VA.getLocVT(); |
1408 | 1454 |
1409 SDValue ArgValue; | 1455 SDValue ArgValue; |
1410 if (VA.needsCustom()) { | 1456 if (VA.needsCustom()) { |
1411 // f64 and vector types are split up into multiple registers or | 1457 // f64 and vector types are split up into multiple registers or |
1412 // combinations of registers and stack slots. | 1458 // combinations of registers and stack slots. |
1413 RegVT = MVT::i32; | 1459 RegVT = MVT::i32; |
1414 | 1460 |
1415 if (VA.getLocVT() == MVT::v2f64) { | 1461 if (VA.getLocVT() == MVT::v2f64) { |
1416 SDValue ArgValue1 = GetF64FormalArgument(VA, ArgLocs[++i], | 1462 SDValue ArgValue1 = GetF64FormalArgument(VA, ArgLocs[++i], |
1417 Root, DAG, dl); | 1463 Chain, DAG, dl); |
1418 VA = ArgLocs[++i]; // skip ahead to next loc | 1464 VA = ArgLocs[++i]; // skip ahead to next loc |
1419 SDValue ArgValue2 = GetF64FormalArgument(VA, ArgLocs[++i], | 1465 SDValue ArgValue2 = GetF64FormalArgument(VA, ArgLocs[++i], |
1420 Root, DAG, dl); | 1466 Chain, DAG, dl); |
1421 ArgValue = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64); | 1467 ArgValue = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64); |
1422 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, | 1468 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, |
1423 ArgValue, ArgValue1, DAG.getIntPtrConstant(0)); | 1469 ArgValue, ArgValue1, DAG.getIntPtrConstant(0)); |
1424 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, | 1470 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, |
1425 ArgValue, ArgValue2, DAG.getIntPtrConstant(1)); | 1471 ArgValue, ArgValue2, DAG.getIntPtrConstant(1)); |
1426 } else | 1472 } else |
1427 ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Root, DAG, dl); | 1473 ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl); |
1428 | 1474 |
1429 } else { | 1475 } else { |
1430 TargetRegisterClass *RC; | 1476 TargetRegisterClass *RC; |
1431 if (FloatABIType == FloatABI::Hard && RegVT == MVT::f32) | 1477 if (FloatABIType == FloatABI::Hard && RegVT == MVT::f32) |
1432 RC = ARM::SPRRegisterClass; | 1478 RC = ARM::SPRRegisterClass; |
1433 else if (FloatABIType == FloatABI::Hard && RegVT == MVT::f64) | 1479 else if (FloatABIType == FloatABI::Hard && RegVT == MVT::f64) |
1434 RC = ARM::DPRRegisterClass; | 1480 RC = ARM::DPRRegisterClass; |
1435 else if (AFI->isThumbFunction()) | 1481 else if (AFI->isThumb1OnlyFunction()) |
1436 RC = ARM::tGPRRegisterClass; | 1482 RC = ARM::tGPRRegisterClass; |
1437 else | 1483 else |
1438 RC = ARM::GPRRegisterClass; | 1484 RC = ARM::GPRRegisterClass; |
1439 | 1485 |
1440 assert((RegVT == MVT::i32 || RegVT == MVT::f32 || | 1486 assert((RegVT == MVT::i32 || RegVT == MVT::f32 || |
1441 (FloatABIType == FloatABI::Hard && RegVT == MVT::f64)) && | 1487 (FloatABIType == FloatABI::Hard && RegVT == MVT::f64)) && |
1442 "RegVT not supported by FORMAL_ARGUMENTS Lowering"); | 1488 "RegVT not supported by formal arguments Lowering"); |
1443 | 1489 |
1444 // Transform the arguments in physical registers into virtual ones. | 1490 // Transform the arguments in physical registers into virtual ones. |
1445 unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); | 1491 unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); |
1446 ArgValue = DAG.getCopyFromReg(Root, dl, Reg, RegVT); | 1492 ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); |
1447 } | 1493 } |
1448 | 1494 |
1449 // If this is an 8 or 16-bit value, it is really passed promoted | 1495 // If this is an 8 or 16-bit value, it is really passed promoted |
1450 // to 32 bits. Insert an assert[sz]ext to capture this, then | 1496 // to 32 bits. Insert an assert[sz]ext to capture this, then |
1451 // truncate to the right size. | 1497 // truncate to the right size. |
1452 switch (VA.getLocInfo()) { | 1498 switch (VA.getLocInfo()) { |
1453 default: assert(0 && "Unknown loc info!"); | 1499 default: llvm_unreachable("Unknown loc info!"); |
1454 case CCValAssign::Full: break; | 1500 case CCValAssign::Full: break; |
1455 case CCValAssign::BCvt: | 1501 case CCValAssign::BCvt: |
1456 ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getValVT(), ArgValue); | 1502 ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getValVT(), ArgValue); |
1457 break; | 1503 break; |
1458 case CCValAssign::SExt: | 1504 case CCValAssign::SExt: |
1459 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, | 1505 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, |
1460 DAG.getValueType(VA.getValVT())); | 1506 DAG.getValueType(VA.getValVT())); |
1461 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); | 1507 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); |
1462 break; | 1508 break; |
1463 case CCValAssign::ZExt: | 1509 case CCValAssign::ZExt: |
1464 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, | 1510 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, |
1465 DAG.getValueType(VA.getValVT())); | 1511 DAG.getValueType(VA.getValVT())); |
1466 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); | 1512 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); |
1467 break; | 1513 break; |
1468 } | 1514 } |
1469 | 1515 |
1470 ArgValues.push_back(ArgValue); | 1516 InVals.push_back(ArgValue); |
1471 | 1517 |
1472 } else { // VA.isRegLoc() | 1518 } else { // VA.isRegLoc() |
1473 | 1519 |
1474 // sanity check | 1520 // sanity check |
1475 assert(VA.isMemLoc()); | 1521 assert(VA.isMemLoc()); |
1476 assert(VA.getValVT() != MVT::i64 && "i64 should already be lowered"); | 1522 assert(VA.getValVT() != MVT::i64 && "i64 should already be lowered"); |
1477 | 1523 |
1478 unsigned ArgSize = VA.getLocVT().getSizeInBits()/8; | 1524 unsigned ArgSize = VA.getLocVT().getSizeInBits()/8; |
1479 int FI = MFI->CreateFixedObject(ArgSize, VA.getLocMemOffset()); | 1525 int FI = MFI->CreateFixedObject(ArgSize, VA.getLocMemOffset()); |
1480 | 1526 |
1481 // Create load nodes to retrieve arguments from the stack. | 1527 // Create load nodes to retrieve arguments from the stack. |
1482 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); | 1528 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); |
1483 ArgValues.push_back(DAG.getLoad(VA.getValVT(), dl, Root, FIN, NULL, 0)); | 1529 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0)); |
1484 } | 1530 } |
1485 } | 1531 } |
1486 | 1532 |
1487 // varargs | 1533 // varargs |
1488 if (isVarArg) { | 1534 if (isVarArg) { |
1489 static const unsigned GPRArgRegs[] = { | 1535 static const unsigned GPRArgRegs[] = { |
1490 ARM::R0, ARM::R1, ARM::R2, ARM::R3 | 1536 ARM::R0, ARM::R1, ARM::R2, ARM::R3 |
1491 }; | 1537 }; |
1492 | 1538 |
1493 unsigned NumGPRs = CCInfo.getFirstUnallocated | 1539 unsigned NumGPRs = CCInfo.getFirstUnallocated |
1494 (GPRArgRegs, sizeof(GPRArgRegs) / sizeof(GPRArgRegs[0])); | 1540 (GPRArgRegs, sizeof(GPRArgRegs) / sizeof(GPRArgRegs[0])); |
1495 | 1541 |
1496 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); | 1542 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); |
1497 unsigned VARegSize = (4 - NumGPRs) * 4; | 1543 unsigned VARegSize = (4 - NumGPRs) * 4; |
1498 unsigned VARegSaveSize = (VARegSize + Align - 1) & ~(Align - 1); | 1544 unsigned VARegSaveSize = (VARegSize + Align - 1) & ~(Align - 1); |
1499 unsigned ArgOffset = 0; | 1545 unsigned ArgOffset = 0; |
1500 if (VARegSaveSize) { | 1546 if (VARegSaveSize) { |
1501 // If this function is vararg, store any remaining integer argument regs | 1547 // If this function is vararg, store any remaining integer argument regs |
1502 // to their spots on the stack so that they may be loaded by deferencing | 1548 // to their spots on the stack so that they may be loaded by deferencing |
1503 // the result of va_next. | 1549 // the result of va_next. |
1504 AFI->setVarArgsRegSaveSize(VARegSaveSize); | 1550 AFI->setVarArgsRegSaveSize(VARegSaveSize); |
1505 ArgOffset = CCInfo.getNextStackOffset(); | 1551 ArgOffset = CCInfo.getNextStackOffset(); |
1506 VarArgsFrameIndex = MFI->CreateFixedObject(VARegSaveSize, ArgOffset + | 1552 VarArgsFrameIndex = MFI->CreateFixedObject(VARegSaveSize, ArgOffset + |
1507 VARegSaveSize - VARegSize); | 1553 VARegSaveSize - VARegSize); |
1508 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy()); | 1554 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy()); |
1509 | 1555 |
1510 SmallVector<SDValue, 4> MemOps; | 1556 SmallVector<SDValue, 4> MemOps; |
1511 for (; NumGPRs < 4; ++NumGPRs) { | 1557 for (; NumGPRs < 4; ++NumGPRs) { |
1512 TargetRegisterClass *RC; | 1558 TargetRegisterClass *RC; |
1513 if (AFI->isThumbFunction()) | 1559 if (AFI->isThumb1OnlyFunction()) |
1514 RC = ARM::tGPRRegisterClass; | 1560 RC = ARM::tGPRRegisterClass; |
1515 else | 1561 else |
1516 RC = ARM::GPRRegisterClass; | 1562 RC = ARM::GPRRegisterClass; |
1517 | 1563 |
1518 unsigned VReg = MF.addLiveIn(GPRArgRegs[NumGPRs], RC); | 1564 unsigned VReg = MF.addLiveIn(GPRArgRegs[NumGPRs], RC); |
1519 SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); | 1565 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); |
1520 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); | 1566 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); |
1521 MemOps.push_back(Store); | 1567 MemOps.push_back(Store); |
1522 FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(), FIN, | 1568 FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(), FIN, |
1523 DAG.getConstant(4, getPointerTy())); | 1569 DAG.getConstant(4, getPointerTy())); |
1524 } | 1570 } |
1525 if (!MemOps.empty()) | 1571 if (!MemOps.empty()) |
1526 Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, | 1572 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, |
1527 &MemOps[0], MemOps.size()); | 1573 &MemOps[0], MemOps.size()); |
1528 } else | 1574 } else |
1529 // This will point to the next argument passed via stack. | 1575 // This will point to the next argument passed via stack. |
1530 VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); | 1576 VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); |
1531 } | 1577 } |
1532 | 1578 |
1533 ArgValues.push_back(Root); | 1579 return Chain; |
1534 | |
1535 // Return the new list of results. | |
1536 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), | |
1537 &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); | |
1538 } | 1580 } |
1539 | 1581 |
1540 /// isFloatingPointZero - Return true if this is +0.0. | 1582 /// isFloatingPointZero - Return true if this is +0.0. |
1541 static bool isFloatingPointZero(SDValue Op) { | 1583 static bool isFloatingPointZero(SDValue Op) { |
1542 if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op)) | 1584 if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op)) |
1543 return CFP->getValueAPF().isPosZero(); | 1585 return CFP->getValueAPF().isPosZero(); |
1544 else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) { | 1586 else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) { |
1545 // Maybe this has already been legalized into the constant pool? | 1587 // Maybe this has already been legalized into the constant pool? |
1546 if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) { | 1588 if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) { |
1547 SDValue WrapperOp = Op.getOperand(1).getOperand(0); | 1589 SDValue WrapperOp = Op.getOperand(1).getOperand(0); |
1548 if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(WrapperOp)) | 1590 if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(WrapperOp)) |
1549 if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal())) | 1591 if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal())) |
1550 return CFP->getValueAPF().isPosZero(); | 1592 return CFP->getValueAPF().isPosZero(); |
1551 } | 1593 } |
1552 } | 1594 } |
1553 return false; | 1595 return false; |
1554 } | 1596 } |
1555 | 1597 |
1556 static bool isLegalCmpImmediate(unsigned C, bool isThumb) { | 1598 static bool isLegalCmpImmediate(unsigned C, bool isThumb1Only) { |
1557 return ( isThumb && (C & ~255U) == 0) || | 1599 return ( isThumb1Only && (C & ~255U) == 0) || |
1558 (!isThumb && ARM_AM::getSOImmVal(C) != -1); | 1600 (!isThumb1Only && ARM_AM::getSOImmVal(C) != -1); |
1559 } | 1601 } |
1560 | 1602 |
1561 /// Returns appropriate ARM CMP (cmp) and corresponding condition code for | 1603 /// Returns appropriate ARM CMP (cmp) and corresponding condition code for |
1562 /// the given operands. | 1604 /// the given operands. |
1563 static SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, | 1605 static SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, |
1564 SDValue &ARMCC, SelectionDAG &DAG, bool isThumb, | 1606 SDValue &ARMCC, SelectionDAG &DAG, bool isThumb1Only, |
1565 DebugLoc dl) { | 1607 DebugLoc dl) { |
1566 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) { | 1608 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) { |
1567 unsigned C = RHSC->getZExtValue(); | 1609 unsigned C = RHSC->getZExtValue(); |
1568 if (!isLegalCmpImmediate(C, isThumb)) { | 1610 if (!isLegalCmpImmediate(C, isThumb1Only)) { |
1569 // Constant does not fit, try adjusting it by one? | 1611 // Constant does not fit, try adjusting it by one? |
1570 switch (CC) { | 1612 switch (CC) { |
1571 default: break; | 1613 default: break; |
1572 case ISD::SETLT: | 1614 case ISD::SETLT: |
1573 case ISD::SETGE: | 1615 case ISD::SETGE: |
1574 if (isLegalCmpImmediate(C-1, isThumb)) { | 1616 if (isLegalCmpImmediate(C-1, isThumb1Only)) { |
1575 CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT; | 1617 CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT; |
1576 RHS = DAG.getConstant(C-1, MVT::i32); | 1618 RHS = DAG.getConstant(C-1, MVT::i32); |
1577 } | 1619 } |
1578 break; | 1620 break; |
1579 case ISD::SETULT: | 1621 case ISD::SETULT: |
1580 case ISD::SETUGE: | 1622 case ISD::SETUGE: |
1581 if (C > 0 && isLegalCmpImmediate(C-1, isThumb)) { | 1623 if (C > 0 && isLegalCmpImmediate(C-1, isThumb1Only)) { |
1582 CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT; | 1624 CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT; |
1583 RHS = DAG.getConstant(C-1, MVT::i32); | 1625 RHS = DAG.getConstant(C-1, MVT::i32); |
1584 } | 1626 } |
1585 break; | 1627 break; |
1586 case ISD::SETLE: | 1628 case ISD::SETLE: |
1587 case ISD::SETGT: | 1629 case ISD::SETGT: |
1588 if (isLegalCmpImmediate(C+1, isThumb)) { | 1630 if (isLegalCmpImmediate(C+1, isThumb1Only)) { |
1589 CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE; | 1631 CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE; |
1590 RHS = DAG.getConstant(C+1, MVT::i32); | 1632 RHS = DAG.getConstant(C+1, MVT::i32); |
1591 } | 1633 } |
1592 break; | 1634 break; |
1593 case ISD::SETULE: | 1635 case ISD::SETULE: |
1594 case ISD::SETUGT: | 1636 case ISD::SETUGT: |
1595 if (C < 0xffffffff && isLegalCmpImmediate(C+1, isThumb)) { | 1637 if (C < 0xffffffff && isLegalCmpImmediate(C+1, isThumb1Only)) { |
1596 CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE; | 1638 CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE; |
1597 RHS = DAG.getConstant(C+1, MVT::i32); | 1639 RHS = DAG.getConstant(C+1, MVT::i32); |
1598 } | 1640 } |
1599 break; | 1641 break; |
1600 } | 1642 } |
1601 } | 1643 } |
1602 } | 1644 } |
1603 | 1645 |
1604 ARMCC::CondCodes CondCode = IntCCToARMCC(CC); | 1646 ARMCC::CondCodes CondCode = IntCCToARMCC(CC); |
1605 ARMISD::NodeType CompareType; | 1647 ARMISD::NodeType CompareType; |
1606 switch (CondCode) { | 1648 switch (CondCode) { |
1607 default: | 1649 default: |
1608 CompareType = ARMISD::CMP; | 1650 CompareType = ARMISD::CMP; |
1609 break; | 1651 break; |
1610 case ARMCC::EQ: | 1652 case ARMCC::EQ: |
1611 case ARMCC::NE: | 1653 case ARMCC::NE: |
1612 case ARMCC::MI: | 1654 // Uses only Z Flag |
1613 case ARMCC::PL: | 1655 CompareType = ARMISD::CMPZ; |
1614 // Uses only N and Z Flags | |
1615 CompareType = ARMISD::CMPNZ; | |
1616 break; | 1656 break; |
1617 } | 1657 } |
1618 ARMCC = DAG.getConstant(CondCode, MVT::i32); | 1658 ARMCC = DAG.getConstant(CondCode, MVT::i32); |
1619 return DAG.getNode(CompareType, dl, MVT::Flag, LHS, RHS); | 1659 return DAG.getNode(CompareType, dl, MVT::Flag, LHS, RHS); |
1620 } | 1660 } |
1621 | 1661 |
1622 /// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands. | 1662 /// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands. |
1623 static SDValue getVFPCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG, | 1663 static SDValue getVFPCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG, |
1624 DebugLoc dl) { | 1664 DebugLoc dl) { |
1625 SDValue Cmp; | 1665 SDValue Cmp; |
(...skipping 10 matching lines...) Expand all Loading... | |
1636 SDValue LHS = Op.getOperand(0); | 1676 SDValue LHS = Op.getOperand(0); |
1637 SDValue RHS = Op.getOperand(1); | 1677 SDValue RHS = Op.getOperand(1); |
1638 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); | 1678 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); |
1639 SDValue TrueVal = Op.getOperand(2); | 1679 SDValue TrueVal = Op.getOperand(2); |
1640 SDValue FalseVal = Op.getOperand(3); | 1680 SDValue FalseVal = Op.getOperand(3); |
1641 DebugLoc dl = Op.getDebugLoc(); | 1681 DebugLoc dl = Op.getDebugLoc(); |
1642 | 1682 |
1643 if (LHS.getValueType() == MVT::i32) { | 1683 if (LHS.getValueType() == MVT::i32) { |
1644 SDValue ARMCC; | 1684 SDValue ARMCC; |
1645 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); | 1685 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); |
1646 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMCC, DAG, ST->isThumb(), dl); | 1686 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMCC, DAG, ST->isThumb1Only(), dl); |
1647 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMCC, CCR,Cmp); | 1687 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMCC, CCR,Cmp); |
1648 } | 1688 } |
1649 | 1689 |
1650 ARMCC::CondCodes CondCode, CondCode2; | 1690 ARMCC::CondCodes CondCode, CondCode2; |
1651 if (FPCCToARMCC(CC, CondCode, CondCode2)) | 1691 if (FPCCToARMCC(CC, CondCode, CondCode2)) |
1652 std::swap(TrueVal, FalseVal); | 1692 std::swap(TrueVal, FalseVal); |
1653 | 1693 |
1654 SDValue ARMCC = DAG.getConstant(CondCode, MVT::i32); | 1694 SDValue ARMCC = DAG.getConstant(CondCode, MVT::i32); |
1655 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); | 1695 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); |
1656 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl); | 1696 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl); |
(...skipping 14 matching lines...) Expand all Loading... | |
1671 SDValue Chain = Op.getOperand(0); | 1711 SDValue Chain = Op.getOperand(0); |
1672 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); | 1712 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); |
1673 SDValue LHS = Op.getOperand(2); | 1713 SDValue LHS = Op.getOperand(2); |
1674 SDValue RHS = Op.getOperand(3); | 1714 SDValue RHS = Op.getOperand(3); |
1675 SDValue Dest = Op.getOperand(4); | 1715 SDValue Dest = Op.getOperand(4); |
1676 DebugLoc dl = Op.getDebugLoc(); | 1716 DebugLoc dl = Op.getDebugLoc(); |
1677 | 1717 |
1678 if (LHS.getValueType() == MVT::i32) { | 1718 if (LHS.getValueType() == MVT::i32) { |
1679 SDValue ARMCC; | 1719 SDValue ARMCC; |
1680 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); | 1720 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); |
1681 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMCC, DAG, ST->isThumb(), dl); | 1721 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMCC, DAG, ST->isThumb1Only(), dl); |
1682 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, | 1722 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, |
1683 Chain, Dest, ARMCC, CCR,Cmp); | 1723 Chain, Dest, ARMCC, CCR,Cmp); |
1684 } | 1724 } |
1685 | 1725 |
1686 assert(LHS.getValueType() == MVT::f32 || LHS.getValueType() == MVT::f64); | 1726 assert(LHS.getValueType() == MVT::f32 || LHS.getValueType() == MVT::f64); |
1687 ARMCC::CondCodes CondCode, CondCode2; | 1727 ARMCC::CondCodes CondCode, CondCode2; |
1688 if (FPCCToARMCC(CC, CondCode, CondCode2)) | 1728 if (FPCCToARMCC(CC, CondCode, CondCode2)) |
1689 // Swap the LHS/RHS of the comparison if needed. | 1729 // Swap the LHS/RHS of the comparison if needed. |
1690 std::swap(LHS, RHS); | 1730 std::swap(LHS, RHS); |
1691 | 1731 |
(...skipping 13 matching lines...) Expand all Loading... | |
1705 | 1745 |
1706 SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) { | 1746 SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) { |
1707 SDValue Chain = Op.getOperand(0); | 1747 SDValue Chain = Op.getOperand(0); |
1708 SDValue Table = Op.getOperand(1); | 1748 SDValue Table = Op.getOperand(1); |
1709 SDValue Index = Op.getOperand(2); | 1749 SDValue Index = Op.getOperand(2); |
1710 DebugLoc dl = Op.getDebugLoc(); | 1750 DebugLoc dl = Op.getDebugLoc(); |
1711 | 1751 |
1712 MVT PTy = getPointerTy(); | 1752 MVT PTy = getPointerTy(); |
1713 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table); | 1753 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table); |
1714 ARMFunctionInfo *AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>(); | 1754 ARMFunctionInfo *AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>(); |
1715 SDValue UId = DAG.getConstant(AFI->createJumpTableUId(), PTy); | 1755 SDValue UId = DAG.getConstant(AFI->createJumpTableUId(), PTy); |
1716 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy); | 1756 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy); |
1717 Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI, UId); | 1757 Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI, UId); |
1718 Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, PTy)); | 1758 Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, PTy)); |
1719 SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table); | 1759 SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table); |
1720 bool isPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_; | 1760 if (Subtarget->isThumb2()) { |
1721 Addr = DAG.getLoad(isPIC ? (MVT)MVT::i32 : PTy, dl, | 1761 // Thumb2 uses a two-level jump. That is, it jumps into the jump table |
1722 Chain, Addr, NULL, 0); | 1762 // which does another jump to the destination. This also makes it easier |
1723 Chain = Addr.getValue(1); | 1763 // to translate it to TBB / TBH later. |
1724 if (isPIC) | 1764 // FIXME: This might not work if the function is extremely large. |
1765 return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain, | |
1766 Addr, Op.getOperand(2), JTI, UId); | |
1767 } | |
1768 if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { | |
1769 Addr = DAG.getLoad((MVT)MVT::i32, dl, Chain, Addr, NULL, 0); | |
1770 Chain = Addr.getValue(1); | |
1725 Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, Table); | 1771 Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, Table); |
1726 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId); | 1772 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId); |
1773 } else { | |
1774 Addr = DAG.getLoad(PTy, dl, Chain, Addr, NULL, 0); | |
1775 Chain = Addr.getValue(1); | |
1776 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId); | |
1777 } | |
1727 } | 1778 } |
1728 | 1779 |
1729 static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) { | 1780 static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) { |
1730 DebugLoc dl = Op.getDebugLoc(); | 1781 DebugLoc dl = Op.getDebugLoc(); |
1731 unsigned Opc = | 1782 unsigned Opc = |
1732 Op.getOpcode() == ISD::FP_TO_SINT ? ARMISD::FTOSI : ARMISD::FTOUI; | 1783 Op.getOpcode() == ISD::FP_TO_SINT ? ARMISD::FTOSI : ARMISD::FTOUI; |
1733 Op = DAG.getNode(Opc, dl, MVT::f32, Op.getOperand(0)); | 1784 Op = DAG.getNode(Opc, dl, MVT::f32, Op.getOperand(0)); |
1734 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op); | 1785 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op); |
1735 } | 1786 } |
1736 | 1787 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1974 assert(VT == MVT::i64 && | 2025 assert(VT == MVT::i64 && |
1975 (N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) && | 2026 (N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) && |
1976 "Unknown shift to lower!"); | 2027 "Unknown shift to lower!"); |
1977 | 2028 |
1978 // We only lower SRA, SRL of 1 here, all others use generic lowering. | 2029 // We only lower SRA, SRL of 1 here, all others use generic lowering. |
1979 if (!isa<ConstantSDNode>(N->getOperand(1)) || | 2030 if (!isa<ConstantSDNode>(N->getOperand(1)) || |
1980 cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() != 1) | 2031 cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() != 1) |
1981 return SDValue(); | 2032 return SDValue(); |
1982 | 2033 |
1983 // If we are in thumb mode, we don't have RRX. | 2034 // If we are in thumb mode, we don't have RRX. |
1984 if (ST->isThumb()) return SDValue(); | 2035 if (ST->isThumb1Only()) return SDValue(); |
1985 | 2036 |
1986 // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr. | 2037 // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr. |
1987 SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), | 2038 SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), |
1988 DAG.getConstant(0, MVT::i32)); | 2039 DAG.getConstant(0, MVT::i32)); |
1989 SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), | 2040 SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), |
1990 DAG.getConstant(1, MVT::i32)); | 2041 DAG.getConstant(1, MVT::i32)); |
1991 | 2042 |
1992 // First, build a SRA_FLAG/SRL_FLAG op, which shifts the top part by one and | 2043 // First, build a SRA_FLAG/SRL_FLAG op, which shifts the top part by one and |
1993 // captures the result into a carry flag. | 2044 // captures the result into a carry flag. |
1994 unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::SRL_FLAG:ARMISD::SRA_FLAG; | 2045 unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::SRL_FLAG:ARMISD::SRA_FLAG; |
(...skipping 14 matching lines...) Expand all Loading... | |
2009 | 2060 |
2010 SDValue Op0 = Op.getOperand(0); | 2061 SDValue Op0 = Op.getOperand(0); |
2011 SDValue Op1 = Op.getOperand(1); | 2062 SDValue Op1 = Op.getOperand(1); |
2012 SDValue CC = Op.getOperand(2); | 2063 SDValue CC = Op.getOperand(2); |
2013 MVT VT = Op.getValueType(); | 2064 MVT VT = Op.getValueType(); |
2014 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get(); | 2065 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get(); |
2015 DebugLoc dl = Op.getDebugLoc(); | 2066 DebugLoc dl = Op.getDebugLoc(); |
2016 | 2067 |
2017 if (Op.getOperand(1).getValueType().isFloatingPoint()) { | 2068 if (Op.getOperand(1).getValueType().isFloatingPoint()) { |
2018 switch (SetCCOpcode) { | 2069 switch (SetCCOpcode) { |
2019 default: assert(0 && "Illegal FP comparison"); break; | 2070 default: llvm_unreachable("Illegal FP comparison"); break; |
2020 case ISD::SETUNE: | 2071 case ISD::SETUNE: |
2021 case ISD::SETNE: Invert = true; // Fallthrough | 2072 case ISD::SETNE: Invert = true; // Fallthrough |
2022 case ISD::SETOEQ: | 2073 case ISD::SETOEQ: |
2023 case ISD::SETEQ: Opc = ARMISD::VCEQ; break; | 2074 case ISD::SETEQ: Opc = ARMISD::VCEQ; break; |
2024 case ISD::SETOLT: | 2075 case ISD::SETOLT: |
2025 case ISD::SETLT: Swap = true; // Fallthrough | 2076 case ISD::SETLT: Swap = true; // Fallthrough |
2026 case ISD::SETOGT: | 2077 case ISD::SETOGT: |
2027 case ISD::SETGT: Opc = ARMISD::VCGT; break; | 2078 case ISD::SETGT: Opc = ARMISD::VCGT; break; |
2028 case ISD::SETOLE: | 2079 case ISD::SETOLE: |
2029 case ISD::SETLE: Swap = true; // Fallthrough | 2080 case ISD::SETLE: Swap = true; // Fallthrough |
(...skipping 18 matching lines...) Expand all Loading... | |
2048 TmpOp0 = Op0; | 2099 TmpOp0 = Op0; |
2049 TmpOp1 = Op1; | 2100 TmpOp1 = Op1; |
2050 Opc = ISD::OR; | 2101 Opc = ISD::OR; |
2051 Op0 = DAG.getNode(ARMISD::VCGT, dl, VT, TmpOp1, TmpOp0); | 2102 Op0 = DAG.getNode(ARMISD::VCGT, dl, VT, TmpOp1, TmpOp0); |
2052 Op1 = DAG.getNode(ARMISD::VCGE, dl, VT, TmpOp0, TmpOp1); | 2103 Op1 = DAG.getNode(ARMISD::VCGE, dl, VT, TmpOp0, TmpOp1); |
2053 break; | 2104 break; |
2054 } | 2105 } |
2055 } else { | 2106 } else { |
2056 // Integer comparisons. | 2107 // Integer comparisons. |
2057 switch (SetCCOpcode) { | 2108 switch (SetCCOpcode) { |
2058 default: assert(0 && "Illegal integer comparison"); break; | 2109 default: llvm_unreachable("Illegal integer comparison"); break; |
2059 case ISD::SETNE: Invert = true; | 2110 case ISD::SETNE: Invert = true; |
2060 case ISD::SETEQ: Opc = ARMISD::VCEQ; break; | 2111 case ISD::SETEQ: Opc = ARMISD::VCEQ; break; |
2061 case ISD::SETLT: Swap = true; | 2112 case ISD::SETLT: Swap = true; |
2062 case ISD::SETGT: Opc = ARMISD::VCGT; break; | 2113 case ISD::SETGT: Opc = ARMISD::VCGT; break; |
2063 case ISD::SETLE: Swap = true; | 2114 case ISD::SETLE: Swap = true; |
2064 case ISD::SETGE: Opc = ARMISD::VCGE; break; | 2115 case ISD::SETGE: Opc = ARMISD::VCGE; break; |
2065 case ISD::SETULT: Swap = true; | 2116 case ISD::SETULT: Swap = true; |
2066 case ISD::SETUGT: Opc = ARMISD::VCGTU; break; | 2117 case ISD::SETUGT: Opc = ARMISD::VCGTU; break; |
2067 case ISD::SETULE: Swap = true; | 2118 case ISD::SETULE: Swap = true; |
2068 case ISD::SETUGE: Opc = ARMISD::VCGEU; break; | 2119 case ISD::SETUGE: Opc = ARMISD::VCGEU; break; |
2069 } | 2120 } |
2070 | 2121 |
2071 // Detect VTST (Vector Test Bits) = vicmp ne (and (op0, op1), zero). | 2122 // Detect VTST (Vector Test Bits) = icmp ne (and (op0, op1), zero). |
2072 if (Opc == ARMISD::VCEQ) { | 2123 if (Opc == ARMISD::VCEQ) { |
2073 | 2124 |
2074 SDValue AndOp; | 2125 SDValue AndOp; |
2075 if (ISD::isBuildVectorAllZeros(Op1.getNode())) | 2126 if (ISD::isBuildVectorAllZeros(Op1.getNode())) |
2076 AndOp = Op0; | 2127 AndOp = Op0; |
2077 else if (ISD::isBuildVectorAllZeros(Op0.getNode())) | 2128 else if (ISD::isBuildVectorAllZeros(Op0.getNode())) |
2078 AndOp = Op1; | 2129 AndOp = Op1; |
2079 | 2130 |
2080 // Ignore bitconvert. | 2131 // Ignore bitconvert. |
2081 if (AndOp.getNode() && AndOp.getOpcode() == ISD::BIT_CONVERT) | 2132 if (AndOp.getNode() && AndOp.getOpcode() == ISD::BIT_CONVERT) |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2152 if (((SplatBits | SplatUndef) & BitMask) == BitMask) | 2203 if (((SplatBits | SplatUndef) & BitMask) == BitMask) |
2153 Val |= BitMask; | 2204 Val |= BitMask; |
2154 else if ((SplatBits & BitMask) != 0) | 2205 else if ((SplatBits & BitMask) != 0) |
2155 return SDValue(); | 2206 return SDValue(); |
2156 BitMask <<= 8; | 2207 BitMask <<= 8; |
2157 } | 2208 } |
2158 return DAG.getTargetConstant(Val, MVT::i64); | 2209 return DAG.getTargetConstant(Val, MVT::i64); |
2159 } | 2210 } |
2160 | 2211 |
2161 default: | 2212 default: |
2162 assert(0 && "unexpected size for isVMOVSplat"); | 2213 llvm_unreachable("unexpected size for isVMOVSplat"); |
2163 break; | 2214 break; |
2164 } | 2215 } |
2165 | 2216 |
2166 return SDValue(); | 2217 return SDValue(); |
2167 } | 2218 } |
2168 | 2219 |
2169 /// getVMOVImm - If this is a build_vector of constants which can be | 2220 /// getVMOVImm - If this is a build_vector of constants which can be |
2170 /// formed by using a VMOV instruction of the specified element size, | 2221 /// formed by using a VMOV instruction of the specified element size, |
2171 /// return the constant being splatted. The ByteSize field indicates the | 2222 /// return the constant being splatted. The ByteSize field indicates the |
2172 /// number of bytes of each element [1248]. | 2223 /// number of bytes of each element [1248]. |
2173 SDValue ARM::getVMOVImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) { | 2224 SDValue ARM::getVMOVImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) { |
2174 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N); | 2225 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N); |
2175 APInt SplatBits, SplatUndef; | 2226 APInt SplatBits, SplatUndef; |
2176 unsigned SplatBitSize; | 2227 unsigned SplatBitSize; |
2177 bool HasAnyUndefs; | 2228 bool HasAnyUndefs; |
2178 if (! BVN || ! BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, | 2229 if (! BVN || ! BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, |
2179 HasAnyUndefs, ByteSize * 8)) | 2230 HasAnyUndefs, ByteSize * 8)) |
2180 return SDValue(); | 2231 return SDValue(); |
2181 | 2232 |
2182 if (SplatBitSize > ByteSize * 8) | 2233 if (SplatBitSize > ByteSize * 8) |
2183 return SDValue(); | 2234 return SDValue(); |
2184 | 2235 |
2185 return isVMOVSplat(SplatBits.getZExtValue(), SplatUndef.getZExtValue(), | 2236 return isVMOVSplat(SplatBits.getZExtValue(), SplatUndef.getZExtValue(), |
2186 SplatBitSize, DAG); | 2237 SplatBitSize, DAG); |
2187 } | 2238 } |
2188 | 2239 |
2240 /// isVREVMask - Check if a vector shuffle corresponds to a VREV | |
2241 /// instruction with the specified blocksize. (The order of the elements | |
2242 /// within each block of the vector is reversed.) | |
2243 bool ARM::isVREVMask(ShuffleVectorSDNode *N, unsigned BlockSize) { | |
2244 assert((BlockSize==16 || BlockSize==32 || BlockSize==64) && | |
2245 "Only possible block sizes for VREV are: 16, 32, 64"); | |
2246 | |
2247 MVT VT = N->getValueType(0); | |
2248 unsigned NumElts = VT.getVectorNumElements(); | |
2249 unsigned EltSz = VT.getVectorElementType().getSizeInBits(); | |
2250 unsigned BlockElts = N->getMaskElt(0) + 1; | |
2251 | |
2252 if (BlockSize <= EltSz || BlockSize != BlockElts * EltSz) | |
2253 return false; | |
2254 | |
2255 for (unsigned i = 0; i < NumElts; ++i) { | |
2256 if ((unsigned) N->getMaskElt(i) != | |
2257 (i - i%BlockElts) + (BlockElts - 1 - i%BlockElts)) | |
2258 return false; | |
2259 } | |
2260 | |
2261 return true; | |
2262 } | |
2263 | |
2189 static SDValue BuildSplat(SDValue Val, MVT VT, SelectionDAG &DAG, DebugLoc dl) { | 2264 static SDValue BuildSplat(SDValue Val, MVT VT, SelectionDAG &DAG, DebugLoc dl) { |
2190 // Canonicalize all-zeros and all-ones vectors. | 2265 // Canonicalize all-zeros and all-ones vectors. |
2191 ConstantSDNode *ConstVal = dyn_cast<ConstantSDNode>(Val.getNode()); | 2266 ConstantSDNode *ConstVal = dyn_cast<ConstantSDNode>(Val.getNode()); |
2192 if (ConstVal->isNullValue()) | 2267 if (ConstVal->isNullValue()) |
2193 return getZeroVector(VT, DAG, dl); | 2268 return getZeroVector(VT, DAG, dl); |
2194 if (ConstVal->isAllOnesValue()) | 2269 if (ConstVal->isAllOnesValue()) |
2195 return getOnesVector(VT, DAG, dl); | 2270 return getOnesVector(VT, DAG, dl); |
2196 | 2271 |
2197 MVT CanonicalVT; | 2272 MVT CanonicalVT; |
2198 if (VT.is64BitVector()) { | 2273 if (VT.is64BitVector()) { |
2199 switch (Val.getValueType().getSizeInBits()) { | 2274 switch (Val.getValueType().getSizeInBits()) { |
2200 case 8: CanonicalVT = MVT::v8i8; break; | 2275 case 8: CanonicalVT = MVT::v8i8; break; |
2201 case 16: CanonicalVT = MVT::v4i16; break; | 2276 case 16: CanonicalVT = MVT::v4i16; break; |
2202 case 32: CanonicalVT = MVT::v2i32; break; | 2277 case 32: CanonicalVT = MVT::v2i32; break; |
2203 case 64: CanonicalVT = MVT::v1i64; break; | 2278 case 64: CanonicalVT = MVT::v1i64; break; |
2204 default: assert(0 && "unexpected splat element type"); break; | 2279 default: llvm_unreachable("unexpected splat element type"); break; |
2205 } | 2280 } |
2206 } else { | 2281 } else { |
2207 assert(VT.is128BitVector() && "unknown splat vector size"); | 2282 assert(VT.is128BitVector() && "unknown splat vector size"); |
2208 switch (Val.getValueType().getSizeInBits()) { | 2283 switch (Val.getValueType().getSizeInBits()) { |
2209 case 8: CanonicalVT = MVT::v16i8; break; | 2284 case 8: CanonicalVT = MVT::v16i8; break; |
2210 case 16: CanonicalVT = MVT::v8i16; break; | 2285 case 16: CanonicalVT = MVT::v8i16; break; |
2211 case 32: CanonicalVT = MVT::v4i32; break; | 2286 case 32: CanonicalVT = MVT::v4i32; break; |
2212 case 64: CanonicalVT = MVT::v2i64; break; | 2287 case 64: CanonicalVT = MVT::v2i64; break; |
2213 default: assert(0 && "unexpected splat element type"); break; | 2288 default: llvm_unreachable("unexpected splat element type"); break; |
2214 } | 2289 } |
2215 } | 2290 } |
2216 | 2291 |
2217 // Build a canonical splat for this value. | 2292 // Build a canonical splat for this value. |
2218 SmallVector<SDValue, 8> Ops; | 2293 SmallVector<SDValue, 8> Ops; |
2219 Ops.assign(CanonicalVT.getVectorNumElements(), Val); | 2294 Ops.assign(CanonicalVT.getVectorNumElements(), Val); |
2220 SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, dl, CanonicalVT, &Ops[0], | 2295 SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, dl, CanonicalVT, &Ops[0], |
2221 Ops.size()); | 2296 Ops.size()); |
2222 return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Res); | 2297 return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Res); |
2223 } | 2298 } |
2224 | 2299 |
2225 // If this is a case we can't handle, return null and let the default | 2300 // If this is a case we can't handle, return null and let the default |
2226 // expansion code take care of it. | 2301 // expansion code take care of it. |
2227 static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { | 2302 static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { |
2228 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(Op.getNode()); | 2303 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(Op.getNode()); |
2229 assert(BVN != 0 && "Expected a BuildVectorSDNode in LowerBUILD_VECTOR"); | 2304 assert(BVN != 0 && "Expected a BuildVectorSDNode in LowerBUILD_VECTOR"); |
2230 DebugLoc dl = Op.getDebugLoc(); | 2305 DebugLoc dl = Op.getDebugLoc(); |
2306 MVT VT = Op.getValueType(); | |
2231 | 2307 |
2232 APInt SplatBits, SplatUndef; | 2308 APInt SplatBits, SplatUndef; |
2233 unsigned SplatBitSize; | 2309 unsigned SplatBitSize; |
2234 bool HasAnyUndefs; | 2310 bool HasAnyUndefs; |
2235 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) { | 2311 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) { |
2236 SDValue Val = isVMOVSplat(SplatBits.getZExtValue(), | 2312 SDValue Val = isVMOVSplat(SplatBits.getZExtValue(), |
2237 SplatUndef.getZExtValue(), SplatBitSize, DAG); | 2313 SplatUndef.getZExtValue(), SplatBitSize, DAG); |
2238 if (Val.getNode()) | 2314 if (Val.getNode()) |
2239 return BuildSplat(Val, Op.getValueType(), DAG, dl); | 2315 return BuildSplat(Val, VT, DAG, dl); |
2316 } | |
2317 | |
2318 // If there are only 2 elements in a 128-bit vector, insert them into an | |
2319 // undef vector. This handles the common case for 128-bit vector argument | |
2320 // passing, where the insertions should be translated to subreg accesses | |
2321 // with no real instructions. | |
2322 if (VT.is128BitVector() && Op.getNumOperands() == 2) { | |
2323 SDValue Val = DAG.getUNDEF(VT); | |
2324 SDValue Op0 = Op.getOperand(0); | |
2325 SDValue Op1 = Op.getOperand(1); | |
2326 if (Op0.getOpcode() != ISD::UNDEF) | |
2327 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Val, Op0, | |
2328 DAG.getIntPtrConstant(0)); | |
2329 if (Op1.getOpcode() != ISD::UNDEF) | |
2330 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Val, Op1, | |
2331 DAG.getIntPtrConstant(1)); | |
2332 return Val; | |
2240 } | 2333 } |
2241 | 2334 |
2242 return SDValue(); | 2335 return SDValue(); |
2243 } | 2336 } |
2244 | 2337 |
2245 static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { | 2338 static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { |
2246 return Op; | 2339 return Op; |
2247 } | 2340 } |
2248 | 2341 |
2249 static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) { | 2342 static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) { |
2250 return Op; | 2343 return Op; |
2251 } | 2344 } |
2252 | 2345 |
2253 static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) { | 2346 static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) { |
2254 MVT VT = Op.getValueType(); | 2347 MVT VT = Op.getValueType(); |
2255 DebugLoc dl = Op.getDebugLoc(); | 2348 DebugLoc dl = Op.getDebugLoc(); |
2256 assert((VT == MVT::i8 || VT == MVT::i16) && | 2349 assert((VT == MVT::i8 || VT == MVT::i16) && |
2257 "unexpected type for custom-lowering vector extract"); | 2350 "unexpected type for custom-lowering vector extract"); |
2258 SDValue Vec = Op.getOperand(0); | 2351 SDValue Vec = Op.getOperand(0); |
2259 SDValue Lane = Op.getOperand(1); | 2352 SDValue Lane = Op.getOperand(1); |
2260 Op = DAG.getNode(ARMISD::VGETLANEu, dl, MVT::i32, Vec, Lane); | 2353 Op = DAG.getNode(ARMISD::VGETLANEu, dl, MVT::i32, Vec, Lane); |
2261 Op = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Op, DAG.getValueType(VT)); | 2354 Op = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Op, DAG.getValueType(VT)); |
2262 return DAG.getNode(ISD::TRUNCATE, dl, VT, Op); | 2355 return DAG.getNode(ISD::TRUNCATE, dl, VT, Op); |
2263 } | 2356 } |
2264 | 2357 |
2265 static SDValue LowerCONCAT_VECTORS(SDValue Op) { | 2358 static SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) { |
2266 if (Op.getValueType().is128BitVector() && Op.getNumOperands() == 2) | 2359 // The only time a CONCAT_VECTORS operation can have legal types is when |
2267 return Op; | 2360 // two 64-bit vectors are concatenated to a 128-bit vector. |
2268 return SDValue(); | 2361 assert(Op.getValueType().is128BitVector() && Op.getNumOperands() == 2 && |
2362 "unexpected CONCAT_VECTORS"); | |
2363 DebugLoc dl = Op.getDebugLoc(); | |
2364 SDValue Val = DAG.getUNDEF(MVT::v2f64); | |
2365 SDValue Op0 = Op.getOperand(0); | |
2366 SDValue Op1 = Op.getOperand(1); | |
2367 if (Op0.getOpcode() != ISD::UNDEF) | |
2368 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val, | |
2369 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, Op0), | |
2370 DAG.getIntPtrConstant(0)); | |
2371 if (Op1.getOpcode() != ISD::UNDEF) | |
2372 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val, | |
2373 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, Op1), | |
2374 DAG.getIntPtrConstant(1)); | |
2375 return DAG.getNode(ISD::BIT_CONVERT, dl, Op.getValueType(), Val); | |
2269 } | 2376 } |
2270 | 2377 |
2271 SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { | 2378 SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { |
2272 switch (Op.getOpcode()) { | 2379 switch (Op.getOpcode()) { |
2273 default: assert(0 && "Don't know how to custom lower this!"); abort(); | 2380 default: llvm_unreachable("Don't know how to custom lower this!"); |
2274 case ISD::ConstantPool: return LowerConstantPool(Op, DAG); | 2381 case ISD::ConstantPool: return LowerConstantPool(Op, DAG); |
2275 case ISD::JumpTable: return LowerJumpTable(Op, DAG); | 2382 case ISD::JumpTable: return LowerJumpTable(Op, DAG); |
2276 case ISD::GlobalAddress: | 2383 case ISD::GlobalAddress: |
2277 return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) : | 2384 return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) : |
2278 LowerGlobalAddressELF(Op, DAG); | 2385 LowerGlobalAddressELF(Op, DAG); |
2279 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); | 2386 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); |
2280 case ISD::CALL: return LowerCALL(Op, DAG); | |
2281 case ISD::RET: return LowerRET(Op, DAG); | |
2282 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, Subtarget); | 2387 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, Subtarget); |
2283 case ISD::BR_CC: return LowerBR_CC(Op, DAG, Subtarget); | 2388 case ISD::BR_CC: return LowerBR_CC(Op, DAG, Subtarget); |
2284 case ISD::BR_JT: return LowerBR_JT(Op, DAG); | 2389 case ISD::BR_JT: return LowerBR_JT(Op, DAG); |
2285 case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); | 2390 case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); |
2286 case ISD::SINT_TO_FP: | 2391 case ISD::SINT_TO_FP: |
2287 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG); | 2392 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG); |
2288 case ISD::FP_TO_SINT: | 2393 case ISD::FP_TO_SINT: |
2289 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG); | 2394 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG); |
2290 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); | 2395 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); |
2291 case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); | |
2292 case ISD::RETURNADDR: break; | 2396 case ISD::RETURNADDR: break; |
2293 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); | 2397 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); |
2294 case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); | 2398 case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); |
2399 case ISD::INTRINSIC_W_CHAIN: return LowerINTRINSIC_W_CHAIN(Op, DAG); | |
2295 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); | 2400 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); |
2296 case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(Op.getNode(), DAG); | 2401 case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(Op.getNode(), DAG); |
2297 case ISD::SHL: | 2402 case ISD::SHL: |
2298 case ISD::SRL: | 2403 case ISD::SRL: |
2299 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget); | 2404 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget); |
2300 case ISD::VSETCC: return LowerVSETCC(Op, DAG); | 2405 case ISD::VSETCC: return LowerVSETCC(Op, DAG); |
2301 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG); | 2406 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG); |
2302 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG); | 2407 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG); |
2303 case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG); | 2408 case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG); |
2304 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG); | 2409 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG); |
2305 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op); | 2410 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG); |
2306 } | 2411 } |
2307 return SDValue(); | 2412 return SDValue(); |
2308 } | 2413 } |
2309 | 2414 |
2310 /// ReplaceNodeResults - Replace the results of node with an illegal result | 2415 /// ReplaceNodeResults - Replace the results of node with an illegal result |
2311 /// type with new values built out of custom code. | 2416 /// type with new values built out of custom code. |
2312 void ARMTargetLowering::ReplaceNodeResults(SDNode *N, | 2417 void ARMTargetLowering::ReplaceNodeResults(SDNode *N, |
2313 SmallVectorImpl<SDValue>&Results, | 2418 SmallVectorImpl<SDValue>&Results, |
2314 SelectionDAG &DAG) { | 2419 SelectionDAG &DAG) { |
2315 switch (N->getOpcode()) { | 2420 switch (N->getOpcode()) { |
2316 default: | 2421 default: |
2317 assert(0 && "Don't know how to custom expand this!"); | 2422 llvm_unreachable("Don't know how to custom expand this!"); |
2318 return; | 2423 return; |
2319 case ISD::BIT_CONVERT: | 2424 case ISD::BIT_CONVERT: |
2320 Results.push_back(ExpandBIT_CONVERT(N, DAG)); | 2425 Results.push_back(ExpandBIT_CONVERT(N, DAG)); |
2321 return; | 2426 return; |
2322 case ISD::SRL: | 2427 case ISD::SRL: |
2323 case ISD::SRA: { | 2428 case ISD::SRA: { |
2324 SDValue Res = LowerShift(N, DAG, Subtarget); | 2429 SDValue Res = LowerShift(N, DAG, Subtarget); |
2325 if (Res.getNode()) | 2430 if (Res.getNode()) |
2326 Results.push_back(Res); | 2431 Results.push_back(Res); |
2327 return; | 2432 return; |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2599 VShiftOpc = (IntNo == Intrinsic::arm_neon_vshifts ? | 2704 VShiftOpc = (IntNo == Intrinsic::arm_neon_vshifts ? |
2600 ARMISD::VSHRs : ARMISD::VSHRu); | 2705 ARMISD::VSHRs : ARMISD::VSHRu); |
2601 break; | 2706 break; |
2602 } | 2707 } |
2603 return SDValue(); | 2708 return SDValue(); |
2604 | 2709 |
2605 case Intrinsic::arm_neon_vshiftls: | 2710 case Intrinsic::arm_neon_vshiftls: |
2606 case Intrinsic::arm_neon_vshiftlu: | 2711 case Intrinsic::arm_neon_vshiftlu: |
2607 if (isVShiftLImm(N->getOperand(2), VT, true, Cnt)) | 2712 if (isVShiftLImm(N->getOperand(2), VT, true, Cnt)) |
2608 break; | 2713 break; |
2609 assert(0 && "invalid shift count for vshll intrinsic"); | 2714 llvm_unreachable("invalid shift count for vshll intrinsic"); |
2610 abort(); | |
2611 | 2715 |
2612 case Intrinsic::arm_neon_vrshifts: | 2716 case Intrinsic::arm_neon_vrshifts: |
2613 case Intrinsic::arm_neon_vrshiftu: | 2717 case Intrinsic::arm_neon_vrshiftu: |
2614 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt)) | 2718 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt)) |
2615 break; | 2719 break; |
2616 return SDValue(); | 2720 return SDValue(); |
2617 | 2721 |
2618 case Intrinsic::arm_neon_vqshifts: | 2722 case Intrinsic::arm_neon_vqshifts: |
2619 case Intrinsic::arm_neon_vqshiftu: | 2723 case Intrinsic::arm_neon_vqshiftu: |
2620 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) | 2724 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) |
2621 break; | 2725 break; |
2622 return SDValue(); | 2726 return SDValue(); |
2623 | 2727 |
2624 case Intrinsic::arm_neon_vqshiftsu: | 2728 case Intrinsic::arm_neon_vqshiftsu: |
2625 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) | 2729 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) |
2626 break; | 2730 break; |
2627 assert(0 && "invalid shift count for vqshlu intrinsic"); | 2731 llvm_unreachable("invalid shift count for vqshlu intrinsic"); |
2628 abort(); | |
2629 | 2732 |
2630 case Intrinsic::arm_neon_vshiftn: | 2733 case Intrinsic::arm_neon_vshiftn: |
2631 case Intrinsic::arm_neon_vrshiftn: | 2734 case Intrinsic::arm_neon_vrshiftn: |
2632 case Intrinsic::arm_neon_vqshiftns: | 2735 case Intrinsic::arm_neon_vqshiftns: |
2633 case Intrinsic::arm_neon_vqshiftnu: | 2736 case Intrinsic::arm_neon_vqshiftnu: |
2634 case Intrinsic::arm_neon_vqshiftnsu: | 2737 case Intrinsic::arm_neon_vqshiftnsu: |
2635 case Intrinsic::arm_neon_vqrshiftns: | 2738 case Intrinsic::arm_neon_vqrshiftns: |
2636 case Intrinsic::arm_neon_vqrshiftnu: | 2739 case Intrinsic::arm_neon_vqrshiftnu: |
2637 case Intrinsic::arm_neon_vqrshiftnsu: | 2740 case Intrinsic::arm_neon_vqrshiftnsu: |
2638 // Narrowing shifts require an immediate right shift. | 2741 // Narrowing shifts require an immediate right shift. |
2639 if (isVShiftRImm(N->getOperand(2), VT, true, true, Cnt)) | 2742 if (isVShiftRImm(N->getOperand(2), VT, true, true, Cnt)) |
2640 break; | 2743 break; |
2641 assert(0 && "invalid shift count for narrowing vector shift intrinsic"); | 2744 llvm_unreachable("invalid shift count for narrowing vector shift intrinsic "); |
2642 abort(); | |
2643 | 2745 |
2644 default: | 2746 default: |
2645 assert(0 && "unhandled vector shift"); | 2747 llvm_unreachable("unhandled vector shift"); |
2646 } | 2748 } |
2647 | 2749 |
2648 switch (IntNo) { | 2750 switch (IntNo) { |
2649 case Intrinsic::arm_neon_vshifts: | 2751 case Intrinsic::arm_neon_vshifts: |
2650 case Intrinsic::arm_neon_vshiftu: | 2752 case Intrinsic::arm_neon_vshiftu: |
2651 // Opcode already set above. | 2753 // Opcode already set above. |
2652 break; | 2754 break; |
2653 case Intrinsic::arm_neon_vshiftls: | 2755 case Intrinsic::arm_neon_vshiftls: |
2654 case Intrinsic::arm_neon_vshiftlu: | 2756 case Intrinsic::arm_neon_vshiftlu: |
2655 if (Cnt == VT.getVectorElementType().getSizeInBits()) | 2757 if (Cnt == VT.getVectorElementType().getSizeInBits()) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2693 case Intrinsic::arm_neon_vshiftins: { | 2795 case Intrinsic::arm_neon_vshiftins: { |
2694 MVT VT = N->getOperand(1).getValueType(); | 2796 MVT VT = N->getOperand(1).getValueType(); |
2695 int64_t Cnt; | 2797 int64_t Cnt; |
2696 unsigned VShiftOpc = 0; | 2798 unsigned VShiftOpc = 0; |
2697 | 2799 |
2698 if (isVShiftLImm(N->getOperand(3), VT, false, Cnt)) | 2800 if (isVShiftLImm(N->getOperand(3), VT, false, Cnt)) |
2699 VShiftOpc = ARMISD::VSLI; | 2801 VShiftOpc = ARMISD::VSLI; |
2700 else if (isVShiftRImm(N->getOperand(3), VT, false, true, Cnt)) | 2802 else if (isVShiftRImm(N->getOperand(3), VT, false, true, Cnt)) |
2701 VShiftOpc = ARMISD::VSRI; | 2803 VShiftOpc = ARMISD::VSRI; |
2702 else { | 2804 else { |
2703 assert(0 && "invalid shift count for vsli/vsri intrinsic"); | 2805 llvm_unreachable("invalid shift count for vsli/vsri intrinsic"); |
2704 abort(); | |
2705 } | 2806 } |
2706 | 2807 |
2707 return DAG.getNode(VShiftOpc, N->getDebugLoc(), N->getValueType(0), | 2808 return DAG.getNode(VShiftOpc, N->getDebugLoc(), N->getValueType(0), |
2708 N->getOperand(1), N->getOperand(2), | 2809 N->getOperand(1), N->getOperand(2), |
2709 DAG.getConstant(Cnt, MVT::i32)); | 2810 DAG.getConstant(Cnt, MVT::i32)); |
2710 } | 2811 } |
2711 | 2812 |
2712 case Intrinsic::arm_neon_vqrshifts: | 2813 case Intrinsic::arm_neon_vqrshifts: |
2713 case Intrinsic::arm_neon_vqrshiftu: | 2814 case Intrinsic::arm_neon_vqrshiftu: |
2714 // No immediate versions of these to check for. | 2815 // No immediate versions of these to check for. |
(...skipping 13 matching lines...) Expand all Loading... | |
2728 MVT VT = N->getValueType(0); | 2829 MVT VT = N->getValueType(0); |
2729 | 2830 |
2730 // Nothing to be done for scalar shifts. | 2831 // Nothing to be done for scalar shifts. |
2731 if (! VT.isVector()) | 2832 if (! VT.isVector()) |
2732 return SDValue(); | 2833 return SDValue(); |
2733 | 2834 |
2734 assert(ST->hasNEON() && "unexpected vector shift"); | 2835 assert(ST->hasNEON() && "unexpected vector shift"); |
2735 int64_t Cnt; | 2836 int64_t Cnt; |
2736 | 2837 |
2737 switch (N->getOpcode()) { | 2838 switch (N->getOpcode()) { |
2738 default: assert(0 && "unexpected shift opcode"); | 2839 default: llvm_unreachable("unexpected shift opcode"); |
2739 | 2840 |
2740 case ISD::SHL: | 2841 case ISD::SHL: |
2741 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt)) | 2842 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt)) |
2742 return DAG.getNode(ARMISD::VSHL, N->getDebugLoc(), VT, N->getOperand(0), | 2843 return DAG.getNode(ARMISD::VSHL, N->getDebugLoc(), VT, N->getOperand(0), |
2743 DAG.getConstant(Cnt, MVT::i32)); | 2844 DAG.getConstant(Cnt, MVT::i32)); |
2744 break; | 2845 break; |
2745 | 2846 |
2746 case ISD::SRA: | 2847 case ISD::SRA: |
2747 case ISD::SRL: | 2848 case ISD::SRL: |
2748 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) { | 2849 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) { |
(...skipping 22 matching lines...) Expand all Loading... | |
2771 MVT VT = N->getValueType(0); | 2872 MVT VT = N->getValueType(0); |
2772 MVT EltVT = N0.getValueType(); | 2873 MVT EltVT = N0.getValueType(); |
2773 const TargetLowering &TLI = DAG.getTargetLoweringInfo(); | 2874 const TargetLowering &TLI = DAG.getTargetLoweringInfo(); |
2774 | 2875 |
2775 if (VT == MVT::i32 && | 2876 if (VT == MVT::i32 && |
2776 (EltVT == MVT::i8 || EltVT == MVT::i16) && | 2877 (EltVT == MVT::i8 || EltVT == MVT::i16) && |
2777 TLI.isTypeLegal(Vec.getValueType())) { | 2878 TLI.isTypeLegal(Vec.getValueType())) { |
2778 | 2879 |
2779 unsigned Opc = 0; | 2880 unsigned Opc = 0; |
2780 switch (N->getOpcode()) { | 2881 switch (N->getOpcode()) { |
2781 default: assert(0 && "unexpected opcode"); | 2882 default: llvm_unreachable("unexpected opcode"); |
2782 case ISD::SIGN_EXTEND: | 2883 case ISD::SIGN_EXTEND: |
2783 Opc = ARMISD::VGETLANEs; | 2884 Opc = ARMISD::VGETLANEs; |
2784 break; | 2885 break; |
2785 case ISD::ZERO_EXTEND: | 2886 case ISD::ZERO_EXTEND: |
2786 case ISD::ANY_EXTEND: | 2887 case ISD::ANY_EXTEND: |
2787 Opc = ARMISD::VGETLANEu; | 2888 Opc = ARMISD::VGETLANEu; |
2788 break; | 2889 break; |
2789 } | 2890 } |
2790 return DAG.getNode(Opc, N->getDebugLoc(), VT, Vec, Lane); | 2891 return DAG.getNode(Opc, N->getDebugLoc(), VT, Vec, Lane); |
2791 } | 2892 } |
(...skipping 27 matching lines...) Expand all Loading... | |
2819 /// as the offset of the target addressing mode for load / store of the | 2920 /// as the offset of the target addressing mode for load / store of the |
2820 /// given type. | 2921 /// given type. |
2821 static bool isLegalAddressImmediate(int64_t V, MVT VT, | 2922 static bool isLegalAddressImmediate(int64_t V, MVT VT, |
2822 const ARMSubtarget *Subtarget) { | 2923 const ARMSubtarget *Subtarget) { |
2823 if (V == 0) | 2924 if (V == 0) |
2824 return true; | 2925 return true; |
2825 | 2926 |
2826 if (!VT.isSimple()) | 2927 if (!VT.isSimple()) |
2827 return false; | 2928 return false; |
2828 | 2929 |
2829 if (Subtarget->isThumb()) { | 2930 if (Subtarget->isThumb()) { // FIXME for thumb2 |
2830 if (V < 0) | 2931 if (V < 0) |
2831 return false; | 2932 return false; |
2832 | 2933 |
2833 unsigned Scale = 1; | 2934 unsigned Scale = 1; |
2834 switch (VT.getSimpleVT()) { | 2935 switch (VT.getSimpleVT()) { |
2835 default: return false; | 2936 default: return false; |
2836 case MVT::i1: | 2937 case MVT::i1: |
2837 case MVT::i8: | 2938 case MVT::i8: |
2838 // Scale == 1; | 2939 // Scale == 1; |
2839 break; | 2940 break; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2885 return false; | 2986 return false; |
2886 | 2987 |
2887 // Can never fold addr of global into load/store. | 2988 // Can never fold addr of global into load/store. |
2888 if (AM.BaseGV) | 2989 if (AM.BaseGV) |
2889 return false; | 2990 return false; |
2890 | 2991 |
2891 switch (AM.Scale) { | 2992 switch (AM.Scale) { |
2892 case 0: // no scale reg, must be "r+i" or "r", or "i". | 2993 case 0: // no scale reg, must be "r+i" or "r", or "i". |
2893 break; | 2994 break; |
2894 case 1: | 2995 case 1: |
2895 if (Subtarget->isThumb()) | 2996 if (Subtarget->isThumb()) // FIXME for thumb2 |
2896 return false; | 2997 return false; |
2897 // FALL THROUGH. | 2998 // FALL THROUGH. |
2898 default: | 2999 default: |
2899 // ARM doesn't support any R+R*scale+imm addr modes. | 3000 // ARM doesn't support any R+R*scale+imm addr modes. |
2900 if (AM.BaseOffs) | 3001 if (AM.BaseOffs) |
2901 return false; | 3002 return false; |
2902 | 3003 |
2903 if (!VT.isSimple()) | 3004 if (!VT.isSimple()) |
2904 return false; | 3005 return false; |
2905 | 3006 |
(...skipping 25 matching lines...) Expand all Loading... | |
2931 | 3032 |
2932 // Allow r << imm, but the imm has to be a multiple of two. | 3033 // Allow r << imm, but the imm has to be a multiple of two. |
2933 if (AM.Scale & 1) return false; | 3034 if (AM.Scale & 1) return false; |
2934 return isPowerOf2_32(AM.Scale); | 3035 return isPowerOf2_32(AM.Scale); |
2935 } | 3036 } |
2936 break; | 3037 break; |
2937 } | 3038 } |
2938 return true; | 3039 return true; |
2939 } | 3040 } |
2940 | 3041 |
2941 static bool getIndexedAddressParts(SDNode *Ptr, MVT VT, | 3042 static bool getARMIndexedAddressParts(SDNode *Ptr, MVT VT, |
2942 bool isSEXTLoad, SDValue &Base, | 3043 bool isSEXTLoad, SDValue &Base, |
2943 SDValue &Offset, bool &isInc, | 3044 SDValue &Offset, bool &isInc, |
2944 SelectionDAG &DAG) { | 3045 SelectionDAG &DAG) { |
2945 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB) | 3046 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB) |
2946 return false; | 3047 return false; |
2947 | 3048 |
2948 if (VT == MVT::i16 || ((VT == MVT::i8 || VT == MVT::i1) && isSEXTLoad)) { | 3049 if (VT == MVT::i16 || ((VT == MVT::i8 || VT == MVT::i1) && isSEXTLoad)) { |
2949 // AddressingMode 3 | 3050 // AddressingMode 3 |
2950 Base = Ptr->getOperand(0); | 3051 Base = Ptr->getOperand(0); |
2951 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) { | 3052 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) { |
2952 int RHSC = (int)RHS->getZExtValue(); | 3053 int RHSC = (int)RHS->getZExtValue(); |
2953 if (RHSC < 0 && RHSC > -256) { | 3054 if (RHSC < 0 && RHSC > -256) { |
3055 assert(Ptr->getOpcode() == ISD::ADD); | |
2954 isInc = false; | 3056 isInc = false; |
2955 Offset = DAG.getConstant(-RHSC, RHS->getValueType(0)); | 3057 Offset = DAG.getConstant(-RHSC, RHS->getValueType(0)); |
2956 return true; | 3058 return true; |
2957 } | 3059 } |
2958 } | 3060 } |
2959 isInc = (Ptr->getOpcode() == ISD::ADD); | 3061 isInc = (Ptr->getOpcode() == ISD::ADD); |
2960 Offset = Ptr->getOperand(1); | 3062 Offset = Ptr->getOperand(1); |
2961 return true; | 3063 return true; |
2962 } else if (VT == MVT::i32 || VT == MVT::i8 || VT == MVT::i1) { | 3064 } else if (VT == MVT::i32 || VT == MVT::i8 || VT == MVT::i1) { |
2963 // AddressingMode 2 | 3065 // AddressingMode 2 |
2964 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) { | 3066 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) { |
2965 int RHSC = (int)RHS->getZExtValue(); | 3067 int RHSC = (int)RHS->getZExtValue(); |
2966 if (RHSC < 0 && RHSC > -0x1000) { | 3068 if (RHSC < 0 && RHSC > -0x1000) { |
3069 assert(Ptr->getOpcode() == ISD::ADD); | |
2967 isInc = false; | 3070 isInc = false; |
2968 Offset = DAG.getConstant(-RHSC, RHS->getValueType(0)); | 3071 Offset = DAG.getConstant(-RHSC, RHS->getValueType(0)); |
2969 Base = Ptr->getOperand(0); | 3072 Base = Ptr->getOperand(0); |
2970 return true; | 3073 return true; |
2971 } | 3074 } |
2972 } | 3075 } |
2973 | 3076 |
2974 if (Ptr->getOpcode() == ISD::ADD) { | 3077 if (Ptr->getOpcode() == ISD::ADD) { |
2975 isInc = true; | 3078 isInc = true; |
2976 ARM_AM::ShiftOpc ShOpcVal= ARM_AM::getShiftOpcForNode(Ptr->getOperand(0)); | 3079 ARM_AM::ShiftOpc ShOpcVal= ARM_AM::getShiftOpcForNode(Ptr->getOperand(0)); |
(...skipping 10 matching lines...) Expand all Loading... | |
2987 isInc = (Ptr->getOpcode() == ISD::ADD); | 3090 isInc = (Ptr->getOpcode() == ISD::ADD); |
2988 Base = Ptr->getOperand(0); | 3091 Base = Ptr->getOperand(0); |
2989 Offset = Ptr->getOperand(1); | 3092 Offset = Ptr->getOperand(1); |
2990 return true; | 3093 return true; |
2991 } | 3094 } |
2992 | 3095 |
2993 // FIXME: Use FLDM / FSTM to emulate indexed FP load / store. | 3096 // FIXME: Use FLDM / FSTM to emulate indexed FP load / store. |
2994 return false; | 3097 return false; |
2995 } | 3098 } |
2996 | 3099 |
3100 static bool getT2IndexedAddressParts(SDNode *Ptr, MVT VT, | |
3101 bool isSEXTLoad, SDValue &Base, | |
3102 SDValue &Offset, bool &isInc, | |
3103 SelectionDAG &DAG) { | |
3104 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB) | |
3105 return false; | |
3106 | |
3107 Base = Ptr->getOperand(0); | |
3108 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) { | |
3109 int RHSC = (int)RHS->getZExtValue(); | |
3110 if (RHSC < 0 && RHSC > -0x100) { // 8 bits. | |
3111 assert(Ptr->getOpcode() == ISD::ADD); | |
3112 isInc = false; | |
3113 Offset = DAG.getConstant(-RHSC, RHS->getValueType(0)); | |
3114 return true; | |
3115 } else if (RHSC > 0 && RHSC < 0x100) { // 8 bit, no zero. | |
3116 isInc = Ptr->getOpcode() == ISD::ADD; | |
3117 Offset = DAG.getConstant(RHSC, RHS->getValueType(0)); | |
3118 return true; | |
3119 } | |
3120 } | |
3121 | |
3122 return false; | |
3123 } | |
3124 | |
2997 /// getPreIndexedAddressParts - returns true by value, base pointer and | 3125 /// getPreIndexedAddressParts - returns true by value, base pointer and |
2998 /// offset pointer and addressing mode by reference if the node's address | 3126 /// offset pointer and addressing mode by reference if the node's address |
2999 /// can be legally represented as pre-indexed load / store address. | 3127 /// can be legally represented as pre-indexed load / store address. |
3000 bool | 3128 bool |
3001 ARMTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base, | 3129 ARMTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base, |
3002 SDValue &Offset, | 3130 SDValue &Offset, |
3003 ISD::MemIndexedMode &AM, | 3131 ISD::MemIndexedMode &AM, |
3004 SelectionDAG &DAG) const { | 3132 SelectionDAG &DAG) const { |
3005 if (Subtarget->isThumb()) | 3133 if (Subtarget->isThumb1Only()) |
3006 return false; | 3134 return false; |
3007 | 3135 |
3008 MVT VT; | 3136 MVT VT; |
3009 SDValue Ptr; | 3137 SDValue Ptr; |
3010 bool isSEXTLoad = false; | 3138 bool isSEXTLoad = false; |
3011 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { | 3139 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { |
3012 Ptr = LD->getBasePtr(); | 3140 Ptr = LD->getBasePtr(); |
3013 VT = LD->getMemoryVT(); | 3141 VT = LD->getMemoryVT(); |
3014 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; | 3142 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; |
3015 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { | 3143 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { |
3016 Ptr = ST->getBasePtr(); | 3144 Ptr = ST->getBasePtr(); |
3017 VT = ST->getMemoryVT(); | 3145 VT = ST->getMemoryVT(); |
3018 } else | 3146 } else |
3019 return false; | 3147 return false; |
3020 | 3148 |
3021 bool isInc; | 3149 bool isInc; |
3022 bool isLegal = getIndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base, Off set, | 3150 bool isLegal = false; |
3023 isInc, DAG); | 3151 if (Subtarget->isThumb() && Subtarget->hasThumb2()) |
3024 if (isLegal) { | 3152 isLegal = getT2IndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base, |
3025 AM = isInc ? ISD::PRE_INC : ISD::PRE_DEC; | 3153 Offset, isInc, DAG); |
3026 return true; | 3154 else |
3027 } | 3155 isLegal = getARMIndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base, |
3028 return false; | 3156 Offset, isInc, DAG); |
3157 if (!isLegal) | |
3158 return false; | |
3159 | |
3160 AM = isInc ? ISD::PRE_INC : ISD::PRE_DEC; | |
3161 return true; | |
3029 } | 3162 } |
3030 | 3163 |
3031 /// getPostIndexedAddressParts - returns true by value, base pointer and | 3164 /// getPostIndexedAddressParts - returns true by value, base pointer and |
3032 /// offset pointer and addressing mode by reference if this node can be | 3165 /// offset pointer and addressing mode by reference if this node can be |
3033 /// combined with a load / store to form a post-indexed load / store. | 3166 /// combined with a load / store to form a post-indexed load / store. |
3034 bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, | 3167 bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, |
3035 SDValue &Base, | 3168 SDValue &Base, |
3036 SDValue &Offset, | 3169 SDValue &Offset, |
3037 ISD::MemIndexedMode &AM, | 3170 ISD::MemIndexedMode &AM, |
3038 SelectionDAG &DAG) const { | 3171 SelectionDAG &DAG) const { |
3039 if (Subtarget->isThumb()) | 3172 if (Subtarget->isThumb1Only()) |
3040 return false; | 3173 return false; |
3041 | 3174 |
3042 MVT VT; | 3175 MVT VT; |
3043 SDValue Ptr; | 3176 SDValue Ptr; |
3044 bool isSEXTLoad = false; | 3177 bool isSEXTLoad = false; |
3045 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { | 3178 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { |
3046 VT = LD->getMemoryVT(); | 3179 VT = LD->getMemoryVT(); |
3047 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; | 3180 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; |
3048 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { | 3181 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { |
3049 VT = ST->getMemoryVT(); | 3182 VT = ST->getMemoryVT(); |
3050 } else | 3183 } else |
3051 return false; | 3184 return false; |
3052 | 3185 |
3053 bool isInc; | 3186 bool isInc; |
3054 bool isLegal = getIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset, | 3187 bool isLegal = false; |
3188 if (Subtarget->isThumb() && Subtarget->hasThumb2()) | |
3189 isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset, | |
3055 isInc, DAG); | 3190 isInc, DAG); |
3056 if (isLegal) { | 3191 else |
3057 AM = isInc ? ISD::POST_INC : ISD::POST_DEC; | 3192 isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset, |
3058 return true; | 3193 isInc, DAG); |
3059 } | 3194 if (!isLegal) |
3060 return false; | 3195 return false; |
3196 | |
3197 AM = isInc ? ISD::POST_INC : ISD::POST_DEC; | |
3198 return true; | |
3061 } | 3199 } |
3062 | 3200 |
3063 void ARMTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, | 3201 void ARMTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, |
3064 const APInt &Mask, | 3202 const APInt &Mask, |
3065 APInt &KnownZero, | 3203 APInt &KnownZero, |
3066 APInt &KnownOne, | 3204 APInt &KnownOne, |
3067 const SelectionDAG &DAG, | 3205 const SelectionDAG &DAG, |
3068 unsigned Depth) const { | 3206 unsigned Depth) const { |
3069 KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); | 3207 KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); |
3070 switch (Op.getOpcode()) { | 3208 switch (Op.getOpcode()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3102 return TargetLowering::getConstraintType(Constraint); | 3240 return TargetLowering::getConstraintType(Constraint); |
3103 } | 3241 } |
3104 | 3242 |
3105 std::pair<unsigned, const TargetRegisterClass*> | 3243 std::pair<unsigned, const TargetRegisterClass*> |
3106 ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, | 3244 ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, |
3107 MVT VT) const { | 3245 MVT VT) const { |
3108 if (Constraint.size() == 1) { | 3246 if (Constraint.size() == 1) { |
3109 // GCC RS6000 Constraint Letters | 3247 // GCC RS6000 Constraint Letters |
3110 switch (Constraint[0]) { | 3248 switch (Constraint[0]) { |
3111 case 'l': | 3249 case 'l': |
3112 if (Subtarget->isThumb()) | 3250 if (Subtarget->isThumb1Only()) |
3113 return std::make_pair(0U, ARM::tGPRRegisterClass); | 3251 return std::make_pair(0U, ARM::tGPRRegisterClass); |
3114 else | 3252 else |
3115 return std::make_pair(0U, ARM::GPRRegisterClass); | 3253 return std::make_pair(0U, ARM::GPRRegisterClass); |
3116 case 'r': | 3254 case 'r': |
3117 return std::make_pair(0U, ARM::GPRRegisterClass); | 3255 return std::make_pair(0U, ARM::GPRRegisterClass); |
3118 case 'w': | 3256 case 'w': |
3119 if (VT == MVT::f32) | 3257 if (VT == MVT::f32) |
3120 return std::make_pair(0U, ARM::SPRRegisterClass); | 3258 return std::make_pair(0U, ARM::SPRRegisterClass); |
3121 if (VT == MVT::f64) | 3259 if (VT == MVT::f64) |
3122 return std::make_pair(0U, ARM::DPRRegisterClass); | 3260 return std::make_pair(0U, ARM::DPRRegisterClass); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3183 | 3321 |
3184 int64_t CVal64 = C->getSExtValue(); | 3322 int64_t CVal64 = C->getSExtValue(); |
3185 int CVal = (int) CVal64; | 3323 int CVal = (int) CVal64; |
3186 // None of these constraints allow values larger than 32 bits. Check | 3324 // None of these constraints allow values larger than 32 bits. Check |
3187 // that the value fits in an int. | 3325 // that the value fits in an int. |
3188 if (CVal != CVal64) | 3326 if (CVal != CVal64) |
3189 return; | 3327 return; |
3190 | 3328 |
3191 switch (Constraint) { | 3329 switch (Constraint) { |
3192 case 'I': | 3330 case 'I': |
3193 if (Subtarget->isThumb()) { | 3331 if (Subtarget->isThumb1Only()) { |
3194 // This must be a constant between 0 and 255, for ADD immediates. | 3332 // This must be a constant between 0 and 255, for ADD |
3333 // immediates. | |
3195 if (CVal >= 0 && CVal <= 255) | 3334 if (CVal >= 0 && CVal <= 255) |
3335 break; | |
3336 } else if (Subtarget->isThumb2()) { | |
3337 // A constant that can be used as an immediate value in a | |
3338 // data-processing instruction. | |
3339 if (ARM_AM::getT2SOImmVal(CVal) != -1) | |
3196 break; | 3340 break; |
3197 } else { | 3341 } else { |
3198 // A constant that can be used as an immediate value in a | 3342 // A constant that can be used as an immediate value in a |
3199 // data-processing instruction. | 3343 // data-processing instruction. |
3200 if (ARM_AM::getSOImmVal(CVal) != -1) | 3344 if (ARM_AM::getSOImmVal(CVal) != -1) |
3201 break; | 3345 break; |
3202 } | 3346 } |
3203 return; | 3347 return; |
3204 | 3348 |
3205 case 'J': | 3349 case 'J': |
3206 if (Subtarget->isThumb()) { | 3350 if (Subtarget->isThumb()) { // FIXME thumb2 |
3207 // This must be a constant between -255 and -1, for negated ADD | 3351 // This must be a constant between -255 and -1, for negated ADD |
3208 // immediates. This can be used in GCC with an "n" modifier that | 3352 // immediates. This can be used in GCC with an "n" modifier that |
3209 // prints the negated value, for use with SUB instructions. It is | 3353 // prints the negated value, for use with SUB instructions. It is |
3210 // not useful otherwise but is implemented for compatibility. | 3354 // not useful otherwise but is implemented for compatibility. |
3211 if (CVal >= -255 && CVal <= -1) | 3355 if (CVal >= -255 && CVal <= -1) |
3212 break; | 3356 break; |
3213 } else { | 3357 } else { |
3214 // This must be a constant between -4095 and 4095. It is not clear | 3358 // This must be a constant between -4095 and 4095. It is not clear |
3215 // what this constraint is intended for. Implemented for | 3359 // what this constraint is intended for. Implemented for |
3216 // compatibility with GCC. | 3360 // compatibility with GCC. |
3217 if (CVal >= -4095 && CVal <= 4095) | 3361 if (CVal >= -4095 && CVal <= 4095) |
3218 break; | 3362 break; |
3219 } | 3363 } |
3220 return; | 3364 return; |
3221 | 3365 |
3222 case 'K': | 3366 case 'K': |
3223 if (Subtarget->isThumb()) { | 3367 if (Subtarget->isThumb1Only()) { |
3224 // A 32-bit value where only one byte has a nonzero value. Exclude | 3368 // A 32-bit value where only one byte has a nonzero value. Exclude |
3225 // zero to match GCC. This constraint is used by GCC internally for | 3369 // zero to match GCC. This constraint is used by GCC internally for |
3226 // constants that can be loaded with a move/shift combination. | 3370 // constants that can be loaded with a move/shift combination. |
3227 // It is not useful otherwise but is implemented for compatibility. | 3371 // It is not useful otherwise but is implemented for compatibility. |
3228 if (CVal != 0 && ARM_AM::isThumbImmShiftedVal(CVal)) | 3372 if (CVal != 0 && ARM_AM::isThumbImmShiftedVal(CVal)) |
3373 break; | |
3374 } else if (Subtarget->isThumb2()) { | |
3375 // A constant whose bitwise inverse can be used as an immediate | |
3376 // value in a data-processing instruction. This can be used in GCC | |
3377 // with a "B" modifier that prints the inverted value, for use with | |
3378 // BIC and MVN instructions. It is not useful otherwise but is | |
3379 // implemented for compatibility. | |
3380 if (ARM_AM::getT2SOImmVal(~CVal) != -1) | |
3229 break; | 3381 break; |
3230 } else { | 3382 } else { |
3231 // A constant whose bitwise inverse can be used as an immediate | 3383 // A constant whose bitwise inverse can be used as an immediate |
3232 // value in a data-processing instruction. This can be used in GCC | 3384 // value in a data-processing instruction. This can be used in GCC |
3233 // with a "B" modifier that prints the inverted value, for use with | 3385 // with a "B" modifier that prints the inverted value, for use with |
3234 // BIC and MVN instructions. It is not useful otherwise but is | 3386 // BIC and MVN instructions. It is not useful otherwise but is |
3235 // implemented for compatibility. | 3387 // implemented for compatibility. |
3236 if (ARM_AM::getSOImmVal(~CVal) != -1) | 3388 if (ARM_AM::getSOImmVal(~CVal) != -1) |
3237 break; | 3389 break; |
3238 } | 3390 } |
3239 return; | 3391 return; |
3240 | 3392 |
3241 case 'L': | 3393 case 'L': |
3242 if (Subtarget->isThumb()) { | 3394 if (Subtarget->isThumb1Only()) { |
3243 // This must be a constant between -7 and 7, | 3395 // This must be a constant between -7 and 7, |
3244 // for 3-operand ADD/SUB immediate instructions. | 3396 // for 3-operand ADD/SUB immediate instructions. |
3245 if (CVal >= -7 && CVal < 7) | 3397 if (CVal >= -7 && CVal < 7) |
3398 break; | |
3399 } else if (Subtarget->isThumb2()) { | |
3400 // A constant whose negation can be used as an immediate value in a | |
3401 // data-processing instruction. This can be used in GCC with an "n" | |
3402 // modifier that prints the negated value, for use with SUB | |
3403 // instructions. It is not useful otherwise but is implemented for | |
3404 // compatibility. | |
3405 if (ARM_AM::getT2SOImmVal(-CVal) != -1) | |
3246 break; | 3406 break; |
3247 } else { | 3407 } else { |
3248 // A constant whose negation can be used as an immediate value in a | 3408 // A constant whose negation can be used as an immediate value in a |
3249 // data-processing instruction. This can be used in GCC with an "n" | 3409 // data-processing instruction. This can be used in GCC with an "n" |
3250 // modifier that prints the negated value, for use with SUB | 3410 // modifier that prints the negated value, for use with SUB |
3251 // instructions. It is not useful otherwise but is implemented for | 3411 // instructions. It is not useful otherwise but is implemented for |
3252 // compatibility. | 3412 // compatibility. |
3253 if (ARM_AM::getSOImmVal(-CVal) != -1) | 3413 if (ARM_AM::getSOImmVal(-CVal) != -1) |
3254 break; | 3414 break; |
3255 } | 3415 } |
3256 return; | 3416 return; |
3257 | 3417 |
3258 case 'M': | 3418 case 'M': |
3259 if (Subtarget->isThumb()) { | 3419 if (Subtarget->isThumb()) { // FIXME thumb2 |
3260 // This must be a multiple of 4 between 0 and 1020, for | 3420 // This must be a multiple of 4 between 0 and 1020, for |
3261 // ADD sp + immediate. | 3421 // ADD sp + immediate. |
3262 if ((CVal >= 0 && CVal <= 1020) && ((CVal & 3) == 0)) | 3422 if ((CVal >= 0 && CVal <= 1020) && ((CVal & 3) == 0)) |
3263 break; | 3423 break; |
3264 } else { | 3424 } else { |
3265 // A power of two or a constant between 0 and 32. This is used in | 3425 // A power of two or a constant between 0 and 32. This is used in |
3266 // GCC for the shift amount on shifted register operands, but it is | 3426 // GCC for the shift amount on shifted register operands, but it is |
3267 // useful in general for any shift amounts. | 3427 // useful in general for any shift amounts. |
3268 if ((CVal >= 0 && CVal <= 32) || ((CVal & (CVal - 1)) == 0)) | 3428 if ((CVal >= 0 && CVal <= 32) || ((CVal & (CVal - 1)) == 0)) |
3269 break; | 3429 break; |
3270 } | 3430 } |
3271 return; | 3431 return; |
3272 | 3432 |
3273 case 'N': | 3433 case 'N': |
3274 if (Subtarget->isThumb()) { | 3434 if (Subtarget->isThumb()) { // FIXME thumb2 |
3275 // This must be a constant between 0 and 31, for shift amounts. | 3435 // This must be a constant between 0 and 31, for shift amounts. |
3276 if (CVal >= 0 && CVal <= 31) | 3436 if (CVal >= 0 && CVal <= 31) |
3277 break; | 3437 break; |
3278 } | 3438 } |
3279 return; | 3439 return; |
3280 | 3440 |
3281 case 'O': | 3441 case 'O': |
3282 if (Subtarget->isThumb()) { | 3442 if (Subtarget->isThumb()) { // FIXME thumb2 |
3283 // This must be a multiple of 4 between -508 and 508, for | 3443 // This must be a multiple of 4 between -508 and 508, for |
3284 // ADD/SUB sp = sp + immediate. | 3444 // ADD/SUB sp = sp + immediate. |
3285 if ((CVal >= -508 && CVal <= 508) && ((CVal & 3) == 0)) | 3445 if ((CVal >= -508 && CVal <= 508) && ((CVal & 3) == 0)) |
3286 break; | 3446 break; |
3287 } | 3447 } |
3288 return; | 3448 return; |
3289 } | 3449 } |
3290 Result = DAG.getTargetConstant(CVal, Op.getValueType()); | 3450 Result = DAG.getTargetConstant(CVal, Op.getValueType()); |
3291 break; | 3451 break; |
3292 } | 3452 } |
3293 | 3453 |
3294 if (Result.getNode()) { | 3454 if (Result.getNode()) { |
3295 Ops.push_back(Result); | 3455 Ops.push_back(Result); |
3296 return; | 3456 return; |
3297 } | 3457 } |
3298 return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, hasMemory, | 3458 return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, hasMemory, |
3299 Ops, DAG); | 3459 Ops, DAG); |
3300 } | 3460 } |
LEFT | RIGHT |