ARMISelLowering.cpp revision bff392384ddb032c732c38ec78b91d7a25dcf467
13473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor//===-- ARMISelLowering.cpp - ARM DAG Lowering Implementation -------------===// 23473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// 33473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// The LLVM Compiler Infrastructure 43473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// 53473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// This file is distributed under the University of Illinois Open Source 63473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// License. See LICENSE.TXT for details. 73473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// 83473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor//===----------------------------------------------------------------------===// 93473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// 103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// This file defines the interfaces that ARM uses to lower LLVM code into a 11c5d64345cf19bfd72418eb0a837869b0462e9130Daniel Veillard// selection DAG. 123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// 133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor//===----------------------------------------------------------------------===// 143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "ARM.h" 163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "ARMAddressingModes.h" 17f3afa7dd4e8daacfa62f7345b7d7071e0cb33423Daniel Veillard#include "ARMConstantPoolValue.h" 1834ce8bece2f22cc99d25221b77315cd008f4866bDaniel Veillard#include "ARMISelLowering.h" 1970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese#include "ARMMachineFunctionInfo.h" 203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "ARMRegisterInfo.h" 213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "ARMSubtarget.h" 223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "ARMTargetMachine.h" 233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "ARMTargetObjectFile.h" 243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/CallingConv.h" 253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/Constants.h" 263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/Function.h" 273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/Instruction.h" 283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/Intrinsics.h" 293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/GlobalValue.h" 3075eb1adc04eb72a061d5b37bc0c73f4d92400d57Daniel Veillard#include "llvm/CodeGen/CallingConvLower.h" 3175eb1adc04eb72a061d5b37bc0c73f4d92400d57Daniel Veillard#include "llvm/CodeGen/MachineBasicBlock.h" 3275eb1adc04eb72a061d5b37bc0c73f4d92400d57Daniel Veillard#include "llvm/CodeGen/MachineFrameInfo.h" 333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/CodeGen/MachineFunction.h" 343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/CodeGen/MachineInstrBuilder.h" 353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/CodeGen/MachineRegisterInfo.h" 363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/CodeGen/PseudoSourceValue.h" 373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/CodeGen/SelectionDAG.h" 383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/Target/TargetOptions.h" 393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/ADT/VectorExtras.h" 403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/Support/ErrorHandling.h" 413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "llvm/Support/MathExtras.h" 423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorusing namespace llvm; 433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 45d85f4f437c9d54a658b229a77426e693bd328787Daniel Veillard CCValAssign::LocInfo &LocInfo, 469b731d709ee99b59b815d51ad80ebba409f0f20dDaniel Veillard ISD::ArgFlagsTy &ArgFlags, 479b731d709ee99b59b815d51ad80ebba409f0f20dDaniel Veillard CCState &State); 489b731d709ee99b59b815d51ad80ebba409f0f20dDaniel Veillardstatic bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 49d85f4f437c9d54a658b229a77426e693bd328787Daniel Veillard CCValAssign::LocInfo &LocInfo, 50d85f4f437c9d54a658b229a77426e693bd328787Daniel Veillard ISD::ArgFlagsTy &ArgFlags, 513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCState &State); 523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool RetCC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign::LocInfo &LocInfo, 543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ISD::ArgFlagsTy &ArgFlags, 553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCState &State); 563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign::LocInfo &LocInfo, 583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ISD::ArgFlagsTy &ArgFlags, 593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCState &State); 603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid ARMTargetLowering::addTypeForNEON(EVT VT, EVT PromotedLdStVT, 623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor EVT PromotedBitwiseVT) { 633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (VT != PromotedLdStVT) { 643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::LOAD, VT.getSimpleVT(), Promote); 653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor AddPromotedToType (ISD::LOAD, VT.getSimpleVT(), 663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor PromotedLdStVT.getSimpleVT()); 673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::STORE, VT.getSimpleVT(), Promote); 693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor AddPromotedToType (ISD::STORE, VT.getSimpleVT(), 703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor PromotedLdStVT.getSimpleVT()); 713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 72c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard 733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor EVT ElemTy = VT.getVectorElementType(); 743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ElemTy != MVT::i64 && ElemTy != MVT::f64) 753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::VSETCC, VT.getSimpleVT(), Custom); 761638a47a884b089825e26459081e137483b7d454Daniel Veillard if (ElemTy == MVT::i8 || ElemTy == MVT::i16) 771638a47a884b089825e26459081e137483b7d454Daniel Veillard setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT.getSimpleVT(), Custom); 781638a47a884b089825e26459081e137483b7d454Daniel Veillard setOperationAction(ISD::BUILD_VECTOR, VT.getSimpleVT(), Custom); 791638a47a884b089825e26459081e137483b7d454Daniel Veillard setOperationAction(ISD::VECTOR_SHUFFLE, VT.getSimpleVT(), Custom); 801638a47a884b089825e26459081e137483b7d454Daniel Veillard setOperationAction(ISD::SCALAR_TO_VECTOR, VT.getSimpleVT(), Custom); 81c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard setOperationAction(ISD::CONCAT_VECTORS, VT.getSimpleVT(), Custom); 82c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard if (VT.isInteger()) { 831638a47a884b089825e26459081e137483b7d454Daniel Veillard setOperationAction(ISD::SHL, VT.getSimpleVT(), Custom); 841638a47a884b089825e26459081e137483b7d454Daniel Veillard setOperationAction(ISD::SRA, VT.getSimpleVT(), Custom); 851638a47a884b089825e26459081e137483b7d454Daniel Veillard setOperationAction(ISD::SRL, VT.getSimpleVT(), Custom); 86d0463560300f1d8b3e41d70c3728ed84fdc8dd30Daniel Veillard } 87f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Promote all bit-wise operations. 893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (VT.isInteger() && VT != PromotedBitwiseVT) { 903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::AND, VT.getSimpleVT(), Promote); 913c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard AddPromotedToType (ISD::AND, VT.getSimpleVT(), 928efff671578465d3bf122cc0a6811bc3763ee519Daniel Veillard PromotedBitwiseVT.getSimpleVT()); 933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::OR, VT.getSimpleVT(), Promote); 943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor AddPromotedToType (ISD::OR, VT.getSimpleVT(), 953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor PromotedBitwiseVT.getSimpleVT()); 963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::XOR, VT.getSimpleVT(), Promote); 973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor AddPromotedToType (ISD::XOR, VT.getSimpleVT(), 98a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard PromotedBitwiseVT.getSimpleVT()); 993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 100a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard} 1013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid ARMTargetLowering::addDRTypeForNEON(EVT VT) { 1033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addRegisterClass(VT, ARM::DPRRegisterClass); 10489f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard addTypeForNEON(VT, MVT::f64, MVT::v2i32); 10589f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard} 10689f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard 10789f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillardvoid ARMTargetLowering::addQRTypeForNEON(EVT VT) { 10889f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard addRegisterClass(VT, ARM::QPRRegisterClass); 10989f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard addTypeForNEON(VT, MVT::v2f64, MVT::v4i32); 110c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard} 111c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard 11275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillardstatic TargetLoweringObjectFile *createTLOF(TargetMachine &TM) { 11375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (TM.getSubtarget<ARMSubtarget>().isTargetDarwin()) 11475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return new TargetLoweringObjectFileMachO(); 11575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return new ARMElfTargetObjectFile(); 116f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::ARMTargetLowering(TargetMachine &TM) 1193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor : TargetLowering(TM, createTLOF(TM)), ARMPCLabelIndex(0) { 1203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Subtarget = &TM.getSubtarget<ARMSubtarget>(); 1213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Subtarget->isTargetDarwin()) { 1233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Uses VFP for Thumb libfuncs if available. 1243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Subtarget->isThumb() && Subtarget->hasVFP2()) { 1253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Single-precision floating-point arithmetic. 1263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::ADD_F32, "__addsf3vfp"); 1273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::SUB_F32, "__subsf3vfp"); 1283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::MUL_F32, "__mulsf3vfp"); 1293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::DIV_F32, "__divsf3vfp"); 1303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Double-precision floating-point arithmetic. 1323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::ADD_F64, "__adddf3vfp"); 1333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::SUB_F64, "__subdf3vfp"); 1343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::MUL_F64, "__muldf3vfp"); 1353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::DIV_F64, "__divdf3vfp"); 1363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 137351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard // Single-precision comparisons. 1383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::OEQ_F32, "__eqsf2vfp"); 1393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::UNE_F32, "__nesf2vfp"); 1403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::OLT_F32, "__ltsf2vfp"); 1413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::OLE_F32, "__lesf2vfp"); 1423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::OGE_F32, "__gesf2vfp"); 1433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::OGT_F32, "__gtsf2vfp"); 1443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::UO_F32, "__unordsf2vfp"); 1453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::O_F32, "__unordsf2vfp"); 1463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setCmpLibcallCC(RTLIB::OEQ_F32, ISD::SETNE); 1483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setCmpLibcallCC(RTLIB::UNE_F32, ISD::SETNE); 149f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard setCmpLibcallCC(RTLIB::OLT_F32, ISD::SETNE); 1503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setCmpLibcallCC(RTLIB::OLE_F32, ISD::SETNE); 1513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setCmpLibcallCC(RTLIB::OGE_F32, ISD::SETNE); 1523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setCmpLibcallCC(RTLIB::OGT_F32, ISD::SETNE); 153847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard setCmpLibcallCC(RTLIB::UO_F32, ISD::SETNE); 154a840b69261c44760d45370bef989c77f84727406Daniel Veillard setCmpLibcallCC(RTLIB::O_F32, ISD::SETEQ); 1553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Double-precision comparisons. 1573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::OEQ_F64, "__eqdf2vfp"); 1583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::UNE_F64, "__nedf2vfp"); 1593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::OLT_F64, "__ltdf2vfp"); 1603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::OLE_F64, "__ledf2vfp"); 1613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::OGE_F64, "__gedf2vfp"); 162a2351322c89608d09ce1a99e5eccd62d00c79890Daniel Veillard setLibcallName(RTLIB::OGT_F64, "__gtdf2vfp"); 163f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard setLibcallName(RTLIB::UO_F64, "__unorddf2vfp"); 1643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::O_F64, "__unorddf2vfp"); 1652b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard 1662b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setCmpLibcallCC(RTLIB::OEQ_F64, ISD::SETNE); 1672b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setCmpLibcallCC(RTLIB::UNE_F64, ISD::SETNE); 1682b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setCmpLibcallCC(RTLIB::OLT_F64, ISD::SETNE); 1692b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setCmpLibcallCC(RTLIB::OLE_F64, ISD::SETNE); 1702b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setCmpLibcallCC(RTLIB::OGE_F64, ISD::SETNE); 1712b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setCmpLibcallCC(RTLIB::OGT_F64, ISD::SETNE); 1722b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setCmpLibcallCC(RTLIB::UO_F64, ISD::SETNE); 1732b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setCmpLibcallCC(RTLIB::O_F64, ISD::SETEQ); 1742b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard 1752b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard // Floating-point to integer conversions. 1762b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard // i64 conversions are done via library routines even when generating VFP 1773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // instructions, so use the same ones. 1783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::FPTOSINT_F64_I32, "__fixdfsivfp"); 17956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard setLibcallName(RTLIB::FPTOUINT_F64_I32, "__fixunsdfsivfp"); 1803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::FPTOSINT_F32_I32, "__fixsfsivfp"); 1813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::FPTOUINT_F32_I32, "__fixunssfsivfp"); 1823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Conversions between floating types. 1843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::FPROUND_F64_F32, "__truncdfsf2vfp"); 1853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::FPEXT_F32_F64, "__extendsfdf2vfp"); 1863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 187de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // Integer to floating-point conversions. 1882db8c125be777d642fc1143f23a77d8cf0aa4de1Daniel Veillard // i64 conversions are done via library routines even when generating VFP 1892db8c125be777d642fc1143f23a77d8cf0aa4de1Daniel Veillard // instructions, so use the same ones. 190de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // FIXME: There appears to be some naming inconsistency in ARM libgcc: 191de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // e.g., __floatunsidf vs. __floatunssidfvfp. 192de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard setLibcallName(RTLIB::SINTTOFP_I32_F64, "__floatsidfvfp"); 193de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard setLibcallName(RTLIB::UINTTOFP_I32_F64, "__floatunssidfvfp"); 194de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard setLibcallName(RTLIB::SINTTOFP_I32_F32, "__floatsisfvfp"); 195de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard setLibcallName(RTLIB::UINTTOFP_I32_F32, "__floatunssisfvfp"); 196de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 197de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 198de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 199de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // These libcalls are not available in 32-bit. 200de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard setLibcallName(RTLIB::SHL_I128, 0); 2013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::SRL_I128, 0); 2023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLibcallName(RTLIB::SRA_I128, 0); 2033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Subtarget->isThumb1Only()) 2053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addRegisterClass(MVT::i32, ARM::tGPRRegisterClass); 2063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 2073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addRegisterClass(MVT::i32, ARM::GPRRegisterClass); 2083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) { 2093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addRegisterClass(MVT::f32, ARM::SPRRegisterClass); 2103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addRegisterClass(MVT::f64, ARM::DPRRegisterClass); 2113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setTruncStoreAction(MVT::f64, MVT::f32, Expand); 2133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Subtarget->hasNEON()) { 2163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addDRTypeForNEON(MVT::v2f32); 2173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addDRTypeForNEON(MVT::v8i8); 2183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addDRTypeForNEON(MVT::v4i16); 2193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addDRTypeForNEON(MVT::v2i32); 2203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addDRTypeForNEON(MVT::v1i64); 2213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addQRTypeForNEON(MVT::v4f32); 2233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addQRTypeForNEON(MVT::v2f64); 2243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addQRTypeForNEON(MVT::v16i8); 2253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addQRTypeForNEON(MVT::v8i16); 22629b1748205897f727696b62fdba333efc9671440Daniel Veillard addQRTypeForNEON(MVT::v4i32); 2273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor addQRTypeForNEON(MVT::v2i64); 2283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN); 2303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setTargetDAGCombine(ISD::SHL); 2313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setTargetDAGCombine(ISD::SRL); 2323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setTargetDAGCombine(ISD::SRA); 2333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setTargetDAGCombine(ISD::SIGN_EXTEND); 2343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setTargetDAGCombine(ISD::ZERO_EXTEND); 2353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setTargetDAGCombine(ISD::ANY_EXTEND); 2363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor computeRegisterProperties(); 2393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // ARM does not have f32 extending load. 2413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); 2423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // ARM does not have i1 sign extending load. 2445e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 2453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // ARM supports all 4 flavors of integer indexed load / store. 2473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!Subtarget->isThumb1Only()) { 2483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (unsigned im = (unsigned)ISD::PRE_INC; 2493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) { 2503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIndexedLoadAction(im, MVT::i1, Legal); 251744acfffe537ed3922c57d28d8ea304ee9403942Daniel Veillard setIndexedLoadAction(im, MVT::i8, Legal); 2523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIndexedLoadAction(im, MVT::i16, Legal); 253744acfffe537ed3922c57d28d8ea304ee9403942Daniel Veillard setIndexedLoadAction(im, MVT::i32, Legal); 254744acfffe537ed3922c57d28d8ea304ee9403942Daniel Veillard setIndexedStoreAction(im, MVT::i1, Legal); 2553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIndexedStoreAction(im, MVT::i8, Legal); 2563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIndexedStoreAction(im, MVT::i16, Legal); 2573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIndexedStoreAction(im, MVT::i32, Legal); 2583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // i64 operation support. 2623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Subtarget->isThumb1Only()) { 2633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::MUL, MVT::i64, Expand); 2643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::MULHU, MVT::i32, Expand); 2653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::MULHS, MVT::i32, Expand); 2663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); 2673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); 2683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 2693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::MUL, MVT::i64, Expand); 2703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::MULHU, MVT::i32, Expand); 2713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!Subtarget->hasV6Ops()) 2723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::MULHS, MVT::i32, Expand); 2733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 274015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); 275015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); 276015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); 277015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::SRL, MVT::i64, Custom); 2783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SRA, MVT::i64, Custom); 2793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // ARM does not have ROTL. 2813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::ROTL, MVT::i32, Expand); 2823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::CTTZ, MVT::i32, Expand); 2833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::CTPOP, MVT::i32, Expand); 2843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) 2853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::CTLZ, MVT::i32, Expand); 2863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Only ARMv6 has BSWAP. 2883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!Subtarget->hasV6Ops()) 2893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::BSWAP, MVT::i32, Expand); 290351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard 291351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard // These are expanded into libcalls. 292351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard setOperationAction(ISD::SDIV, MVT::i32, Expand); 293351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard setOperationAction(ISD::UDIV, MVT::i32, Expand); 2943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SREM, MVT::i32, Expand); 295de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard setOperationAction(ISD::UREM, MVT::i32, Expand); 296015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::SDIVREM, MVT::i32, Expand); 297015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::UDIVREM, MVT::i32, Expand); 298015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack 299de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // Support label based line numbers. 300015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand); 301015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); 302015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack 3033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 304015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::ConstantPool, MVT::i32, Custom); 305015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); 306015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); 307015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack 308015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack // Use the default implementation. 309015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::VASTART, MVT::Other, Custom); 310015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::VAARG, MVT::Other, Expand); 311351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard setOperationAction(ISD::VACOPY, MVT::Other, Expand); 312351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard setOperationAction(ISD::VAEND, MVT::Other, Expand); 313015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); 314015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); 315015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::EHSELECTION, MVT::i32, Expand); 316015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack // FIXME: Shouldn't need this, since no register is used, but the legalizer 3173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // doesn't yet know how to not do that for SjLj. 3183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setExceptionSelectorRegister(ARM::R0); 3193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Subtarget->isThumb()) 3203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); 3213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 3223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); 3233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); 3243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!Subtarget->hasV6Ops() && !Subtarget->isThumb2()) { 3263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); 3273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand); 3283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 3293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 3303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 331015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) 3323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Turn f64->i64 into FMRRD, i64 -> f64 to FMDRR iff target supports vfp2. 3333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::BIT_CONVERT, MVT::i64, Custom); 3343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // We want to custom lower some of our intrinsics. 3363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 337015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); 338015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); 3393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SETCC, MVT::i32, Expand); 3413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SETCC, MVT::f32, Expand); 3423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SETCC, MVT::f64, Expand); 3433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SELECT, MVT::i32, Expand); 3443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SELECT, MVT::f32, Expand); 3453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SELECT, MVT::f64, Expand); 3463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 3473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 348de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); 349015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack 350015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::BRCOND, MVT::Other, Expand); 351015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::BR_CC, MVT::i32, Custom); 352015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::BR_CC, MVT::f32, Custom); 353015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::BR_CC, MVT::f64, Custom); 354015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::BR_JT, MVT::Other, Custom); 355015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack 3563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // We don't support sin/cos/fmod/copysign/pow 357015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::FSIN, MVT::f64, Expand); 358015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::FSIN, MVT::f32, Expand); 359015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::FCOS, MVT::f32, Expand); 360015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::FCOS, MVT::f64, Expand); 361015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::FREM, MVT::f64, Expand); 362015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack setOperationAction(ISD::FREM, MVT::f32, Expand); 3633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) { 3643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); 3653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); 3663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 3673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::FPOW, MVT::f64, Expand); 3683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::FPOW, MVT::f32, Expand); 3693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // int <-> fp are custom expanded into bit_convert + ARMISD ops. 3713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) { 3723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); 3733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom); 3743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); 3753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); 3763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 3773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // We have target-specific dag combine patterns for the following nodes: 3792b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard // ARMISD::FMRRD - No need to call setTargetDAGCombine 3802b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setTargetDAGCombine(ISD::ADD); 3812b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard setTargetDAGCombine(ISD::SUB); 3822b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard 3833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setStackPointerRegisterToSaveRestore(ARM::SP); 3843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setSchedulingPreference(SchedulingForRegPressure); 3853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIfCvtBlockSizeLimit(Subtarget->isThumb() ? 0 : 10); 3863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIfCvtDupBlockSizeLimit(Subtarget->isThumb() ? 0 : 2); 3873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 388f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (!Subtarget->isThumb()) { 3893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Use branch latency information to determine if-conversion limits. 390cacbe5d110d469463edb0dd8e11e493daaf3dbc4Daniel Veillard // FIXME: If-converter should use instruction latency of the branch being 3913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // eliminated to compute the threshold. For ARMv6, the branch "latency" 3923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // varies depending on whether it's dynamically or statically predicted 3933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // and on whether the destination is in the prefetch buffer. 3943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 3953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const InstrItineraryData &InstrItins = Subtarget->getInstrItineraryData(); 3963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned Latency= InstrItins.getLatency(TII->get(ARM::Bcc).getSchedClass()); 3973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Latency > 1) { 3983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIfCvtBlockSizeLimit(Latency-1); 3993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Latency > 2) 4003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIfCvtDupBlockSizeLimit(Latency-2); 4013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 4023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIfCvtBlockSizeLimit(10); 4033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor setIfCvtDupBlockSizeLimit(2); 4043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor maxStoresPerMemcpy = 1; //// temporary - rewrite interface to use type 408351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard // Do not enable CodePlacementOpt for now: it currently runs after the 4093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // ARMConstantIslandPass and messes up branch relaxation and placement 4103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // of constant islands. 4113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // benefitFromCodePlacementOpt = true; 412847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard} 413a840b69261c44760d45370bef989c77f84727406Daniel Veillard 4143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { 4153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (Opcode) { 4163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: return 0; 4173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::Wrapper: return "ARMISD::Wrapper"; 4183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::WrapperJT: return "ARMISD::WrapperJT"; 4193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::CALL: return "ARMISD::CALL"; 4203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED"; 4213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK"; 4223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::tCALL: return "ARMISD::tCALL"; 4233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::BRCOND: return "ARMISD::BRCOND"; 4243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::BR_JT: return "ARMISD::BR_JT"; 4253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::BR2_JT: return "ARMISD::BR2_JT"; 4263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG"; 427f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD"; 4283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::CMP: return "ARMISD::CMP"; 4293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::CMPZ: return "ARMISD::CMPZ"; 430f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::CMPFP: return "ARMISD::CMPFP"; 431f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::CMPFPw0: return "ARMISD::CMPFPw0"; 432f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::FMSTAT: return "ARMISD::FMSTAT"; 433f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::CMOV: return "ARMISD::CMOV"; 434f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::CNEG: return "ARMISD::CNEG"; 435f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 436f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::FTOSI: return "ARMISD::FTOSI"; 437f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::FTOUI: return "ARMISD::FTOUI"; 438f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::SITOF: return "ARMISD::SITOF"; 4393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::UITOF: return "ARMISD::UITOF"; 4403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 441f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::SRL_FLAG: return "ARMISD::SRL_FLAG"; 442ba6db03c40b3ac223695fe08e96744ab389c6dabDaniel Veillard case ARMISD::SRA_FLAG: return "ARMISD::SRA_FLAG"; 443f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::RRX: return "ARMISD::RRX"; 444ba6db03c40b3ac223695fe08e96744ab389c6dabDaniel Veillard 445f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::FMRRD: return "ARMISD::FMRRD"; 4462b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard case ARMISD::FMDRR: return "ARMISD::FMDRR"; 447f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 448f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::THREAD_POINTER:return "ARMISD::THREAD_POINTER"; 449f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 450f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::DYN_ALLOC: return "ARMISD::DYN_ALLOC"; 451f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 452f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VCEQ: return "ARMISD::VCEQ"; 453f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VCGE: return "ARMISD::VCGE"; 454f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VCGEU: return "ARMISD::VCGEU"; 455f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VCGT: return "ARMISD::VCGT"; 456f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VCGTU: return "ARMISD::VCGTU"; 457f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VTST: return "ARMISD::VTST"; 458f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 459f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VSHL: return "ARMISD::VSHL"; 460f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VSHRs: return "ARMISD::VSHRs"; 461f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VSHRu: return "ARMISD::VSHRu"; 462f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VSHLLs: return "ARMISD::VSHLLs"; 463f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VSHLLu: return "ARMISD::VSHLLu"; 464f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VSHLLi: return "ARMISD::VSHLLi"; 465f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VSHRN: return "ARMISD::VSHRN"; 466f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VRSHRs: return "ARMISD::VRSHRs"; 467f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VRSHRu: return "ARMISD::VRSHRu"; 46856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard case ARMISD::VRSHRN: return "ARMISD::VRSHRN"; 4693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VQSHLs: return "ARMISD::VQSHLs"; 470f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VQSHLu: return "ARMISD::VQSHLu"; 471f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ARMISD::VQSHLsu: return "ARMISD::VQSHLsu"; 4723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VQSHRNs: return "ARMISD::VQSHRNs"; 4733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VQSHRNu: return "ARMISD::VQSHRNu"; 4743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VQSHRNsu: return "ARMISD::VQSHRNsu"; 4753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VQRSHRNs: return "ARMISD::VQRSHRNs"; 4763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VQRSHRNu: return "ARMISD::VQRSHRNu"; 4773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VQRSHRNsu: return "ARMISD::VQRSHRNsu"; 4783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VGETLANEu: return "ARMISD::VGETLANEu"; 4793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VGETLANEs: return "ARMISD::VGETLANEs"; 4803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VDUPLANEQ: return "ARMISD::VDUPLANEQ"; 4813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VLD2D: return "ARMISD::VLD2D"; 4823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VLD3D: return "ARMISD::VLD3D"; 4833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VLD4D: return "ARMISD::VLD4D"; 4843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VST2D: return "ARMISD::VST2D"; 4853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VST3D: return "ARMISD::VST3D"; 4863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ARMISD::VST4D: return "ARMISD::VST4D"; 4873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 4893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// getFunctionAlignment - Return the Log2 alignment of this function. 4913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorunsigned ARMTargetLowering::getFunctionAlignment(const Function *F) const { 4923c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard return getTargetMachine().getSubtarget<ARMSubtarget>().isThumb() ? 1 : 2; 4933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 4942b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard 4953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor//===----------------------------------------------------------------------===// 4963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// Lowering Code 4973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor//===----------------------------------------------------------------------===// 4983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// IntCCToARMCC - Convert a DAG integer condition code to an ARM CC 5003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic ARMCC::CondCodes IntCCToARMCC(ISD::CondCode CC) { 5013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (CC) { 5023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: llvm_unreachable("Unknown condition code!"); 5033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETNE: return ARMCC::NE; 5043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETEQ: return ARMCC::EQ; 5053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETGT: return ARMCC::GT; 5063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETGE: return ARMCC::GE; 5073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETLT: return ARMCC::LT; 5083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETLE: return ARMCC::LE; 5093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETUGT: return ARMCC::HI; 5103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETUGE: return ARMCC::HS; 5113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETULT: return ARMCC::LO; 5123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETULE: return ARMCC::LS; 5133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 514f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 5153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// FPCCToARMCC - Convert a DAG fp condition code to an ARM CC. It 517f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard/// returns true if the operands should be inverted to form the proper 5183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// comparison. 5192b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillardstatic bool FPCCToARMCC(ISD::CondCode CC, ARMCC::CondCodes &CondCode, 520f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ARMCC::CondCodes &CondCode2) { 5213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bool Invert = false; 5223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CondCode2 = ARMCC::AL; 5233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (CC) { 5243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: llvm_unreachable("Unknown FP condition!"); 5253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETEQ: 5263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETOEQ: CondCode = ARMCC::EQ; break; 5273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETGT: 5283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETOGT: CondCode = ARMCC::GT; break; 5293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETGE: 5303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETOGE: CondCode = ARMCC::GE; break; 5313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETOLT: CondCode = ARMCC::MI; break; 5323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETOLE: CondCode = ARMCC::GT; Invert = true; break; 5333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETONE: CondCode = ARMCC::MI; CondCode2 = ARMCC::GT; break; 5343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETO: CondCode = ARMCC::VC; break; 5353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETUO: CondCode = ARMCC::VS; break; 5363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETUEQ: CondCode = ARMCC::EQ; CondCode2 = ARMCC::VS; break; 5373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETUGT: CondCode = ARMCC::HI; break; 5383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETUGE: CondCode = ARMCC::PL; break; 5393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETLT: 5403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETULT: CondCode = ARMCC::LT; break; 5413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETLE: 5423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETULE: CondCode = ARMCC::LE; break; 5433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case ISD::SETNE: 544f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ISD::SETUNE: CondCode = ARMCC::NE; break; 545f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 546f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return Invert; 547f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 548f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 5493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor//===----------------------------------------------------------------------===// 5502b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard// Calling Convention Implementation 551f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard//===----------------------------------------------------------------------===// 5523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include "ARMGenCallingConv.inc" 5543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// APCS f64 is in register pairs, possibly split to stack 5563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool f64AssignAPCS(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 5573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign::LocInfo &LocInfo, 5583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCState &State, bool CanFail) { 5593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor static const unsigned RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 }; 56050f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard 56150f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard // Try to get the first register. 56250f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard if (unsigned Reg = State.AllocateReg(RegList, 4)) 56350f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 56450f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard else { 5653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // For the 2nd half of a v2f64, do not fail. 5663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CanFail) 5673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return false; 5683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Put the whole thing on the stack. 5703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 5713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.AllocateStack(8, 4), 5723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor LocVT, LocInfo)); 5733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return true; 5743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Try to get the second register. 5773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (unsigned Reg = State.AllocateReg(RegList, 4)) 5783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 5793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 5803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 5813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.AllocateStack(4, 4), 5823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor LocVT, LocInfo)); 5833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return true; 5843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 585f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 5863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 5873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign::LocInfo &LocInfo, 5883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ISD::ArgFlagsTy &ArgFlags, 589f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard CCState &State) { 5903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, true)) 5913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return false; 5923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (LocVT == MVT::v2f64 && 5933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor !f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, false)) 5943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return false; 5953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return true; // we handled it 596f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 597f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 598f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard// AAPCS f64 is in aligned register pairs 5993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool f64AssignAAPCS(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 6003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign::LocInfo &LocInfo, 6013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCState &State, bool CanFail) { 6023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor static const unsigned HiRegList[] = { ARM::R0, ARM::R2 }; 6033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor static const unsigned LoRegList[] = { ARM::R1, ARM::R3 }; 6043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned Reg = State.AllocateReg(HiRegList, LoRegList, 2); 6063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Reg == 0) { 6073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // For the 2nd half of a v2f64, do not just fail. 6083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CanFail) 6093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return false; 6103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Put the whole thing on the stack. 6123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 6133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.AllocateStack(8, 8), 6143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor LocVT, LocInfo)); 6153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return true; 6163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned i; 6193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0; i < 2; ++i) 6203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (HiRegList[i] == Reg) 621a840b69261c44760d45370bef989c77f84727406Daniel Veillard break; 622cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard 6233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 6243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i], 6253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor LocVT, LocInfo)); 6263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return true; 6273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 6303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign::LocInfo &LocInfo, 6313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ISD::ArgFlagsTy &ArgFlags, 6323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCState &State) { 6333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, true)) 6343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return false; 6353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (LocVT == MVT::v2f64 && 6363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor !f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, false)) 6373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return false; 6383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return true; // we handled it 6393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool f64RetAssign(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 6423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign::LocInfo &LocInfo, CCState &State) { 6433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor static const unsigned HiRegList[] = { ARM::R0, ARM::R2 }; 6443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor static const unsigned LoRegList[] = { ARM::R1, ARM::R3 }; 6453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned Reg = State.AllocateReg(HiRegList, LoRegList, 2); 6473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Reg == 0) 6483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return false; // we didn't handle it 6493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned i; 6513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0; i < 2; ++i) 6523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (HiRegList[i] == Reg) 6533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 6563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i], 6573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor LocVT, LocInfo)); 6583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return true; 6593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool RetCC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 6623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign::LocInfo &LocInfo, 6633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ISD::ArgFlagsTy &ArgFlags, 6643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCState &State) { 665a840b69261c44760d45370bef989c77f84727406Daniel Veillard if (!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State)) 6663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return false; 6673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (LocVT == MVT::v2f64 && !f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State)) 6683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return false; 6693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return true; // we handled it 6703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 671a840b69261c44760d45370bef989c77f84727406Daniel Veillard 672a840b69261c44760d45370bef989c77f84727406Daniel Veillardstatic bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT, 673a840b69261c44760d45370bef989c77f84727406Daniel Veillard CCValAssign::LocInfo &LocInfo, 674a840b69261c44760d45370bef989c77f84727406Daniel Veillard ISD::ArgFlagsTy &ArgFlags, 675a840b69261c44760d45370bef989c77f84727406Daniel Veillard CCState &State) { 676a840b69261c44760d45370bef989c77f84727406Daniel Veillard return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags, 677a840b69261c44760d45370bef989c77f84727406Daniel Veillard State); 678a840b69261c44760d45370bef989c77f84727406Daniel Veillard} 679a840b69261c44760d45370bef989c77f84727406Daniel Veillard 680a840b69261c44760d45370bef989c77f84727406Daniel Veillard/// CCAssignFnForNode - Selects the correct CCAssignFn for a the 681a840b69261c44760d45370bef989c77f84727406Daniel Veillard/// given CallingConvention value. 682a840b69261c44760d45370bef989c77f84727406Daniel VeillardCCAssignFn *ARMTargetLowering::CCAssignFnForNode(unsigned CC, 683a840b69261c44760d45370bef989c77f84727406Daniel Veillard bool Return, 684a840b69261c44760d45370bef989c77f84727406Daniel Veillard bool isVarArg) const { 685a840b69261c44760d45370bef989c77f84727406Daniel Veillard switch (CC) { 686a840b69261c44760d45370bef989c77f84727406Daniel Veillard default: 687a840b69261c44760d45370bef989c77f84727406Daniel Veillard llvm_unreachable("Unsupported calling convention"); 688a840b69261c44760d45370bef989c77f84727406Daniel Veillard case CallingConv::C: 689a840b69261c44760d45370bef989c77f84727406Daniel Veillard case CallingConv::Fast: 6903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Use target triple & subtarget features to do actual dispatch. 691a840b69261c44760d45370bef989c77f84727406Daniel Veillard if (Subtarget->isAAPCS_ABI()) { 6923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Subtarget->hasVFP2() && 6933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor FloatABIType == FloatABI::Hard && !isVarArg) 6943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); 6953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 696a840b69261c44760d45370bef989c77f84727406Daniel Veillard return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); 697a840b69261c44760d45370bef989c77f84727406Daniel Veillard } else 698a840b69261c44760d45370bef989c77f84727406Daniel Veillard return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); 699a840b69261c44760d45370bef989c77f84727406Daniel Veillard case CallingConv::ARM_AAPCS_VFP: 700a840b69261c44760d45370bef989c77f84727406Daniel Veillard return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); 701a840b69261c44760d45370bef989c77f84727406Daniel Veillard case CallingConv::ARM_AAPCS: 702a840b69261c44760d45370bef989c77f84727406Daniel Veillard return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); 703a840b69261c44760d45370bef989c77f84727406Daniel Veillard case CallingConv::ARM_APCS: 704a840b69261c44760d45370bef989c77f84727406Daniel Veillard return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); 705a840b69261c44760d45370bef989c77f84727406Daniel Veillard } 706a840b69261c44760d45370bef989c77f84727406Daniel Veillard} 707a840b69261c44760d45370bef989c77f84727406Daniel Veillard 708a840b69261c44760d45370bef989c77f84727406Daniel Veillard/// LowerCallResult - Lower the result values of a call into the 709a840b69261c44760d45370bef989c77f84727406Daniel Veillard/// appropriate copies out of appropriate physical registers. 710a840b69261c44760d45370bef989c77f84727406Daniel VeillardSDValue 711a840b69261c44760d45370bef989c77f84727406Daniel VeillardARMTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 712a840b69261c44760d45370bef989c77f84727406Daniel Veillard unsigned CallConv, bool isVarArg, 713a840b69261c44760d45370bef989c77f84727406Daniel Veillard const SmallVectorImpl<ISD::InputArg> &Ins, 714a840b69261c44760d45370bef989c77f84727406Daniel Veillard DebugLoc dl, SelectionDAG &DAG, 7153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SmallVectorImpl<SDValue> &InVals) { 7163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Assign locations to each value returned by this call. 7183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SmallVector<CCValAssign, 16> RVLocs; 7193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 7207e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack RVLocs, *DAG.getContext()); 7217e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack CCInfo.AnalyzeCallResult(Ins, 7227e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack CCAssignFnForNode(CallConv, /* Return*/ true, 7237e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack isVarArg)); 7247e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack 7257e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack // Copy all of the result registers out of their specified physreg. 7267e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack for (unsigned i = 0; i != RVLocs.size(); ++i) { 7277e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack CCValAssign VA = RVLocs[i]; 7287e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack 7293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Val; 7303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (VA.needsCustom()) { 7313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Handle f64 or half of a v2f64. 7323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, 7333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor InFlag); 7343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = Lo.getValue(1); 7353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor InFlag = Lo.getValue(2); 7363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor VA = RVLocs[++i]; // skip ahead to next loc 7373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, 7383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor InFlag); 7393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = Hi.getValue(1); 7403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor InFlag = Hi.getValue(2); 741f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard Val = DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, Lo, Hi); 742f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 743f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (VA.getLocVT() == MVT::v2f64) { 7443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64); 7453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val, 7463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DAG.getConstant(0, MVT::i32)); 7473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor VA = RVLocs[++i]; // skip ahead to next loc 749cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InFlag); 7503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = Lo.getValue(1); 7513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor InFlag = Lo.getValue(2); 7523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor VA = RVLocs[++i]; // skip ahead to next loc 7533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InFlag); 7543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = Hi.getValue(1); 7553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor InFlag = Hi.getValue(2); 7563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Val = DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, Lo, Hi); 7573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val, 7583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DAG.getConstant(1, MVT::i32)); 75956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard } 7603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 7613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(), 7625bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard InFlag); 7635bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard Chain = Val.getValue(1); 7645bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard InFlag = Val.getValue(2); 7653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 767de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard switch (VA.getLocInfo()) { 768de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard default: llvm_unreachable("Unknown loc info!"); 7693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case CCValAssign::Full: break; 770de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard case CCValAssign::BCvt: 771de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Val = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getValVT(), Val); 772de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard break; 773de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 774de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 775de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard InVals.push_back(Val); 776de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 777de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 778de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard return Chain; 779de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard} 780de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 7813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified 7823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// by "Src" to address "Dst" of size "Size". Alignment information is 7833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// specified by the specific parameter attribute. The copy will be passed as 7843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// a byval function parameter. 7852b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard/// Sometimes what we are copying is the end of a larger object, the part that 7863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// does not fit in registers. 7873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic SDValue 7883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorCreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, 7893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ISD::ArgFlagsTy Flags, SelectionDAG &DAG, 7903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl) { 7913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32); 7923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(), 7933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /*AlwaysInline=*/false, NULL, 0, NULL, 0); 7943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 7953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// LowerMemOpCallTo - Store the argument to the stack. 7973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 7983473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::LowerMemOpCallTo(SDValue Chain, 7993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue StackPtr, SDValue Arg, 8003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl, SelectionDAG &DAG, 8013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const CCValAssign &VA, 802254b12607d427687ae5c1bd75fabaf2ca530b65eDaniel Veillard ISD::ArgFlagsTy Flags) { 803254b12607d427687ae5c1bd75fabaf2ca530b65eDaniel Veillard unsigned LocMemOffset = VA.getLocMemOffset(); 804254b12607d427687ae5c1bd75fabaf2ca530b65eDaniel Veillard SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset); 805254b12607d427687ae5c1bd75fabaf2ca530b65eDaniel Veillard PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, PtrOff); 806254b12607d427687ae5c1bd75fabaf2ca530b65eDaniel Veillard if (Flags.isByVal()) { 807254b12607d427687ae5c1bd75fabaf2ca530b65eDaniel Veillard return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, dl); 8083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getStore(Chain, dl, Arg, PtrOff, 8103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor PseudoSourceValue::getStack(), LocMemOffset); 8113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 8123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid ARMTargetLowering::PassF64ArgInRegs(DebugLoc dl, SelectionDAG &DAG, 8143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Chain, SDValue &Arg, 8153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor RegsToPassVector &RegsToPass, 8163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign &VA, CCValAssign &NextVA, 8173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue &StackPtr, 8183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SmallVector<SDValue, 8> &MemOpChains, 8193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ISD::ArgFlagsTy Flags) { 8203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue fmrrd = DAG.getNode(ARMISD::FMRRD, dl, 8222b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard DAG.getVTList(MVT::i32, MVT::i32), Arg); 8233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd)); 8243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NextVA.isRegLoc()) 826254b12607d427687ae5c1bd75fabaf2ca530b65eDaniel Veillard RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1))); 8273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 8283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor assert(NextVA.isMemLoc()); 8293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (StackPtr.getNode() == 0) 830de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); 8313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, fmrrd.getValue(1), 8333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor dl, DAG, NextVA, 8343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Flags)); 8353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8362b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard} 8373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// LowerCall - Lowering a call into a callseq_start <- 8393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// ARMISD:CALL <- callseq_end chain. Also add input and output parameter 8403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// nodes. 8413473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 8423473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, 8433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned CallConv, bool isVarArg, 8443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bool isTailCall, 8453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const SmallVectorImpl<ISD::OutputArg> &Outs, 8463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const SmallVectorImpl<ISD::InputArg> &Ins, 8475bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard DebugLoc dl, SelectionDAG &DAG, 8485bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard SmallVectorImpl<SDValue> &InVals) { 8495bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard 8505bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard // Analyze operands of the call, assigning locations to each operand. 8513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SmallVector<CCValAssign, 16> ArgLocs; 8525bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, 8535bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard *DAG.getContext()); 8543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCInfo.AnalyzeCallOperands(Outs, 8555bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard CCAssignFnForNode(CallConv, /* Return*/ false, 8563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor isVarArg)); 8573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Get a count of how many bytes are to be pushed on the stack. 8592b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard unsigned NumBytes = CCInfo.getNextStackOffset(); 8603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Adjust the stack pointer for the new arguments... 8623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // These operations are automatically eliminated by the prolog/epilog pass 8633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true)); 8642b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard 8653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue StackPtr = DAG.getRegister(ARM::SP, MVT::i32); 8663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor RegsToPassVector RegsToPass; 8683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SmallVector<SDValue, 8> MemOpChains; 8695bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard 8705bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard // Walk the register/memloc assignments, inserting copies/loads. In the case 8715bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard // of tail call optimization, arguments are handled later. 8725bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard for (unsigned i = 0, realArgIdx = 0, e = ArgLocs.size(); 8735bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard i != e; 874c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard ++i, ++realArgIdx) { 8753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign &VA = ArgLocs[i]; 876a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard SDValue Arg = Outs[realArgIdx].Val; 8773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags; 8783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8792b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard // Promote the value if needed. 8803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (VA.getLocInfo()) { 8813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: llvm_unreachable("Unknown loc info!"); 882a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard case CCValAssign::Full: break; 8833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case CCValAssign::SExt: 8842b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 8853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case CCValAssign::ZExt: 8873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case CCValAssign::AExt: 8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 8912b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard break; 892f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case CCValAssign::BCvt: 8933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Arg = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getLocVT(), Arg); 8943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // f64 and v2f64 might be passed in i32 pairs and must be split into pieces 8983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (VA.needsCustom()) { 8993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (VA.getLocVT() == MVT::v2f64) { 9003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Op0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, 9013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DAG.getConstant(0, MVT::i32)); 9023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Op1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, 9033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DAG.getConstant(1, MVT::i32)); 9043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor PassF64ArgInRegs(dl, DAG, Chain, Op0, RegsToPass, 9063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor VA, ArgLocs[++i], StackPtr, MemOpChains, Flags); 9073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor VA = ArgLocs[++i]; // skip ahead to next loc 9093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (VA.isRegLoc()) { 9103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor PassF64ArgInRegs(dl, DAG, Chain, Op1, RegsToPass, 9113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor VA, ArgLocs[++i], StackPtr, MemOpChains, Flags); 9123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 9133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor assert(VA.isMemLoc()); 9142db8c125be777d642fc1143f23a77d8cf0aa4de1Daniel Veillard if (StackPtr.getNode() == 0) 9153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); 91656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard 9175c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Op1, 9183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor dl, DAG, VA, Flags)); 9193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 92056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard } else { 9213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor PassF64ArgInRegs(dl, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i], 9223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor StackPtr, MemOpChains, Flags); 9233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9245c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard } else if (VA.isRegLoc()) { 925de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 926de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } else { 927de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard assert(VA.isMemLoc()); 928de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (StackPtr.getNode() == 0) 929de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); 930560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard 931de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg, 932de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard dl, DAG, VA, Flags)); 933de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 934de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 935de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 936560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard if (!MemOpChains.empty()) 937de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 938de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard &MemOpChains[0], MemOpChains.size()); 939de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 940de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // Build a sequence of copy-to-reg nodes chained together with token chain 941de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // and flag operands which copy the outgoing args into the appropriate regs. 942de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard SDValue InFlag; 943de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 944de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 945de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard RegsToPass[i].second, InFlag); 9462b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard InFlag = Chain.getValue(1); 947de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 948de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 949de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every 950de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol 9513dc93a42432cbf6e40d4ac3a4e61152d86a9f7ddDaniel Veillard // node so that legalize doesn't hack it. 952de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard bool isDirect = false; 9538e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard bool isARMFunc = false; 9548e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard bool isLocalARMFunc = false; 9558e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { 9568e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard GlobalValue *GV = G->getGlobal(); 9578e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard isDirect = true; 958de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard bool isExt = GV->isDeclaration() || GV->isWeakForLinker(); 959de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard bool isStub = (isExt && Subtarget->isTargetDarwin()) && 960de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard getTargetMachine().getRelocationModel() != Reloc::Static; 961de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard isARMFunc = !Subtarget->isThumb() || isStub; 9623dc93a42432cbf6e40d4ac3a4e61152d86a9f7ddDaniel Veillard // ARM call to a local ARM function is predicable. 9638e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard isLocalARMFunc = !Subtarget->isThumb() && !isExt; 9648e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard // tBX takes a register source operand. 9658e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) { 9668e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex, 9678e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard ARMCP::CPStub, 4); 968de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); 969de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); 970de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Callee = DAG.getLoad(getPointerTy(), dl, 971de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard DAG.getEntryNode(), CPAddr, NULL, 0); 972de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); 973de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Callee = DAG.getNode(ARMISD::PIC_ADD, dl, 974de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard getPointerTy(), Callee, PICLabel); 975de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } else 976de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Callee = DAG.getTargetGlobalAddress(GV, getPointerTy()); 977de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { 978de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard isDirect = true; 979de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard bool isStub = Subtarget->isTargetDarwin() && 9803dc93a42432cbf6e40d4ac3a4e61152d86a9f7ddDaniel Veillard getTargetMachine().getRelocationModel() != Reloc::Static; 9813dc93a42432cbf6e40d4ac3a4e61152d86a9f7ddDaniel Veillard isARMFunc = !Subtarget->isThumb() || isStub; 9823dc93a42432cbf6e40d4ac3a4e61152d86a9f7ddDaniel Veillard // tBX takes a register source operand. 983de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard const char *Sym = S->getSymbol(); 9843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) { 985de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard ARMConstantPoolValue *CPV = new ARMConstantPoolValue(Sym, ARMPCLabelIndex, 986de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard ARMCP::CPStub, 4); 987de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); 988de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); 98956b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard Callee = DAG.getLoad(getPointerTy(), dl, 99056b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard DAG.getEntryNode(), CPAddr, NULL, 0); 99156b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); 99256b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard Callee = DAG.getNode(ARMISD::PIC_ADD, dl, 99356b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard getPointerTy(), Callee, PICLabel); 99456b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard } else 99556b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard Callee = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 996de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 997de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 998de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // FIXME: handle tail calls differently. 999de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard unsigned CallOpc; 1000de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (Subtarget->isThumb()) { 1001de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if ((!isDirect || isARMFunc) && !Subtarget->hasV5TOps()) 1002de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard CallOpc = ARMISD::CALL_NOLINK; 1003de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard else 1004de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard CallOpc = isARMFunc ? ARMISD::CALL : ARMISD::tCALL; 1005de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } else { 1006de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard CallOpc = (isDirect || Subtarget->hasV5TOps()) 1007de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard ? (isLocalARMFunc ? ARMISD::CALL_PRED : ARMISD::CALL) 1008de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard : ARMISD::CALL_NOLINK; 1009de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1010de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (CallOpc == ARMISD::CALL_NOLINK && !Subtarget->isThumb1Only()) { 1011de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // implicit def LR - LR mustn't be allocated as GRP:$dst of CALL_NOLINK 1012de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Chain = DAG.getCopyToReg(Chain, dl, ARM::LR, DAG.getUNDEF(MVT::i32),InFlag); 1013de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard InFlag = Chain.getValue(1); 1014de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1015de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1016de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard std::vector<SDValue> Ops; 1017de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Ops.push_back(Chain); 1018de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Ops.push_back(Callee); 1019de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1020de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // Add argument registers to the end of the list so that they are known live 1021de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // into the call. 10222b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 10235c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard Ops.push_back(DAG.getRegister(RegsToPass[i].first, 10242b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard RegsToPass[i].second.getValueType())); 10255c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard 1026de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (InFlag.getNode()) 1027de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Ops.push_back(InFlag); 10285c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard // Returns a chain and a flag for retval copy to use. 1029de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Flag), 1030de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard &Ops[0], Ops.size()); 1031de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard InFlag = Chain.getValue(1); 10328e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard 10338e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), 10348e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard DAG.getIntPtrConstant(0, true), InFlag); 10358e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard if (!Ins.empty()) 1036de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard InFlag = Chain.getValue(1); 1037de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1038de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // Handle result values, copying them out of physregs into vregs that we 1039de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // return. 1040de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, 10413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor dl, DAG, InVals); 1042de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard} 1043de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 10448e2c9792e923c95a4d353cbc0bb1146413b60168Daniel VeillardSDValue 10458e2c9792e923c95a4d353cbc0bb1146413b60168Daniel VeillardARMTargetLowering::LowerReturn(SDValue Chain, 10468e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard unsigned CallConv, bool isVarArg, 10478e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard const SmallVectorImpl<ISD::OutputArg> &Outs, 1048de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard DebugLoc dl, SelectionDAG &DAG) { 1049de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1050de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // CCValAssign - represent the assignment of the return value to a location. 1051de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard SmallVector<CCValAssign, 16> RVLocs; 1052de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1053de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // CCState - Info about the registers and stack slots. 1054de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, 1055de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard *DAG.getContext()); 10563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1057de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // Analyze outgoing return values. 1058de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard CCInfo.AnalyzeReturn(Outs, CCAssignFnForNode(CallConv, /* Return */ true, 1059de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard isVarArg)); 1060de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1061de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard // If this is the first return lowered for this function, add 10623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // the regs to the liveout set for the function. 10633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 10645c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard for (unsigned i = 0; i != RVLocs.size(); ++i) 10655c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard if (RVLocs[i].isRegLoc()) 10663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 10675c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard } 10683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Flag; 10703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Copy the result values into the output registers. 10723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (unsigned i = 0, realRVLocIdx = 0; 10733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor i != RVLocs.size(); 10743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ++i, ++realRVLocIdx) { 10753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCValAssign &VA = RVLocs[i]; 10763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor assert(VA.isRegLoc() && "Can only return in registers!"); 10773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Arg = Outs[realRVLocIdx].Val; 10793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (VA.getLocInfo()) { 10813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: llvm_unreachable("Unknown loc info!"); 10823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case CCValAssign::Full: break; 10833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case CCValAssign::BCvt: 10843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Arg = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getLocVT(), Arg); 10853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 10863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1087f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 10889403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (VA.needsCustom()) { 10899403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (VA.getLocVT() == MVT::v2f64) { 10909403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard // Extract the first half and return it in two registers. 10919403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard SDValue Half = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, 10929403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard DAG.getConstant(0, MVT::i32)); 10939403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard SDValue HalfGPRs = DAG.getNode(ARMISD::FMRRD, dl, 10949403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard DAG.getVTList(MVT::i32, MVT::i32), Half); 1095cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard 10969403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), HalfGPRs, Flag); 10979403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard Flag = Chain.getValue(1); 10989403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard VA = RVLocs[++i]; // skip ahead to next loc 10999403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 11009403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard HalfGPRs.getValue(1), Flag); 11019403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard Flag = Chain.getValue(1); 11029403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard VA = RVLocs[++i]; // skip ahead to next loc 11039403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 11049403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard // Extract the 2nd half and fall through to handle it as an f64 value. 11059403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard Arg = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, 11069403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard DAG.getConstant(1, MVT::i32)); 11079403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard } 1108f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // Legalize ret f64 -> ret 2 x i32. We always have fmrrd if f64 is 11093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // available. 11103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue fmrrd = DAG.getNode(ARMISD::FMRRD, dl, 11113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DAG.getVTList(MVT::i32, MVT::i32), &Arg, 1); 11123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), fmrrd, Flag); 11133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Flag = Chain.getValue(1); 11143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor VA = RVLocs[++i]; // skip ahead to next loc 11153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), fmrrd.getValue(1), 11163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Flag); 11173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else 11183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Arg, Flag); 11193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Guarantee that all emitted copies are 11213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // stuck together, avoiding something bad. 11223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Flag = Chain.getValue(1); 11233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 11243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue result; 11263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Flag.getNode()) 11273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor result = DAG.getNode(ARMISD::RET_FLAG, dl, MVT::Other, Chain, Flag); 11283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else // Return Void 11293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor result = DAG.getNode(ARMISD::RET_FLAG, dl, MVT::Other, Chain); 11303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return result; 1132f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 11333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as 11353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is 11363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// one of the above mentioned nodes. It has to be wrapped because otherwise 11373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only 11383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// be used to form addressing mode. These wrapped nodes will be selected 11393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// into MOVi. 11403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) { 11413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor EVT PtrVT = Op.getValueType(); 11423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // FIXME there is no actual debug info here 11433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl = Op.getDebugLoc(); 11443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 11453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Res; 11463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CP->isMachineConstantPoolEntry()) 11473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, 11483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CP->getAlignment()); 11493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 11503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, 11513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CP->getAlignment()); 11523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res); 11533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 11543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// Lower ISD::GlobalTLSAddress using the "general dynamic" model 11563473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 11573473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, 11589403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard SelectionDAG &DAG) { 11593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl = GA->getDebugLoc(); 11603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor EVT PtrVT = getPointerTy(); 11613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; 11623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ARMConstantPoolValue *CPV = 11639403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue, 11643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor PCAdj, "tlsgd", true); 1165cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4); 11663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument); 11673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument, NULL, 0); 11683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Chain = Argument.getValue(1); 11693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); 11713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel); 11729403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 11733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // call __tls_get_addr. 11743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ArgListTy Args; 11753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ArgListEntry Entry; 11769403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard Entry.Node = Argument; 1177f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard Entry.Ty = (const Type *) Type::Int32Ty; 1178f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard Args.push_back(Entry); 11793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // FIXME: is there useful debug info available here? 11803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor std::pair<SDValue, SDValue> CallResult = 1181f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, false, 11823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 0, CallingConv::C, false, /*isReturnValueUsed=*/true, 11833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl); 11843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return CallResult.first; 118578637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack} 118678637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack 118778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack// Lower ISD::GlobalTLSAddress using the "initial exec" or 11883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor// "local exec" model. 11893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 11903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA, 11913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SelectionDAG &DAG) { 11923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor GlobalValue *GV = GA->getGlobal(); 11933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl = GA->getDebugLoc(); 11943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Offset; 11953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Chain = DAG.getEntryNode(); 11963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor EVT PtrVT = getPointerTy(); 11973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Get the Thread Pointer 1198a840b69261c44760d45370bef989c77f84727406Daniel Veillard SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); 11993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (GV->isDeclaration()) { 1201f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // initial exec model 1202f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; 1203f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ARMConstantPoolValue *CPV = 1204f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue, 12053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor PCAdj, "gottpoff", true); 12062b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); 12073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); 12083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, NULL, 0); 12093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = Offset.getValue(1); 12103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); 12122b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel); 12132b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard 12143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, NULL, 0); 12159403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard } else { 12163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // local exec model 12173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ARMConstantPoolValue *CPV = 12183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor new ARMConstantPoolValue(GV, ARMCP::CPValue, "tpoff"); 12193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); 12203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); 12213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, NULL, 0); 12223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // The address of the thread local variable is the add of the thread 12253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // pointer with the offset of the variable. 12263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset); 12273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 12289403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 12293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 12303473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) { 12313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // TODO: implement the "local dynamic" model 12323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor assert(Subtarget->isTargetELF() && 1233f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "TLS not implemented for non-ELF targets"); 12343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op); 1235f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // If the relocation model is PIC, use the "General Dynamic" TLS Model, 1236f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // otherwise use the "Local Exec" TLS Model 1237f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (getTargetMachine().getRelocationModel() == Reloc::PIC_) 12383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return LowerToTLSGeneralDynamicModel(GA, DAG); 1239f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else 12403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return LowerToTLSExecModels(GA, DAG); 12413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1242351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard 1243351f2d6e1ae97775a2458b86cdb110d00332834aDaniel VeillardSDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op, 1244f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SelectionDAG &DAG) { 124582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard EVT PtrVT = getPointerTy(); 1246f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard DebugLoc dl = Op.getDebugLoc(); 1247f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 12482b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard Reloc::Model RelocM = getTargetMachine().getRelocationModel(); 1249f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (RelocM == Reloc::PIC_) { 1250f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard bool UseGOTOFF = GV->hasLocalLinkage() || GV->hasHiddenVisibility(); 1251f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ARMConstantPoolValue *CPV = 1252f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard new ARMConstantPoolValue(GV, ARMCP::CPValue, UseGOTOFF ? "GOTOFF":"GOT"); 1253f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); 12543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); 12553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), 125649cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin CPAddr, NULL, 0); 125749cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin SDValue Chain = Result.getValue(1); 1258f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT); 12593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Result = DAG.getNode(ISD::ADD, dl, PtrVT, Result, GOT); 126049cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin if (!UseGOTOFF) 126149cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin Result = DAG.getLoad(PtrVT, dl, Chain, Result, NULL, 0); 1262f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return Result; 12633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 12643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 4); 126549cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); 1266f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0); 1267351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard } 1268351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard} 1269351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard 127049cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol 127149cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin/// even in non-static mode. 1272f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillardstatic bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) { 1273f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // If symbol visibility is hidden, the extra load is not needed if 127449cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin // the symbol is definitely defined in the current translation unit. 1275f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard bool isDecl = GV->isDeclaration() || GV->hasAvailableExternallyLinkage(); 1276f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage())) 127749cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin return false; 1278f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return RelocM != Reloc::Static && (isDecl || GV->isWeakForLinker()); 12793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 128049cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin 12813473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op, 128249cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin SelectionDAG &DAG) { 1283f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard EVT PtrVT = getPointerTy(); 12843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl = Op.getDebugLoc(); 12853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 12863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Reloc::Model RelocM = getTargetMachine().getRelocationModel(); 12873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bool IsIndirect = GVIsIndirectSymbol(GV, RelocM); 12883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue CPAddr; 12893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (RelocM == Reloc::Static) 12903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 4); 12913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 12923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned PCAdj = (RelocM != Reloc::PIC_) 1293f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ? 0 : (Subtarget->isThumb() ? 4 : 8); 1294f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ARMCP::ARMCPKind Kind = IsIndirect ? ARMCP::CPNonLazyPtr 129578637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack : ARMCP::CPValue; 1296f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex, 1297f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard Kind, PCAdj); 1298f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); 1299f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1300f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); 1301f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 130278637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0); 130378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack SDValue Chain = Result.getValue(1); 1304f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1305f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (RelocM == Reloc::PIC_) { 1306f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); 130778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); 1308f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1309f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (IsIndirect) 1310f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard Result = DAG.getLoad(PtrVT, dl, Chain, Result, NULL, 0); 1311f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1312f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return Result; 1313f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 1314f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1315f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel VeillardSDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, 131678637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack SelectionDAG &DAG){ 131778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack assert(Subtarget->isTargetELF() && 1318f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "GLOBAL OFFSET TABLE not implemented for non-ELF targets"); 1319f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard EVT PtrVT = getPointerTy(); 1320f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard DebugLoc dl = Op.getDebugLoc(); 13213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; 13223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ARMConstantPoolValue *CPV = new ARMConstantPoolValue("_GLOBAL_OFFSET_TABLE_", 13233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ARMPCLabelIndex, 13243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ARMCP::CPValue, PCAdj); 13253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); 13263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); 13273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0); 13283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); 13293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); 13303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic SDValue LowerNeonVLDIntrinsic(SDValue Op, SelectionDAG &DAG, 13333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned Opcode) { 13343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDNode *Node = Op.getNode(); 13353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor EVT VT = Node->getValueType(0); 13363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl = Op.getDebugLoc(); 13373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!VT.is64BitVector()) 13393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return SDValue(); // unimplemented 13403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Ops[] = { Node->getOperand(0), 13423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Node->getOperand(2) }; 13433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getNode(Opcode, dl, Node->getVTList(), Ops, 2); 13443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1345f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic SDValue LowerNeonVSTIntrinsic(SDValue Op, SelectionDAG &DAG, 13473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned Opcode, unsigned NumVecs) { 13489403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard SDNode *Node = Op.getNode(); 13499403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard EVT VT = Node->getOperand(3).getValueType(); 13503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl = Op.getDebugLoc(); 13513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!VT.is64BitVector()) 13533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return SDValue(); // unimplemented 13543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13559403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard SmallVector<SDValue, 6> Ops; 13563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Ops.push_back(Node->getOperand(0)); 13573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Ops.push_back(Node->getOperand(2)); 1358f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard for (unsigned N = 0; N < NumVecs; ++N) 13593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Ops.push_back(Node->getOperand(N + 3)); 13603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getNode(Opcode, dl, MVT::Other, Ops.data(), Ops.size()); 13613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 13643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) { 13653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 13663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (IntNo) { 13673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case Intrinsic::arm_neon_vld2: 13683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return LowerNeonVLDIntrinsic(Op, DAG, ARMISD::VLD2D); 13693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case Intrinsic::arm_neon_vld3: 13709403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard return LowerNeonVLDIntrinsic(Op, DAG, ARMISD::VLD3D); 13719403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard case Intrinsic::arm_neon_vld4: 13729403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard return LowerNeonVLDIntrinsic(Op, DAG, ARMISD::VLD4D); 13739403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard case Intrinsic::arm_neon_vst2: 13749403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard return LowerNeonVSTIntrinsic(Op, DAG, ARMISD::VST2D, 2); 13759403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard case Intrinsic::arm_neon_vst3: 13769403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard return LowerNeonVSTIntrinsic(Op, DAG, ARMISD::VST3D, 3); 13779403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard case Intrinsic::arm_neon_vst4: 13789403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard return LowerNeonVSTIntrinsic(Op, DAG, ARMISD::VST4D, 4); 13793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: return SDValue(); // Don't custom lower most intrinsics. 13803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 13843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) { 13853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 13863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl = Op.getDebugLoc(); 13873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (IntNo) { 13883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: return SDValue(); // Don't custom lower most intrinsics. 13893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case Intrinsic::arm_thread_pointer: { 13903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); 13913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); 13923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case Intrinsic::eh_sjlj_lsda: { 13949403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard // blah. horrible, horrible hack with the forced magic name. 13959403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard // really need to clean this up. It belongs in the target-independent 13969403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard // layer somehow that doesn't require the coupling with the asm 13979403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard // printer. 13989403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard MachineFunction &MF = DAG.getMachineFunction(); 13999403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard EVT PtrVT = getPointerTy(); 1400cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard DebugLoc dl = Op.getDebugLoc(); 14019403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard Reloc::Model RelocM = getTargetMachine().getRelocationModel(); 14029403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard SDValue CPAddr; 14039403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard unsigned PCAdj = (RelocM != Reloc::PIC_) 14049403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard ? 0 : (Subtarget->isThumb() ? 4 : 8); 14059403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard ARMCP::ARMCPKind Kind = ARMCP::CPValue; 14069403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard // Save off the LSDA name for the AsmPrinter to use when it's time 14079403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard // to emit the table 14089403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard std::string LSDAName = "L_lsda_"; 14099403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard LSDAName += MF.getFunction()->getName(); 14109403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard ARMConstantPoolValue *CPV = 14119403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard new ARMConstantPoolValue(LSDAName.c_str(), ARMPCLabelIndex, Kind, PCAdj); 1412f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); 14139403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); 1414f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SDValue Result = 14159403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0); 14169403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard SDValue Chain = Result.getValue(1); 14179403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 14183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (RelocM == Reloc::PIC_) { 14193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); 14203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); 14213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return Result; 14233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case Intrinsic::eh_sjlj_setjmp: 14253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32, Op.getOperand(1)); 14263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 14283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, 14303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned VarArgsFrameIndex) { 14313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // vastart just stores the address of the VarArgsFrameIndex slot into the 1432f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // memory location argument. 1433f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard DebugLoc dl = Op.getDebugLoc(); 14343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); 14353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); 14363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 1437015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0); 14383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 14393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 14413473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) { 14423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDNode *Node = Op.getNode(); 14433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl = Node->getDebugLoc(); 14443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor EVT VT = Node->getValueType(0); 14453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Chain = Op.getOperand(0); 14463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Size = Op.getOperand(1); 14473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Align = Op.getOperand(2); 14483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Chain the dynamic stack allocation so that it doesn't modify the stack 14503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // pointer when other instructions are using the stack. 14513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, true)); 14523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned AlignVal = cast<ConstantSDNode>(Align)->getZExtValue(); 14543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned StackAlign = getTargetMachine().getFrameInfo()->getStackAlignment(); 1455f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (AlignVal > StackAlign) 1456f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // Do this now since selection pass cannot introduce new target 14573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // independent node. 14583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Align = DAG.getConstant(-(uint64_t)AlignVal, VT); 14593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // In Thumb1 mode, there isn't a "sub r, sp, r" instruction, we will end up 14613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // using a "add r, sp, r" instead. Negate the size now so we don't have to 14623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // do even more horrible hack later. 14633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor MachineFunction &MF = DAG.getMachineFunction(); 14643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 1465a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard if (AFI->isThumb1OnlyFunction()) { 14663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bool Negate = true; 14673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ConstantSDNode *C = dyn_cast<ConstantSDNode>(Size); 14683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (C) { 14693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor uint32_t Val = C->getZExtValue(); 14703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Val <= 508 && ((Val & 3) == 0)) 14713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Negate = false; 14723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Negate) 14743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Size = DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, VT), Size); 14753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDVTList VTList = DAG.getVTList(VT, MVT::Other); 1478e392497e4c4313382c3c20903d09a69f0948f721Daniel Veillard SDValue Ops1[] = { Chain, Size, Align }; 14793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Res = DAG.getNode(ARMISD::DYN_ALLOC, dl, VTList, Ops1, 3); 14803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = Res.getValue(1); 14813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true), 1482015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack DAG.getIntPtrConstant(0, true), SDValue()); 14833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Ops2[] = { Res, Chain }; 14843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getMergeValues(Ops2, 2, dl); 14853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 14863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 14883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA, 14893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue &Root, SelectionDAG &DAG, 14903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DebugLoc dl) { 14913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor MachineFunction &MF = DAG.getMachineFunction(); 14923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 14933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1494f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard TargetRegisterClass *RC; 1495f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (AFI->isThumb1OnlyFunction()) 14963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor RC = ARM::tGPRRegisterClass; 14973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 14983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor RC = ARM::GPRRegisterClass; 14993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 150020d823614e9826406cb0f1dbd4dd7fc812694bc3William M. Brack // Transform the arguments stored in physical registers into virtual ones. 15013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); 15023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32); 1503a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard 15043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue ArgValue2; 15053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NextVA.isMemLoc()) { 15063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned ArgSize = NextVA.getLocVT().getSizeInBits()/8; 15073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor MachineFrameInfo *MFI = MF.getFrameInfo(); 15083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int FI = MFI->CreateFixedObject(ArgSize, NextVA.getLocMemOffset()); 15095e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard 15105e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard // Create load node to retrieve arguments from the stack. 15113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); 15123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ArgValue2 = DAG.getLoad(MVT::i32, dl, Root, FIN, NULL, 0); 15133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 15143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Reg = MF.addLiveIn(NextVA.getLocReg(), RC); 15153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32); 15163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, ArgValue, ArgValue2); 15193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 15203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15213473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorSDValue 15223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorARMTargetLowering::LowerFormalArguments(SDValue Chain, 15233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned CallConv, bool isVarArg, 15243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const SmallVectorImpl<ISD::InputArg> 15253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor &Ins, 15265e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard DebugLoc dl, SelectionDAG &DAG, 15275e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard SmallVectorImpl<SDValue> &InVals) { 15283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor MachineFunction &MF = DAG.getMachineFunction(); 15303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor MachineFrameInfo *MFI = MF.getFrameInfo(); 15313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 15333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Assign locations to all of the incoming arguments. 15353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SmallVector<CCValAssign, 16> ArgLocs; 15363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, 15373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *DAG.getContext()); 15383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCInfo.AnalyzeFormalArguments(Ins, 15393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CCAssignFnForNode(CallConv, /* Return*/ false, 1540f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard isVarArg)); 154101c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard 1542f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SmallVector<SDValue, 16> ArgValues; 1543f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1544a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 1545a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard CCValAssign &VA = ArgLocs[i]; 1546f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1547f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // Arguments stored in registers. 1548f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (VA.isRegLoc()) { 1549f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard EVT RegVT = VA.getLocVT(); 1550f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1551f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SDValue ArgValue; 155282cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard if (VA.needsCustom()) { 1553f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // f64 and vector types are split up into multiple registers or 1554f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // combinations of registers and stack slots. 1555f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard RegVT = MVT::i32; 1556f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1557f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (VA.getLocVT() == MVT::v2f64) { 1558847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard SDValue ArgValue1 = GetF64FormalArgument(VA, ArgLocs[++i], 1559847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard Chain, DAG, dl); 1560847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard VA = ArgLocs[++i]; // skip ahead to next loc 1561847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard SDValue ArgValue2 = GetF64FormalArgument(VA, ArgLocs[++i], 1562847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard Chain, DAG, dl); 1563847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard ArgValue = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64); 1564847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, 1565847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard ArgValue, ArgValue1, DAG.getIntPtrConstant(0)); 1566847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, 156782cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard ArgValue, ArgValue2, DAG.getIntPtrConstant(1)); 1568847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard } else 1569847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl); 1570847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard 1571847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard } else { 1572847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard TargetRegisterClass *RC; 1573847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard 1574847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard if (RegVT == MVT::f32) 1575847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard RC = ARM::SPRRegisterClass; 1576847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard else if (RegVT == MVT::f64) 1577847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard RC = ARM::DPRRegisterClass; 1578847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard else if (RegVT == MVT::v2f64) 1579847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard RC = ARM::QPRRegisterClass; 1580847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard else if (RegVT == MVT::i32) 1581847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard RC = (AFI->isThumb1OnlyFunction() ? 158282cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard ARM::tGPRRegisterClass : ARM::GPRRegisterClass); 1583847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard else 1584847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard llvm_unreachable("RegVT not supported by FORMAL_ARGUMENTS Lowering"); 1585847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard 1586847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard // Transform the arguments in physical registers into virtual ones. 1587847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); 1588a840b69261c44760d45370bef989c77f84727406Daniel Veillard ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); 1589a840b69261c44760d45370bef989c77f84727406Daniel Veillard } 1590a840b69261c44760d45370bef989c77f84727406Daniel Veillard 1591a840b69261c44760d45370bef989c77f84727406Daniel Veillard // If this is an 8 or 16-bit value, it is really passed promoted 1592a840b69261c44760d45370bef989c77f84727406Daniel Veillard // to 32 bits. Insert an assert[sz]ext to capture this, then 1593a840b69261c44760d45370bef989c77f84727406Daniel Veillard // truncate to the right size. 1594a840b69261c44760d45370bef989c77f84727406Daniel Veillard switch (VA.getLocInfo()) { 1595a840b69261c44760d45370bef989c77f84727406Daniel Veillard default: llvm_unreachable("Unknown loc info!"); 1596a840b69261c44760d45370bef989c77f84727406Daniel Veillard case CCValAssign::Full: break; 159782cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard case CCValAssign::BCvt: 1598a840b69261c44760d45370bef989c77f84727406Daniel Veillard ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getValVT(), ArgValue); 1599a840b69261c44760d45370bef989c77f84727406Daniel Veillard break; 1600a840b69261c44760d45370bef989c77f84727406Daniel Veillard case CCValAssign::SExt: 1601a840b69261c44760d45370bef989c77f84727406Daniel Veillard ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 1602a840b69261c44760d45370bef989c77f84727406Daniel Veillard DAG.getValueType(VA.getValVT())); 160301c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 1604f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard break; 1605f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case CCValAssign::ZExt: 1606f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 1607f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard DAG.getValueType(VA.getValVT())); 1608a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 1609a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard break; 1610f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1611f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1612f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard InVals.push_back(ArgValue); 1613f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1614a2351322c89608d09ce1a99e5eccd62d00c79890Daniel Veillard } else { // VA.isRegLoc() 1615f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 161682cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard // sanity check 1617f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard assert(VA.isMemLoc()); 1618f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard assert(VA.getValVT() != MVT::i64 && "i64 should already be lowered"); 1619f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1620f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard unsigned ArgSize = VA.getLocVT().getSizeInBits()/8; 1621f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int FI = MFI->CreateFixedObject(ArgSize, VA.getLocMemOffset()); 1622f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1623f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // Create load nodes to retrieve arguments from the stack. 1624f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); 1625f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0)); 1626f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1627f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1628f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1629f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // varargs 1630f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (isVarArg) { 1631f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard static const unsigned GPRArgRegs[] = { 1632f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ARM::R0, ARM::R1, ARM::R2, ARM::R3 1633f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard }; 1634f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1635f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard unsigned NumGPRs = CCInfo.getFirstUnallocated 1636f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard (GPRArgRegs, sizeof(GPRArgRegs) / sizeof(GPRArgRegs[0])); 1637f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1638f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 1639f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard unsigned VARegSize = (4 - NumGPRs) * 4; 1640f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard unsigned VARegSaveSize = (VARegSize + Align - 1) & ~(Align - 1); 1641f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard unsigned ArgOffset = 0; 1642f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (VARegSaveSize) { 1643f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // If this function is vararg, store any remaining integer argument regs 1644f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // to their spots on the stack so that they may be loaded by deferencing 1645f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard // the result of va_next. 1646f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard AFI->setVarArgsRegSaveSize(VARegSaveSize); 1647f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ArgOffset = CCInfo.getNextStackOffset(); 1648f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard VarArgsFrameIndex = MFI->CreateFixedObject(VARegSaveSize, ArgOffset + 1649f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard VARegSaveSize - VARegSize); 1650f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy()); 1651f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1652f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard SmallVector<SDValue, 4> MemOps; 1653f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard for (; NumGPRs < 4; ++NumGPRs) { 1654f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard TargetRegisterClass *RC; 1655f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (AFI->isThumb1OnlyFunction()) 1656f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard RC = ARM::tGPRRegisterClass; 1657f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else 1658f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard RC = ARM::GPRRegisterClass; 1659f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 16603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor unsigned VReg = MF.addLiveIn(GPRArgRegs[NumGPRs], RC); 16613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); 16623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); 16633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor MemOps.push_back(Store); 16643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(), FIN, 16653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor DAG.getConstant(4, getPointerTy())); 16663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!MemOps.empty()) 16683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 16693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor &MemOps[0], MemOps.size()); 16703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else 16713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // This will point to the next argument passed via stack. 16723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); 16733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return Chain; 16763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 16773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/// isFloatingPointZero - Return true if this is +0.0. 16793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic bool isFloatingPointZero(SDValue Op) { 16803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op)) 16813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return CFP->getValueAPF().isPosZero(); 16823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) { 16833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor // Maybe this has already been legalized into the constant pool? 16843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) { 16853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SDValue WrapperOp = Op.getOperand(1).getOperand(0); 16863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(WrapperOp)) 16873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal())) 16883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return CFP->getValueAPF().isPosZero(); 16893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16915d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard return false; 16925d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard} 1693 1694static bool isLegalCmpImmediate(unsigned C, bool isThumb1Only) { 1695 return ( isThumb1Only && (C & ~255U) == 0) || 1696 (!isThumb1Only && ARM_AM::getSOImmVal(C) != -1); 1697} 1698 1699/// Returns appropriate ARM CMP (cmp) and corresponding condition code for 1700/// the given operands. 1701static SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, 1702 SDValue &ARMCC, SelectionDAG &DAG, bool isThumb1Only, 1703 DebugLoc dl) { 1704 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) { 1705 unsigned C = RHSC->getZExtValue(); 1706 if (!isLegalCmpImmediate(C, isThumb1Only)) { 1707 // Constant does not fit, try adjusting it by one? 1708 switch (CC) { 1709 default: break; 1710 case ISD::SETLT: 1711 case ISD::SETGE: 1712 if (isLegalCmpImmediate(C-1, isThumb1Only)) { 1713 CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT; 1714 RHS = DAG.getConstant(C-1, MVT::i32); 1715 } 1716 break; 1717 case ISD::SETULT: 1718 case ISD::SETUGE: 1719 if (C > 0 && isLegalCmpImmediate(C-1, isThumb1Only)) { 1720 CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT; 1721 RHS = DAG.getConstant(C-1, MVT::i32); 1722 } 1723 break; 1724 case ISD::SETLE: 1725 case ISD::SETGT: 1726 if (isLegalCmpImmediate(C+1, isThumb1Only)) { 1727 CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE; 1728 RHS = DAG.getConstant(C+1, MVT::i32); 1729 } 1730 break; 1731 case ISD::SETULE: 1732 case ISD::SETUGT: 1733 if (C < 0xffffffff && isLegalCmpImmediate(C+1, isThumb1Only)) { 1734 CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE; 1735 RHS = DAG.getConstant(C+1, MVT::i32); 1736 } 1737 break; 1738 } 1739 } 1740 } 1741 1742 ARMCC::CondCodes CondCode = IntCCToARMCC(CC); 1743 ARMISD::NodeType CompareType; 1744 switch (CondCode) { 1745 default: 1746 CompareType = ARMISD::CMP; 1747 break; 1748 case ARMCC::EQ: 1749 case ARMCC::NE: 1750 // Uses only Z Flag 1751 CompareType = ARMISD::CMPZ; 1752 break; 1753 } 1754 ARMCC = DAG.getConstant(CondCode, MVT::i32); 1755 return DAG.getNode(CompareType, dl, MVT::Flag, LHS, RHS); 1756} 1757 1758/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands. 1759static SDValue getVFPCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG, 1760 DebugLoc dl) { 1761 SDValue Cmp; 1762 if (!isFloatingPointZero(RHS)) 1763 Cmp = DAG.getNode(ARMISD::CMPFP, dl, MVT::Flag, LHS, RHS); 1764 else 1765 Cmp = DAG.getNode(ARMISD::CMPFPw0, dl, MVT::Flag, LHS); 1766 return DAG.getNode(ARMISD::FMSTAT, dl, MVT::Flag, Cmp); 1767} 1768 1769static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG, 1770 const ARMSubtarget *ST) { 1771 EVT VT = Op.getValueType(); 1772 SDValue LHS = Op.getOperand(0); 1773 SDValue RHS = Op.getOperand(1); 1774 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 1775 SDValue TrueVal = Op.getOperand(2); 1776 SDValue FalseVal = Op.getOperand(3); 1777 DebugLoc dl = Op.getDebugLoc(); 1778 1779 if (LHS.getValueType() == MVT::i32) { 1780 SDValue ARMCC; 1781 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); 1782 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMCC, DAG, ST->isThumb1Only(), dl); 1783 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMCC, CCR,Cmp); 1784 } 1785 1786 ARMCC::CondCodes CondCode, CondCode2; 1787 if (FPCCToARMCC(CC, CondCode, CondCode2)) 1788 std::swap(TrueVal, FalseVal); 1789 1790 SDValue ARMCC = DAG.getConstant(CondCode, MVT::i32); 1791 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); 1792 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl); 1793 SDValue Result = DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, 1794 ARMCC, CCR, Cmp); 1795 if (CondCode2 != ARMCC::AL) { 1796 SDValue ARMCC2 = DAG.getConstant(CondCode2, MVT::i32); 1797 // FIXME: Needs another CMP because flag can have but one use. 1798 SDValue Cmp2 = getVFPCmp(LHS, RHS, DAG, dl); 1799 Result = DAG.getNode(ARMISD::CMOV, dl, VT, 1800 Result, TrueVal, ARMCC2, CCR, Cmp2); 1801 } 1802 return Result; 1803} 1804 1805static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG, 1806 const ARMSubtarget *ST) { 1807 SDValue Chain = Op.getOperand(0); 1808 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 1809 SDValue LHS = Op.getOperand(2); 1810 SDValue RHS = Op.getOperand(3); 1811 SDValue Dest = Op.getOperand(4); 1812 DebugLoc dl = Op.getDebugLoc(); 1813 1814 if (LHS.getValueType() == MVT::i32) { 1815 SDValue ARMCC; 1816 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); 1817 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMCC, DAG, ST->isThumb1Only(), dl); 1818 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, 1819 Chain, Dest, ARMCC, CCR,Cmp); 1820 } 1821 1822 assert(LHS.getValueType() == MVT::f32 || LHS.getValueType() == MVT::f64); 1823 ARMCC::CondCodes CondCode, CondCode2; 1824 if (FPCCToARMCC(CC, CondCode, CondCode2)) 1825 // Swap the LHS/RHS of the comparison if needed. 1826 std::swap(LHS, RHS); 1827 1828 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl); 1829 SDValue ARMCC = DAG.getConstant(CondCode, MVT::i32); 1830 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); 1831 SDVTList VTList = DAG.getVTList(MVT::Other, MVT::Flag); 1832 SDValue Ops[] = { Chain, Dest, ARMCC, CCR, Cmp }; 1833 SDValue Res = DAG.getNode(ARMISD::BRCOND, dl, VTList, Ops, 5); 1834 if (CondCode2 != ARMCC::AL) { 1835 ARMCC = DAG.getConstant(CondCode2, MVT::i32); 1836 SDValue Ops[] = { Res, Dest, ARMCC, CCR, Res.getValue(1) }; 1837 Res = DAG.getNode(ARMISD::BRCOND, dl, VTList, Ops, 5); 1838 } 1839 return Res; 1840} 1841 1842SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) { 1843 SDValue Chain = Op.getOperand(0); 1844 SDValue Table = Op.getOperand(1); 1845 SDValue Index = Op.getOperand(2); 1846 DebugLoc dl = Op.getDebugLoc(); 1847 1848 EVT PTy = getPointerTy(); 1849 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table); 1850 ARMFunctionInfo *AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>(); 1851 SDValue UId = DAG.getConstant(AFI->createJumpTableUId(), PTy); 1852 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy); 1853 Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI, UId); 1854 Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, PTy)); 1855 SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table); 1856 if (Subtarget->isThumb2()) { 1857 // Thumb2 uses a two-level jump. That is, it jumps into the jump table 1858 // which does another jump to the destination. This also makes it easier 1859 // to translate it to TBB / TBH later. 1860 // FIXME: This might not work if the function is extremely large. 1861 return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain, 1862 Addr, Op.getOperand(2), JTI, UId); 1863 } 1864 if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { 1865 Addr = DAG.getLoad((EVT)MVT::i32, dl, Chain, Addr, NULL, 0); 1866 Chain = Addr.getValue(1); 1867 Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, Table); 1868 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId); 1869 } else { 1870 Addr = DAG.getLoad(PTy, dl, Chain, Addr, NULL, 0); 1871 Chain = Addr.getValue(1); 1872 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId); 1873 } 1874} 1875 1876static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) { 1877 DebugLoc dl = Op.getDebugLoc(); 1878 unsigned Opc = 1879 Op.getOpcode() == ISD::FP_TO_SINT ? ARMISD::FTOSI : ARMISD::FTOUI; 1880 Op = DAG.getNode(Opc, dl, MVT::f32, Op.getOperand(0)); 1881 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op); 1882} 1883 1884static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) { 1885 EVT VT = Op.getValueType(); 1886 DebugLoc dl = Op.getDebugLoc(); 1887 unsigned Opc = 1888 Op.getOpcode() == ISD::SINT_TO_FP ? ARMISD::SITOF : ARMISD::UITOF; 1889 1890 Op = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, Op.getOperand(0)); 1891 return DAG.getNode(Opc, dl, VT, Op); 1892} 1893 1894static SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) { 1895 // Implement fcopysign with a fabs and a conditional fneg. 1896 SDValue Tmp0 = Op.getOperand(0); 1897 SDValue Tmp1 = Op.getOperand(1); 1898 DebugLoc dl = Op.getDebugLoc(); 1899 EVT VT = Op.getValueType(); 1900 EVT SrcVT = Tmp1.getValueType(); 1901 SDValue AbsVal = DAG.getNode(ISD::FABS, dl, VT, Tmp0); 1902 SDValue Cmp = getVFPCmp(Tmp1, DAG.getConstantFP(0.0, SrcVT), DAG, dl); 1903 SDValue ARMCC = DAG.getConstant(ARMCC::LT, MVT::i32); 1904 SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); 1905 return DAG.getNode(ARMISD::CNEG, dl, VT, AbsVal, AbsVal, ARMCC, CCR, Cmp); 1906} 1907 1908SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { 1909 MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 1910 MFI->setFrameAddressIsTaken(true); 1911 EVT VT = Op.getValueType(); 1912 DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful 1913 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 1914 unsigned FrameReg = (Subtarget->isThumb() || Subtarget->isTargetDarwin()) 1915 ? ARM::R7 : ARM::R11; 1916 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT); 1917 while (Depth--) 1918 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0); 1919 return FrameAddr; 1920} 1921 1922SDValue 1923ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl, 1924 SDValue Chain, 1925 SDValue Dst, SDValue Src, 1926 SDValue Size, unsigned Align, 1927 bool AlwaysInline, 1928 const Value *DstSV, uint64_t DstSVOff, 1929 const Value *SrcSV, uint64_t SrcSVOff){ 1930 // Do repeated 4-byte loads and stores. To be improved. 1931 // This requires 4-byte alignment. 1932 if ((Align & 3) != 0) 1933 return SDValue(); 1934 // This requires the copy size to be a constant, preferrably 1935 // within a subtarget-specific limit. 1936 ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size); 1937 if (!ConstantSize) 1938 return SDValue(); 1939 uint64_t SizeVal = ConstantSize->getZExtValue(); 1940 if (!AlwaysInline && SizeVal > getSubtarget()->getMaxInlineSizeThreshold()) 1941 return SDValue(); 1942 1943 unsigned BytesLeft = SizeVal & 3; 1944 unsigned NumMemOps = SizeVal >> 2; 1945 unsigned EmittedNumMemOps = 0; 1946 EVT VT = MVT::i32; 1947 unsigned VTSize = 4; 1948 unsigned i = 0; 1949 const unsigned MAX_LOADS_IN_LDM = 6; 1950 SDValue TFOps[MAX_LOADS_IN_LDM]; 1951 SDValue Loads[MAX_LOADS_IN_LDM]; 1952 uint64_t SrcOff = 0, DstOff = 0; 1953 1954 // Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the 1955 // same number of stores. The loads and stores will get combined into 1956 // ldm/stm later on. 1957 while (EmittedNumMemOps < NumMemOps) { 1958 for (i = 0; 1959 i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) { 1960 Loads[i] = DAG.getLoad(VT, dl, Chain, 1961 DAG.getNode(ISD::ADD, dl, MVT::i32, Src, 1962 DAG.getConstant(SrcOff, MVT::i32)), 1963 SrcSV, SrcSVOff + SrcOff); 1964 TFOps[i] = Loads[i].getValue(1); 1965 SrcOff += VTSize; 1966 } 1967 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i); 1968 1969 for (i = 0; 1970 i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) { 1971 TFOps[i] = DAG.getStore(Chain, dl, Loads[i], 1972 DAG.getNode(ISD::ADD, dl, MVT::i32, Dst, 1973 DAG.getConstant(DstOff, MVT::i32)), 1974 DstSV, DstSVOff + DstOff); 1975 DstOff += VTSize; 1976 } 1977 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i); 1978 1979 EmittedNumMemOps += i; 1980 } 1981 1982 if (BytesLeft == 0) 1983 return Chain; 1984 1985 // Issue loads / stores for the trailing (1 - 3) bytes. 1986 unsigned BytesLeftSave = BytesLeft; 1987 i = 0; 1988 while (BytesLeft) { 1989 if (BytesLeft >= 2) { 1990 VT = MVT::i16; 1991 VTSize = 2; 1992 } else { 1993 VT = MVT::i8; 1994 VTSize = 1; 1995 } 1996 1997 Loads[i] = DAG.getLoad(VT, dl, Chain, 1998 DAG.getNode(ISD::ADD, dl, MVT::i32, Src, 1999 DAG.getConstant(SrcOff, MVT::i32)), 2000 SrcSV, SrcSVOff + SrcOff); 2001 TFOps[i] = Loads[i].getValue(1); 2002 ++i; 2003 SrcOff += VTSize; 2004 BytesLeft -= VTSize; 2005 } 2006 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i); 2007 2008 i = 0; 2009 BytesLeft = BytesLeftSave; 2010 while (BytesLeft) { 2011 if (BytesLeft >= 2) { 2012 VT = MVT::i16; 2013 VTSize = 2; 2014 } else { 2015 VT = MVT::i8; 2016 VTSize = 1; 2017 } 2018 2019 TFOps[i] = DAG.getStore(Chain, dl, Loads[i], 2020 DAG.getNode(ISD::ADD, dl, MVT::i32, Dst, 2021 DAG.getConstant(DstOff, MVT::i32)), 2022 DstSV, DstSVOff + DstOff); 2023 ++i; 2024 DstOff += VTSize; 2025 BytesLeft -= VTSize; 2026 } 2027 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i); 2028} 2029 2030static SDValue ExpandBIT_CONVERT(SDNode *N, SelectionDAG &DAG) { 2031 SDValue Op = N->getOperand(0); 2032 DebugLoc dl = N->getDebugLoc(); 2033 if (N->getValueType(0) == MVT::f64) { 2034 // Turn i64->f64 into FMDRR. 2035 SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op, 2036 DAG.getConstant(0, MVT::i32)); 2037 SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op, 2038 DAG.getConstant(1, MVT::i32)); 2039 return DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, Lo, Hi); 2040 } 2041 2042 // Turn f64->i64 into FMRRD. 2043 SDValue Cvt = DAG.getNode(ARMISD::FMRRD, dl, 2044 DAG.getVTList(MVT::i32, MVT::i32), &Op, 1); 2045 2046 // Merge the pieces into a single i64 value. 2047 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Cvt, Cvt.getValue(1)); 2048} 2049 2050/// getZeroVector - Returns a vector of specified type with all zero elements. 2051/// 2052static SDValue getZeroVector(EVT VT, SelectionDAG &DAG, DebugLoc dl) { 2053 assert(VT.isVector() && "Expected a vector type"); 2054 2055 // Zero vectors are used to represent vector negation and in those cases 2056 // will be implemented with the NEON VNEG instruction. However, VNEG does 2057 // not support i64 elements, so sometimes the zero vectors will need to be 2058 // explicitly constructed. For those cases, and potentially other uses in 2059 // the future, always build zero vectors as <4 x i32> or <2 x i32> bitcasted 2060 // to their dest type. This ensures they get CSE'd. 2061 SDValue Vec; 2062 SDValue Cst = DAG.getTargetConstant(0, MVT::i32); 2063 if (VT.getSizeInBits() == 64) 2064 Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i32, Cst, Cst); 2065 else 2066 Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, Cst, Cst, Cst, Cst); 2067 2068 return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Vec); 2069} 2070 2071/// getOnesVector - Returns a vector of specified type with all bits set. 2072/// 2073static SDValue getOnesVector(EVT VT, SelectionDAG &DAG, DebugLoc dl) { 2074 assert(VT.isVector() && "Expected a vector type"); 2075 2076 // Always build ones vectors as <4 x i32> or <2 x i32> bitcasted to their dest 2077 // type. This ensures they get CSE'd. 2078 SDValue Vec; 2079 SDValue Cst = DAG.getTargetConstant(~0U, MVT::i32); 2080 if (VT.getSizeInBits() == 64) 2081 Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i32, Cst, Cst); 2082 else 2083 Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, Cst, Cst, Cst, Cst); 2084 2085 return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Vec); 2086} 2087 2088static SDValue LowerShift(SDNode *N, SelectionDAG &DAG, 2089 const ARMSubtarget *ST) { 2090 EVT VT = N->getValueType(0); 2091 DebugLoc dl = N->getDebugLoc(); 2092 2093 // Lower vector shifts on NEON to use VSHL. 2094 if (VT.isVector()) { 2095 assert(ST->hasNEON() && "unexpected vector shift"); 2096 2097 // Left shifts translate directly to the vshiftu intrinsic. 2098 if (N->getOpcode() == ISD::SHL) 2099 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, 2100 DAG.getConstant(Intrinsic::arm_neon_vshiftu, MVT::i32), 2101 N->getOperand(0), N->getOperand(1)); 2102 2103 assert((N->getOpcode() == ISD::SRA || 2104 N->getOpcode() == ISD::SRL) && "unexpected vector shift opcode"); 2105 2106 // NEON uses the same intrinsics for both left and right shifts. For 2107 // right shifts, the shift amounts are negative, so negate the vector of 2108 // shift amounts. 2109 EVT ShiftVT = N->getOperand(1).getValueType(); 2110 SDValue NegatedCount = DAG.getNode(ISD::SUB, dl, ShiftVT, 2111 getZeroVector(ShiftVT, DAG, dl), 2112 N->getOperand(1)); 2113 Intrinsic::ID vshiftInt = (N->getOpcode() == ISD::SRA ? 2114 Intrinsic::arm_neon_vshifts : 2115 Intrinsic::arm_neon_vshiftu); 2116 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, 2117 DAG.getConstant(vshiftInt, MVT::i32), 2118 N->getOperand(0), NegatedCount); 2119 } 2120 2121 assert(VT == MVT::i64 && 2122 (N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) && 2123 "Unknown shift to lower!"); 2124 2125 // We only lower SRA, SRL of 1 here, all others use generic lowering. 2126 if (!isa<ConstantSDNode>(N->getOperand(1)) || 2127 cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() != 1) 2128 return SDValue(); 2129 2130 // If we are in thumb mode, we don't have RRX. 2131 if (ST->isThumb1Only()) return SDValue(); 2132 2133 // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr. 2134 SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), 2135 DAG.getConstant(0, MVT::i32)); 2136 SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), 2137 DAG.getConstant(1, MVT::i32)); 2138 2139 // First, build a SRA_FLAG/SRL_FLAG op, which shifts the top part by one and 2140 // captures the result into a carry flag. 2141 unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::SRL_FLAG:ARMISD::SRA_FLAG; 2142 Hi = DAG.getNode(Opc, dl, DAG.getVTList(MVT::i32, MVT::Flag), &Hi, 1); 2143 2144 // The low part is an ARMISD::RRX operand, which shifts the carry in. 2145 Lo = DAG.getNode(ARMISD::RRX, dl, MVT::i32, Lo, Hi.getValue(1)); 2146 2147 // Merge the pieces into a single i64 value. 2148 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 2149} 2150 2151static SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG) { 2152 SDValue TmpOp0, TmpOp1; 2153 bool Invert = false; 2154 bool Swap = false; 2155 unsigned Opc = 0; 2156 2157 SDValue Op0 = Op.getOperand(0); 2158 SDValue Op1 = Op.getOperand(1); 2159 SDValue CC = Op.getOperand(2); 2160 EVT VT = Op.getValueType(); 2161 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get(); 2162 DebugLoc dl = Op.getDebugLoc(); 2163 2164 if (Op.getOperand(1).getValueType().isFloatingPoint()) { 2165 switch (SetCCOpcode) { 2166 default: llvm_unreachable("Illegal FP comparison"); break; 2167 case ISD::SETUNE: 2168 case ISD::SETNE: Invert = true; // Fallthrough 2169 case ISD::SETOEQ: 2170 case ISD::SETEQ: Opc = ARMISD::VCEQ; break; 2171 case ISD::SETOLT: 2172 case ISD::SETLT: Swap = true; // Fallthrough 2173 case ISD::SETOGT: 2174 case ISD::SETGT: Opc = ARMISD::VCGT; break; 2175 case ISD::SETOLE: 2176 case ISD::SETLE: Swap = true; // Fallthrough 2177 case ISD::SETOGE: 2178 case ISD::SETGE: Opc = ARMISD::VCGE; break; 2179 case ISD::SETUGE: Swap = true; // Fallthrough 2180 case ISD::SETULE: Invert = true; Opc = ARMISD::VCGT; break; 2181 case ISD::SETUGT: Swap = true; // Fallthrough 2182 case ISD::SETULT: Invert = true; Opc = ARMISD::VCGE; break; 2183 case ISD::SETUEQ: Invert = true; // Fallthrough 2184 case ISD::SETONE: 2185 // Expand this to (OLT | OGT). 2186 TmpOp0 = Op0; 2187 TmpOp1 = Op1; 2188 Opc = ISD::OR; 2189 Op0 = DAG.getNode(ARMISD::VCGT, dl, VT, TmpOp1, TmpOp0); 2190 Op1 = DAG.getNode(ARMISD::VCGT, dl, VT, TmpOp0, TmpOp1); 2191 break; 2192 case ISD::SETUO: Invert = true; // Fallthrough 2193 case ISD::SETO: 2194 // Expand this to (OLT | OGE). 2195 TmpOp0 = Op0; 2196 TmpOp1 = Op1; 2197 Opc = ISD::OR; 2198 Op0 = DAG.getNode(ARMISD::VCGT, dl, VT, TmpOp1, TmpOp0); 2199 Op1 = DAG.getNode(ARMISD::VCGE, dl, VT, TmpOp0, TmpOp1); 2200 break; 2201 } 2202 } else { 2203 // Integer comparisons. 2204 switch (SetCCOpcode) { 2205 default: llvm_unreachable("Illegal integer comparison"); break; 2206 case ISD::SETNE: Invert = true; 2207 case ISD::SETEQ: Opc = ARMISD::VCEQ; break; 2208 case ISD::SETLT: Swap = true; 2209 case ISD::SETGT: Opc = ARMISD::VCGT; break; 2210 case ISD::SETLE: Swap = true; 2211 case ISD::SETGE: Opc = ARMISD::VCGE; break; 2212 case ISD::SETULT: Swap = true; 2213 case ISD::SETUGT: Opc = ARMISD::VCGTU; break; 2214 case ISD::SETULE: Swap = true; 2215 case ISD::SETUGE: Opc = ARMISD::VCGEU; break; 2216 } 2217 2218 // Detect VTST (Vector Test Bits) = icmp ne (and (op0, op1), zero). 2219 if (Opc == ARMISD::VCEQ) { 2220 2221 SDValue AndOp; 2222 if (ISD::isBuildVectorAllZeros(Op1.getNode())) 2223 AndOp = Op0; 2224 else if (ISD::isBuildVectorAllZeros(Op0.getNode())) 2225 AndOp = Op1; 2226 2227 // Ignore bitconvert. 2228 if (AndOp.getNode() && AndOp.getOpcode() == ISD::BIT_CONVERT) 2229 AndOp = AndOp.getOperand(0); 2230 2231 if (AndOp.getNode() && AndOp.getOpcode() == ISD::AND) { 2232 Opc = ARMISD::VTST; 2233 Op0 = DAG.getNode(ISD::BIT_CONVERT, dl, VT, AndOp.getOperand(0)); 2234 Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, VT, AndOp.getOperand(1)); 2235 Invert = !Invert; 2236 } 2237 } 2238 } 2239 2240 if (Swap) 2241 std::swap(Op0, Op1); 2242 2243 SDValue Result = DAG.getNode(Opc, dl, VT, Op0, Op1); 2244 2245 if (Invert) 2246 Result = DAG.getNOT(dl, Result, VT); 2247 2248 return Result; 2249} 2250 2251/// isVMOVSplat - Check if the specified splat value corresponds to an immediate 2252/// VMOV instruction, and if so, return the constant being splatted. 2253static SDValue isVMOVSplat(uint64_t SplatBits, uint64_t SplatUndef, 2254 unsigned SplatBitSize, SelectionDAG &DAG) { 2255 switch (SplatBitSize) { 2256 case 8: 2257 // Any 1-byte value is OK. 2258 assert((SplatBits & ~0xff) == 0 && "one byte splat value is too big"); 2259 return DAG.getTargetConstant(SplatBits, MVT::i8); 2260 2261 case 16: 2262 // NEON's 16-bit VMOV supports splat values where only one byte is nonzero. 2263 if ((SplatBits & ~0xff) == 0 || 2264 (SplatBits & ~0xff00) == 0) 2265 return DAG.getTargetConstant(SplatBits, MVT::i16); 2266 break; 2267 2268 case 32: 2269 // NEON's 32-bit VMOV supports splat values where: 2270 // * only one byte is nonzero, or 2271 // * the least significant byte is 0xff and the second byte is nonzero, or 2272 // * the least significant 2 bytes are 0xff and the third is nonzero. 2273 if ((SplatBits & ~0xff) == 0 || 2274 (SplatBits & ~0xff00) == 0 || 2275 (SplatBits & ~0xff0000) == 0 || 2276 (SplatBits & ~0xff000000) == 0) 2277 return DAG.getTargetConstant(SplatBits, MVT::i32); 2278 2279 if ((SplatBits & ~0xffff) == 0 && 2280 ((SplatBits | SplatUndef) & 0xff) == 0xff) 2281 return DAG.getTargetConstant(SplatBits | 0xff, MVT::i32); 2282 2283 if ((SplatBits & ~0xffffff) == 0 && 2284 ((SplatBits | SplatUndef) & 0xffff) == 0xffff) 2285 return DAG.getTargetConstant(SplatBits | 0xffff, MVT::i32); 2286 2287 // Note: there are a few 32-bit splat values (specifically: 00ffff00, 2288 // ff000000, ff0000ff, and ffff00ff) that are valid for VMOV.I64 but not 2289 // VMOV.I32. A (very) minor optimization would be to replicate the value 2290 // and fall through here to test for a valid 64-bit splat. But, then the 2291 // caller would also need to check and handle the change in size. 2292 break; 2293 2294 case 64: { 2295 // NEON has a 64-bit VMOV splat where each byte is either 0 or 0xff. 2296 uint64_t BitMask = 0xff; 2297 uint64_t Val = 0; 2298 for (int ByteNum = 0; ByteNum < 8; ++ByteNum) { 2299 if (((SplatBits | SplatUndef) & BitMask) == BitMask) 2300 Val |= BitMask; 2301 else if ((SplatBits & BitMask) != 0) 2302 return SDValue(); 2303 BitMask <<= 8; 2304 } 2305 return DAG.getTargetConstant(Val, MVT::i64); 2306 } 2307 2308 default: 2309 llvm_unreachable("unexpected size for isVMOVSplat"); 2310 break; 2311 } 2312 2313 return SDValue(); 2314} 2315 2316/// getVMOVImm - If this is a build_vector of constants which can be 2317/// formed by using a VMOV instruction of the specified element size, 2318/// return the constant being splatted. The ByteSize field indicates the 2319/// number of bytes of each element [1248]. 2320SDValue ARM::getVMOVImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) { 2321 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N); 2322 APInt SplatBits, SplatUndef; 2323 unsigned SplatBitSize; 2324 bool HasAnyUndefs; 2325 if (! BVN || ! BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, 2326 HasAnyUndefs, ByteSize * 8)) 2327 return SDValue(); 2328 2329 if (SplatBitSize > ByteSize * 8) 2330 return SDValue(); 2331 2332 return isVMOVSplat(SplatBits.getZExtValue(), SplatUndef.getZExtValue(), 2333 SplatBitSize, DAG); 2334} 2335 2336/// isVREVMask - Check if a vector shuffle corresponds to a VREV 2337/// instruction with the specified blocksize. (The order of the elements 2338/// within each block of the vector is reversed.) 2339bool ARM::isVREVMask(ShuffleVectorSDNode *N, unsigned BlockSize) { 2340 assert((BlockSize==16 || BlockSize==32 || BlockSize==64) && 2341 "Only possible block sizes for VREV are: 16, 32, 64"); 2342 2343 EVT VT = N->getValueType(0); 2344 unsigned NumElts = VT.getVectorNumElements(); 2345 unsigned EltSz = VT.getVectorElementType().getSizeInBits(); 2346 unsigned BlockElts = N->getMaskElt(0) + 1; 2347 2348 if (BlockSize <= EltSz || BlockSize != BlockElts * EltSz) 2349 return false; 2350 2351 for (unsigned i = 0; i < NumElts; ++i) { 2352 if ((unsigned) N->getMaskElt(i) != 2353 (i - i%BlockElts) + (BlockElts - 1 - i%BlockElts)) 2354 return false; 2355 } 2356 2357 return true; 2358} 2359 2360static SDValue BuildSplat(SDValue Val, EVT VT, SelectionDAG &DAG, DebugLoc dl) { 2361 // Canonicalize all-zeros and all-ones vectors. 2362 ConstantSDNode *ConstVal = dyn_cast<ConstantSDNode>(Val.getNode()); 2363 if (ConstVal->isNullValue()) 2364 return getZeroVector(VT, DAG, dl); 2365 if (ConstVal->isAllOnesValue()) 2366 return getOnesVector(VT, DAG, dl); 2367 2368 EVT CanonicalVT; 2369 if (VT.is64BitVector()) { 2370 switch (Val.getValueType().getSizeInBits()) { 2371 case 8: CanonicalVT = MVT::v8i8; break; 2372 case 16: CanonicalVT = MVT::v4i16; break; 2373 case 32: CanonicalVT = MVT::v2i32; break; 2374 case 64: CanonicalVT = MVT::v1i64; break; 2375 default: llvm_unreachable("unexpected splat element type"); break; 2376 } 2377 } else { 2378 assert(VT.is128BitVector() && "unknown splat vector size"); 2379 switch (Val.getValueType().getSizeInBits()) { 2380 case 8: CanonicalVT = MVT::v16i8; break; 2381 case 16: CanonicalVT = MVT::v8i16; break; 2382 case 32: CanonicalVT = MVT::v4i32; break; 2383 case 64: CanonicalVT = MVT::v2i64; break; 2384 default: llvm_unreachable("unexpected splat element type"); break; 2385 } 2386 } 2387 2388 // Build a canonical splat for this value. 2389 SmallVector<SDValue, 8> Ops; 2390 Ops.assign(CanonicalVT.getVectorNumElements(), Val); 2391 SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, dl, CanonicalVT, &Ops[0], 2392 Ops.size()); 2393 return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Res); 2394} 2395 2396// If this is a case we can't handle, return null and let the default 2397// expansion code take care of it. 2398static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { 2399 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(Op.getNode()); 2400 assert(BVN != 0 && "Expected a BuildVectorSDNode in LowerBUILD_VECTOR"); 2401 DebugLoc dl = Op.getDebugLoc(); 2402 EVT VT = Op.getValueType(); 2403 2404 APInt SplatBits, SplatUndef; 2405 unsigned SplatBitSize; 2406 bool HasAnyUndefs; 2407 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) { 2408 SDValue Val = isVMOVSplat(SplatBits.getZExtValue(), 2409 SplatUndef.getZExtValue(), SplatBitSize, DAG); 2410 if (Val.getNode()) 2411 return BuildSplat(Val, VT, DAG, dl); 2412 } 2413 2414 // If there are only 2 elements in a 128-bit vector, insert them into an 2415 // undef vector. This handles the common case for 128-bit vector argument 2416 // passing, where the insertions should be translated to subreg accesses 2417 // with no real instructions. 2418 if (VT.is128BitVector() && Op.getNumOperands() == 2) { 2419 SDValue Val = DAG.getUNDEF(VT); 2420 SDValue Op0 = Op.getOperand(0); 2421 SDValue Op1 = Op.getOperand(1); 2422 if (Op0.getOpcode() != ISD::UNDEF) 2423 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Val, Op0, 2424 DAG.getIntPtrConstant(0)); 2425 if (Op1.getOpcode() != ISD::UNDEF) 2426 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Val, Op1, 2427 DAG.getIntPtrConstant(1)); 2428 return Val; 2429 } 2430 2431 return SDValue(); 2432} 2433 2434static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { 2435 return Op; 2436} 2437 2438static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) { 2439 return Op; 2440} 2441 2442static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) { 2443 EVT VT = Op.getValueType(); 2444 DebugLoc dl = Op.getDebugLoc(); 2445 assert((VT == MVT::i8 || VT == MVT::i16) && 2446 "unexpected type for custom-lowering vector extract"); 2447 SDValue Vec = Op.getOperand(0); 2448 SDValue Lane = Op.getOperand(1); 2449 Op = DAG.getNode(ARMISD::VGETLANEu, dl, MVT::i32, Vec, Lane); 2450 Op = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Op, DAG.getValueType(VT)); 2451 return DAG.getNode(ISD::TRUNCATE, dl, VT, Op); 2452} 2453 2454static SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) { 2455 // The only time a CONCAT_VECTORS operation can have legal types is when 2456 // two 64-bit vectors are concatenated to a 128-bit vector. 2457 assert(Op.getValueType().is128BitVector() && Op.getNumOperands() == 2 && 2458 "unexpected CONCAT_VECTORS"); 2459 DebugLoc dl = Op.getDebugLoc(); 2460 SDValue Val = DAG.getUNDEF(MVT::v2f64); 2461 SDValue Op0 = Op.getOperand(0); 2462 SDValue Op1 = Op.getOperand(1); 2463 if (Op0.getOpcode() != ISD::UNDEF) 2464 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val, 2465 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, Op0), 2466 DAG.getIntPtrConstant(0)); 2467 if (Op1.getOpcode() != ISD::UNDEF) 2468 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val, 2469 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, Op1), 2470 DAG.getIntPtrConstant(1)); 2471 return DAG.getNode(ISD::BIT_CONVERT, dl, Op.getValueType(), Val); 2472} 2473 2474SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { 2475 switch (Op.getOpcode()) { 2476 default: llvm_unreachable("Don't know how to custom lower this!"); 2477 case ISD::ConstantPool: return LowerConstantPool(Op, DAG); 2478 case ISD::GlobalAddress: 2479 return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) : 2480 LowerGlobalAddressELF(Op, DAG); 2481 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); 2482 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, Subtarget); 2483 case ISD::BR_CC: return LowerBR_CC(Op, DAG, Subtarget); 2484 case ISD::BR_JT: return LowerBR_JT(Op, DAG); 2485 case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); 2486 case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); 2487 case ISD::SINT_TO_FP: 2488 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG); 2489 case ISD::FP_TO_SINT: 2490 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG); 2491 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); 2492 case ISD::RETURNADDR: break; 2493 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 2494 case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); 2495 case ISD::INTRINSIC_VOID: 2496 case ISD::INTRINSIC_W_CHAIN: return LowerINTRINSIC_W_CHAIN(Op, DAG); 2497 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); 2498 case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(Op.getNode(), DAG); 2499 case ISD::SHL: 2500 case ISD::SRL: 2501 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget); 2502 case ISD::VSETCC: return LowerVSETCC(Op, DAG); 2503 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG); 2504 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG); 2505 case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG); 2506 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG); 2507 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG); 2508 } 2509 return SDValue(); 2510} 2511 2512/// ReplaceNodeResults - Replace the results of node with an illegal result 2513/// type with new values built out of custom code. 2514void ARMTargetLowering::ReplaceNodeResults(SDNode *N, 2515 SmallVectorImpl<SDValue>&Results, 2516 SelectionDAG &DAG) { 2517 switch (N->getOpcode()) { 2518 default: 2519 llvm_unreachable("Don't know how to custom expand this!"); 2520 return; 2521 case ISD::BIT_CONVERT: 2522 Results.push_back(ExpandBIT_CONVERT(N, DAG)); 2523 return; 2524 case ISD::SRL: 2525 case ISD::SRA: { 2526 SDValue Res = LowerShift(N, DAG, Subtarget); 2527 if (Res.getNode()) 2528 Results.push_back(Res); 2529 return; 2530 } 2531 } 2532} 2533 2534//===----------------------------------------------------------------------===// 2535// ARM Scheduler Hooks 2536//===----------------------------------------------------------------------===// 2537 2538MachineBasicBlock * 2539ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 2540 MachineBasicBlock *BB) const { 2541 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 2542 DebugLoc dl = MI->getDebugLoc(); 2543 switch (MI->getOpcode()) { 2544 default: 2545 llvm_unreachable("Unexpected instr type to insert"); 2546 case ARM::tMOVCCr_pseudo: { 2547 // To "insert" a SELECT_CC instruction, we actually have to insert the 2548 // diamond control-flow pattern. The incoming instruction knows the 2549 // destination vreg to set, the condition code register to branch on, the 2550 // true/false values to select between, and a branch opcode to use. 2551 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 2552 MachineFunction::iterator It = BB; 2553 ++It; 2554 2555 // thisMBB: 2556 // ... 2557 // TrueVal = ... 2558 // cmpTY ccX, r1, r2 2559 // bCC copy1MBB 2560 // fallthrough --> copy0MBB 2561 MachineBasicBlock *thisMBB = BB; 2562 MachineFunction *F = BB->getParent(); 2563 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 2564 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); 2565 BuildMI(BB, dl, TII->get(ARM::tBcc)).addMBB(sinkMBB) 2566 .addImm(MI->getOperand(3).getImm()).addReg(MI->getOperand(4).getReg()); 2567 F->insert(It, copy0MBB); 2568 F->insert(It, sinkMBB); 2569 // Update machine-CFG edges by first adding all successors of the current 2570 // block to the new block which will contain the Phi node for the select. 2571 for(MachineBasicBlock::succ_iterator i = BB->succ_begin(), 2572 e = BB->succ_end(); i != e; ++i) 2573 sinkMBB->addSuccessor(*i); 2574 // Next, remove all successors of the current block, and add the true 2575 // and fallthrough blocks as its successors. 2576 while(!BB->succ_empty()) 2577 BB->removeSuccessor(BB->succ_begin()); 2578 BB->addSuccessor(copy0MBB); 2579 BB->addSuccessor(sinkMBB); 2580 2581 // copy0MBB: 2582 // %FalseValue = ... 2583 // # fallthrough to sinkMBB 2584 BB = copy0MBB; 2585 2586 // Update machine-CFG edges 2587 BB->addSuccessor(sinkMBB); 2588 2589 // sinkMBB: 2590 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 2591 // ... 2592 BB = sinkMBB; 2593 BuildMI(BB, dl, TII->get(ARM::PHI), MI->getOperand(0).getReg()) 2594 .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB) 2595 .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); 2596 2597 F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. 2598 return BB; 2599 } 2600 2601 case ARM::tANDsp: 2602 case ARM::tADDspr_: 2603 case ARM::tSUBspi_: 2604 case ARM::t2SUBrSPi_: 2605 case ARM::t2SUBrSPi12_: 2606 case ARM::t2SUBrSPs_: { 2607 MachineFunction *MF = BB->getParent(); 2608 unsigned DstReg = MI->getOperand(0).getReg(); 2609 unsigned SrcReg = MI->getOperand(1).getReg(); 2610 bool DstIsDead = MI->getOperand(0).isDead(); 2611 bool SrcIsKill = MI->getOperand(1).isKill(); 2612 2613 if (SrcReg != ARM::SP) { 2614 // Copy the source to SP from virtual register. 2615 const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(SrcReg); 2616 unsigned CopyOpc = (RC == ARM::tGPRRegisterClass) 2617 ? ARM::tMOVtgpr2gpr : ARM::tMOVgpr2gpr; 2618 BuildMI(BB, dl, TII->get(CopyOpc), ARM::SP) 2619 .addReg(SrcReg, getKillRegState(SrcIsKill)); 2620 } 2621 2622 unsigned OpOpc = 0; 2623 bool NeedPred = false, NeedCC = false, NeedOp3 = false; 2624 switch (MI->getOpcode()) { 2625 default: 2626 llvm_unreachable("Unexpected pseudo instruction!"); 2627 case ARM::tANDsp: 2628 OpOpc = ARM::tAND; 2629 NeedPred = true; 2630 break; 2631 case ARM::tADDspr_: 2632 OpOpc = ARM::tADDspr; 2633 break; 2634 case ARM::tSUBspi_: 2635 OpOpc = ARM::tSUBspi; 2636 break; 2637 case ARM::t2SUBrSPi_: 2638 OpOpc = ARM::t2SUBrSPi; 2639 NeedPred = true; NeedCC = true; 2640 break; 2641 case ARM::t2SUBrSPi12_: 2642 OpOpc = ARM::t2SUBrSPi12; 2643 NeedPred = true; 2644 break; 2645 case ARM::t2SUBrSPs_: 2646 OpOpc = ARM::t2SUBrSPs; 2647 NeedPred = true; NeedCC = true; NeedOp3 = true; 2648 break; 2649 } 2650 MachineInstrBuilder MIB = BuildMI(BB, dl, TII->get(OpOpc), ARM::SP); 2651 if (OpOpc == ARM::tAND) 2652 AddDefaultT1CC(MIB); 2653 MIB.addReg(ARM::SP); 2654 MIB.addOperand(MI->getOperand(2)); 2655 if (NeedOp3) 2656 MIB.addOperand(MI->getOperand(3)); 2657 if (NeedPred) 2658 AddDefaultPred(MIB); 2659 if (NeedCC) 2660 AddDefaultCC(MIB); 2661 2662 // Copy the result from SP to virtual register. 2663 const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(DstReg); 2664 unsigned CopyOpc = (RC == ARM::tGPRRegisterClass) 2665 ? ARM::tMOVgpr2tgpr : ARM::tMOVgpr2gpr; 2666 BuildMI(BB, dl, TII->get(CopyOpc)) 2667 .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead)) 2668 .addReg(ARM::SP); 2669 MF->DeleteMachineInstr(MI); // The pseudo instruction is gone now. 2670 return BB; 2671 } 2672 } 2673} 2674 2675//===----------------------------------------------------------------------===// 2676// ARM Optimization Hooks 2677//===----------------------------------------------------------------------===// 2678 2679static 2680SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp, 2681 TargetLowering::DAGCombinerInfo &DCI) { 2682 SelectionDAG &DAG = DCI.DAG; 2683 const TargetLowering &TLI = DAG.getTargetLoweringInfo(); 2684 EVT VT = N->getValueType(0); 2685 unsigned Opc = N->getOpcode(); 2686 bool isSlctCC = Slct.getOpcode() == ISD::SELECT_CC; 2687 SDValue LHS = isSlctCC ? Slct.getOperand(2) : Slct.getOperand(1); 2688 SDValue RHS = isSlctCC ? Slct.getOperand(3) : Slct.getOperand(2); 2689 ISD::CondCode CC = ISD::SETCC_INVALID; 2690 2691 if (isSlctCC) { 2692 CC = cast<CondCodeSDNode>(Slct.getOperand(4))->get(); 2693 } else { 2694 SDValue CCOp = Slct.getOperand(0); 2695 if (CCOp.getOpcode() == ISD::SETCC) 2696 CC = cast<CondCodeSDNode>(CCOp.getOperand(2))->get(); 2697 } 2698 2699 bool DoXform = false; 2700 bool InvCC = false; 2701 assert ((Opc == ISD::ADD || (Opc == ISD::SUB && Slct == N->getOperand(1))) && 2702 "Bad input!"); 2703 2704 if (LHS.getOpcode() == ISD::Constant && 2705 cast<ConstantSDNode>(LHS)->isNullValue()) { 2706 DoXform = true; 2707 } else if (CC != ISD::SETCC_INVALID && 2708 RHS.getOpcode() == ISD::Constant && 2709 cast<ConstantSDNode>(RHS)->isNullValue()) { 2710 std::swap(LHS, RHS); 2711 SDValue Op0 = Slct.getOperand(0); 2712 EVT OpVT = isSlctCC ? Op0.getValueType() : 2713 Op0.getOperand(0).getValueType(); 2714 bool isInt = OpVT.isInteger(); 2715 CC = ISD::getSetCCInverse(CC, isInt); 2716 2717 if (!TLI.isCondCodeLegal(CC, OpVT)) 2718 return SDValue(); // Inverse operator isn't legal. 2719 2720 DoXform = true; 2721 InvCC = true; 2722 } 2723 2724 if (DoXform) { 2725 SDValue Result = DAG.getNode(Opc, RHS.getDebugLoc(), VT, OtherOp, RHS); 2726 if (isSlctCC) 2727 return DAG.getSelectCC(N->getDebugLoc(), OtherOp, Result, 2728 Slct.getOperand(0), Slct.getOperand(1), CC); 2729 SDValue CCOp = Slct.getOperand(0); 2730 if (InvCC) 2731 CCOp = DAG.getSetCC(Slct.getDebugLoc(), CCOp.getValueType(), 2732 CCOp.getOperand(0), CCOp.getOperand(1), CC); 2733 return DAG.getNode(ISD::SELECT, N->getDebugLoc(), VT, 2734 CCOp, OtherOp, Result); 2735 } 2736 return SDValue(); 2737} 2738 2739/// PerformADDCombine - Target-specific dag combine xforms for ISD::ADD. 2740static SDValue PerformADDCombine(SDNode *N, 2741 TargetLowering::DAGCombinerInfo &DCI) { 2742 // added by evan in r37685 with no testcase. 2743 SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); 2744 2745 // fold (add (select cc, 0, c), x) -> (select cc, x, (add, x, c)) 2746 if (N0.getOpcode() == ISD::SELECT && N0.getNode()->hasOneUse()) { 2747 SDValue Result = combineSelectAndUse(N, N0, N1, DCI); 2748 if (Result.getNode()) return Result; 2749 } 2750 if (N1.getOpcode() == ISD::SELECT && N1.getNode()->hasOneUse()) { 2751 SDValue Result = combineSelectAndUse(N, N1, N0, DCI); 2752 if (Result.getNode()) return Result; 2753 } 2754 2755 return SDValue(); 2756} 2757 2758/// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB. 2759static SDValue PerformSUBCombine(SDNode *N, 2760 TargetLowering::DAGCombinerInfo &DCI) { 2761 // added by evan in r37685 with no testcase. 2762 SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); 2763 2764 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c)) 2765 if (N1.getOpcode() == ISD::SELECT && N1.getNode()->hasOneUse()) { 2766 SDValue Result = combineSelectAndUse(N, N1, N0, DCI); 2767 if (Result.getNode()) return Result; 2768 } 2769 2770 return SDValue(); 2771} 2772 2773 2774/// PerformFMRRDCombine - Target-specific dag combine xforms for ARMISD::FMRRD. 2775static SDValue PerformFMRRDCombine(SDNode *N, 2776 TargetLowering::DAGCombinerInfo &DCI) { 2777 // fmrrd(fmdrr x, y) -> x,y 2778 SDValue InDouble = N->getOperand(0); 2779 if (InDouble.getOpcode() == ARMISD::FMDRR) 2780 return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1)); 2781 return SDValue(); 2782} 2783 2784/// getVShiftImm - Check if this is a valid build_vector for the immediate 2785/// operand of a vector shift operation, where all the elements of the 2786/// build_vector must have the same constant integer value. 2787static bool getVShiftImm(SDValue Op, unsigned ElementBits, int64_t &Cnt) { 2788 // Ignore bit_converts. 2789 while (Op.getOpcode() == ISD::BIT_CONVERT) 2790 Op = Op.getOperand(0); 2791 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(Op.getNode()); 2792 APInt SplatBits, SplatUndef; 2793 unsigned SplatBitSize; 2794 bool HasAnyUndefs; 2795 if (! BVN || ! BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, 2796 HasAnyUndefs, ElementBits) || 2797 SplatBitSize > ElementBits) 2798 return false; 2799 Cnt = SplatBits.getSExtValue(); 2800 return true; 2801} 2802 2803/// isVShiftLImm - Check if this is a valid build_vector for the immediate 2804/// operand of a vector shift left operation. That value must be in the range: 2805/// 0 <= Value < ElementBits for a left shift; or 2806/// 0 <= Value <= ElementBits for a long left shift. 2807static bool isVShiftLImm(SDValue Op, EVT VT, bool isLong, int64_t &Cnt) { 2808 assert(VT.isVector() && "vector shift count is not a vector type"); 2809 unsigned ElementBits = VT.getVectorElementType().getSizeInBits(); 2810 if (! getVShiftImm(Op, ElementBits, Cnt)) 2811 return false; 2812 return (Cnt >= 0 && (isLong ? Cnt-1 : Cnt) < ElementBits); 2813} 2814 2815/// isVShiftRImm - Check if this is a valid build_vector for the immediate 2816/// operand of a vector shift right operation. For a shift opcode, the value 2817/// is positive, but for an intrinsic the value count must be negative. The 2818/// absolute value must be in the range: 2819/// 1 <= |Value| <= ElementBits for a right shift; or 2820/// 1 <= |Value| <= ElementBits/2 for a narrow right shift. 2821static bool isVShiftRImm(SDValue Op, EVT VT, bool isNarrow, bool isIntrinsic, 2822 int64_t &Cnt) { 2823 assert(VT.isVector() && "vector shift count is not a vector type"); 2824 unsigned ElementBits = VT.getVectorElementType().getSizeInBits(); 2825 if (! getVShiftImm(Op, ElementBits, Cnt)) 2826 return false; 2827 if (isIntrinsic) 2828 Cnt = -Cnt; 2829 return (Cnt >= 1 && Cnt <= (isNarrow ? ElementBits/2 : ElementBits)); 2830} 2831 2832/// PerformIntrinsicCombine - ARM-specific DAG combining for intrinsics. 2833static SDValue PerformIntrinsicCombine(SDNode *N, SelectionDAG &DAG) { 2834 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 2835 switch (IntNo) { 2836 default: 2837 // Don't do anything for most intrinsics. 2838 break; 2839 2840 // Vector shifts: check for immediate versions and lower them. 2841 // Note: This is done during DAG combining instead of DAG legalizing because 2842 // the build_vectors for 64-bit vector element shift counts are generally 2843 // not legal, and it is hard to see their values after they get legalized to 2844 // loads from a constant pool. 2845 case Intrinsic::arm_neon_vshifts: 2846 case Intrinsic::arm_neon_vshiftu: 2847 case Intrinsic::arm_neon_vshiftls: 2848 case Intrinsic::arm_neon_vshiftlu: 2849 case Intrinsic::arm_neon_vshiftn: 2850 case Intrinsic::arm_neon_vrshifts: 2851 case Intrinsic::arm_neon_vrshiftu: 2852 case Intrinsic::arm_neon_vrshiftn: 2853 case Intrinsic::arm_neon_vqshifts: 2854 case Intrinsic::arm_neon_vqshiftu: 2855 case Intrinsic::arm_neon_vqshiftsu: 2856 case Intrinsic::arm_neon_vqshiftns: 2857 case Intrinsic::arm_neon_vqshiftnu: 2858 case Intrinsic::arm_neon_vqshiftnsu: 2859 case Intrinsic::arm_neon_vqrshiftns: 2860 case Intrinsic::arm_neon_vqrshiftnu: 2861 case Intrinsic::arm_neon_vqrshiftnsu: { 2862 EVT VT = N->getOperand(1).getValueType(); 2863 int64_t Cnt; 2864 unsigned VShiftOpc = 0; 2865 2866 switch (IntNo) { 2867 case Intrinsic::arm_neon_vshifts: 2868 case Intrinsic::arm_neon_vshiftu: 2869 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) { 2870 VShiftOpc = ARMISD::VSHL; 2871 break; 2872 } 2873 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt)) { 2874 VShiftOpc = (IntNo == Intrinsic::arm_neon_vshifts ? 2875 ARMISD::VSHRs : ARMISD::VSHRu); 2876 break; 2877 } 2878 return SDValue(); 2879 2880 case Intrinsic::arm_neon_vshiftls: 2881 case Intrinsic::arm_neon_vshiftlu: 2882 if (isVShiftLImm(N->getOperand(2), VT, true, Cnt)) 2883 break; 2884 llvm_unreachable("invalid shift count for vshll intrinsic"); 2885 2886 case Intrinsic::arm_neon_vrshifts: 2887 case Intrinsic::arm_neon_vrshiftu: 2888 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt)) 2889 break; 2890 return SDValue(); 2891 2892 case Intrinsic::arm_neon_vqshifts: 2893 case Intrinsic::arm_neon_vqshiftu: 2894 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) 2895 break; 2896 return SDValue(); 2897 2898 case Intrinsic::arm_neon_vqshiftsu: 2899 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) 2900 break; 2901 llvm_unreachable("invalid shift count for vqshlu intrinsic"); 2902 2903 case Intrinsic::arm_neon_vshiftn: 2904 case Intrinsic::arm_neon_vrshiftn: 2905 case Intrinsic::arm_neon_vqshiftns: 2906 case Intrinsic::arm_neon_vqshiftnu: 2907 case Intrinsic::arm_neon_vqshiftnsu: 2908 case Intrinsic::arm_neon_vqrshiftns: 2909 case Intrinsic::arm_neon_vqrshiftnu: 2910 case Intrinsic::arm_neon_vqrshiftnsu: 2911 // Narrowing shifts require an immediate right shift. 2912 if (isVShiftRImm(N->getOperand(2), VT, true, true, Cnt)) 2913 break; 2914 llvm_unreachable("invalid shift count for narrowing vector shift intrinsic"); 2915 2916 default: 2917 llvm_unreachable("unhandled vector shift"); 2918 } 2919 2920 switch (IntNo) { 2921 case Intrinsic::arm_neon_vshifts: 2922 case Intrinsic::arm_neon_vshiftu: 2923 // Opcode already set above. 2924 break; 2925 case Intrinsic::arm_neon_vshiftls: 2926 case Intrinsic::arm_neon_vshiftlu: 2927 if (Cnt == VT.getVectorElementType().getSizeInBits()) 2928 VShiftOpc = ARMISD::VSHLLi; 2929 else 2930 VShiftOpc = (IntNo == Intrinsic::arm_neon_vshiftls ? 2931 ARMISD::VSHLLs : ARMISD::VSHLLu); 2932 break; 2933 case Intrinsic::arm_neon_vshiftn: 2934 VShiftOpc = ARMISD::VSHRN; break; 2935 case Intrinsic::arm_neon_vrshifts: 2936 VShiftOpc = ARMISD::VRSHRs; break; 2937 case Intrinsic::arm_neon_vrshiftu: 2938 VShiftOpc = ARMISD::VRSHRu; break; 2939 case Intrinsic::arm_neon_vrshiftn: 2940 VShiftOpc = ARMISD::VRSHRN; break; 2941 case Intrinsic::arm_neon_vqshifts: 2942 VShiftOpc = ARMISD::VQSHLs; break; 2943 case Intrinsic::arm_neon_vqshiftu: 2944 VShiftOpc = ARMISD::VQSHLu; break; 2945 case Intrinsic::arm_neon_vqshiftsu: 2946 VShiftOpc = ARMISD::VQSHLsu; break; 2947 case Intrinsic::arm_neon_vqshiftns: 2948 VShiftOpc = ARMISD::VQSHRNs; break; 2949 case Intrinsic::arm_neon_vqshiftnu: 2950 VShiftOpc = ARMISD::VQSHRNu; break; 2951 case Intrinsic::arm_neon_vqshiftnsu: 2952 VShiftOpc = ARMISD::VQSHRNsu; break; 2953 case Intrinsic::arm_neon_vqrshiftns: 2954 VShiftOpc = ARMISD::VQRSHRNs; break; 2955 case Intrinsic::arm_neon_vqrshiftnu: 2956 VShiftOpc = ARMISD::VQRSHRNu; break; 2957 case Intrinsic::arm_neon_vqrshiftnsu: 2958 VShiftOpc = ARMISD::VQRSHRNsu; break; 2959 } 2960 2961 return DAG.getNode(VShiftOpc, N->getDebugLoc(), N->getValueType(0), 2962 N->getOperand(1), DAG.getConstant(Cnt, MVT::i32)); 2963 } 2964 2965 case Intrinsic::arm_neon_vshiftins: { 2966 EVT VT = N->getOperand(1).getValueType(); 2967 int64_t Cnt; 2968 unsigned VShiftOpc = 0; 2969 2970 if (isVShiftLImm(N->getOperand(3), VT, false, Cnt)) 2971 VShiftOpc = ARMISD::VSLI; 2972 else if (isVShiftRImm(N->getOperand(3), VT, false, true, Cnt)) 2973 VShiftOpc = ARMISD::VSRI; 2974 else { 2975 llvm_unreachable("invalid shift count for vsli/vsri intrinsic"); 2976 } 2977 2978 return DAG.getNode(VShiftOpc, N->getDebugLoc(), N->getValueType(0), 2979 N->getOperand(1), N->getOperand(2), 2980 DAG.getConstant(Cnt, MVT::i32)); 2981 } 2982 2983 case Intrinsic::arm_neon_vqrshifts: 2984 case Intrinsic::arm_neon_vqrshiftu: 2985 // No immediate versions of these to check for. 2986 break; 2987 } 2988 2989 return SDValue(); 2990} 2991 2992/// PerformShiftCombine - Checks for immediate versions of vector shifts and 2993/// lowers them. As with the vector shift intrinsics, this is done during DAG 2994/// combining instead of DAG legalizing because the build_vectors for 64-bit 2995/// vector element shift counts are generally not legal, and it is hard to see 2996/// their values after they get legalized to loads from a constant pool. 2997static SDValue PerformShiftCombine(SDNode *N, SelectionDAG &DAG, 2998 const ARMSubtarget *ST) { 2999 EVT VT = N->getValueType(0); 3000 3001 // Nothing to be done for scalar shifts. 3002 if (! VT.isVector()) 3003 return SDValue(); 3004 3005 assert(ST->hasNEON() && "unexpected vector shift"); 3006 int64_t Cnt; 3007 3008 switch (N->getOpcode()) { 3009 default: llvm_unreachable("unexpected shift opcode"); 3010 3011 case ISD::SHL: 3012 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt)) 3013 return DAG.getNode(ARMISD::VSHL, N->getDebugLoc(), VT, N->getOperand(0), 3014 DAG.getConstant(Cnt, MVT::i32)); 3015 break; 3016 3017 case ISD::SRA: 3018 case ISD::SRL: 3019 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) { 3020 unsigned VShiftOpc = (N->getOpcode() == ISD::SRA ? 3021 ARMISD::VSHRs : ARMISD::VSHRu); 3022 return DAG.getNode(VShiftOpc, N->getDebugLoc(), VT, N->getOperand(0), 3023 DAG.getConstant(Cnt, MVT::i32)); 3024 } 3025 } 3026 return SDValue(); 3027} 3028 3029/// PerformExtendCombine - Target-specific DAG combining for ISD::SIGN_EXTEND, 3030/// ISD::ZERO_EXTEND, and ISD::ANY_EXTEND. 3031static SDValue PerformExtendCombine(SDNode *N, SelectionDAG &DAG, 3032 const ARMSubtarget *ST) { 3033 SDValue N0 = N->getOperand(0); 3034 3035 // Check for sign- and zero-extensions of vector extract operations of 8- 3036 // and 16-bit vector elements. NEON supports these directly. They are 3037 // handled during DAG combining because type legalization will promote them 3038 // to 32-bit types and it is messy to recognize the operations after that. 3039 if (ST->hasNEON() && N0.getOpcode() == ISD::EXTRACT_VECTOR_ELT) { 3040 SDValue Vec = N0.getOperand(0); 3041 SDValue Lane = N0.getOperand(1); 3042 EVT VT = N->getValueType(0); 3043 EVT EltVT = N0.getValueType(); 3044 const TargetLowering &TLI = DAG.getTargetLoweringInfo(); 3045 3046 if (VT == MVT::i32 && 3047 (EltVT == MVT::i8 || EltVT == MVT::i16) && 3048 TLI.isTypeLegal(Vec.getValueType())) { 3049 3050 unsigned Opc = 0; 3051 switch (N->getOpcode()) { 3052 default: llvm_unreachable("unexpected opcode"); 3053 case ISD::SIGN_EXTEND: 3054 Opc = ARMISD::VGETLANEs; 3055 break; 3056 case ISD::ZERO_EXTEND: 3057 case ISD::ANY_EXTEND: 3058 Opc = ARMISD::VGETLANEu; 3059 break; 3060 } 3061 return DAG.getNode(Opc, N->getDebugLoc(), VT, Vec, Lane); 3062 } 3063 } 3064 3065 return SDValue(); 3066} 3067 3068SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N, 3069 DAGCombinerInfo &DCI) const { 3070 switch (N->getOpcode()) { 3071 default: break; 3072 case ISD::ADD: return PerformADDCombine(N, DCI); 3073 case ISD::SUB: return PerformSUBCombine(N, DCI); 3074 case ARMISD::FMRRD: return PerformFMRRDCombine(N, DCI); 3075 case ISD::INTRINSIC_WO_CHAIN: 3076 return PerformIntrinsicCombine(N, DCI.DAG); 3077 case ISD::SHL: 3078 case ISD::SRA: 3079 case ISD::SRL: 3080 return PerformShiftCombine(N, DCI.DAG, Subtarget); 3081 case ISD::SIGN_EXTEND: 3082 case ISD::ZERO_EXTEND: 3083 case ISD::ANY_EXTEND: 3084 return PerformExtendCombine(N, DCI.DAG, Subtarget); 3085 } 3086 return SDValue(); 3087} 3088 3089/// isLegalAddressImmediate - Return true if the integer value can be used 3090/// as the offset of the target addressing mode for load / store of the 3091/// given type. 3092static bool isLegalAddressImmediate(int64_t V, EVT VT, 3093 const ARMSubtarget *Subtarget) { 3094 if (V == 0) 3095 return true; 3096 3097 if (!VT.isSimple()) 3098 return false; 3099 3100 if (Subtarget->isThumb()) { // FIXME for thumb2 3101 if (V < 0) 3102 return false; 3103 3104 unsigned Scale = 1; 3105 switch (VT.getSimpleVT().SimpleTy) { 3106 default: return false; 3107 case MVT::i1: 3108 case MVT::i8: 3109 // Scale == 1; 3110 break; 3111 case MVT::i16: 3112 // Scale == 2; 3113 Scale = 2; 3114 break; 3115 case MVT::i32: 3116 // Scale == 4; 3117 Scale = 4; 3118 break; 3119 } 3120 3121 if ((V & (Scale - 1)) != 0) 3122 return false; 3123 V /= Scale; 3124 return V == (V & ((1LL << 5) - 1)); 3125 } 3126 3127 if (V < 0) 3128 V = - V; 3129 switch (VT.getSimpleVT().SimpleTy) { 3130 default: return false; 3131 case MVT::i1: 3132 case MVT::i8: 3133 case MVT::i32: 3134 // +- imm12 3135 return V == (V & ((1LL << 12) - 1)); 3136 case MVT::i16: 3137 // +- imm8 3138 return V == (V & ((1LL << 8) - 1)); 3139 case MVT::f32: 3140 case MVT::f64: 3141 if (!Subtarget->hasVFP2()) 3142 return false; 3143 if ((V & 3) != 0) 3144 return false; 3145 V >>= 2; 3146 return V == (V & ((1LL << 8) - 1)); 3147 } 3148} 3149 3150/// isLegalAddressingMode - Return true if the addressing mode represented 3151/// by AM is legal for this target, for a load/store of the specified type. 3152bool ARMTargetLowering::isLegalAddressingMode(const AddrMode &AM, 3153 const Type *Ty) const { 3154 EVT VT = getValueType(Ty, true); 3155 if (!isLegalAddressImmediate(AM.BaseOffs, VT, Subtarget)) 3156 return false; 3157 3158 // Can never fold addr of global into load/store. 3159 if (AM.BaseGV) 3160 return false; 3161 3162 switch (AM.Scale) { 3163 case 0: // no scale reg, must be "r+i" or "r", or "i". 3164 break; 3165 case 1: 3166 if (Subtarget->isThumb()) // FIXME for thumb2 3167 return false; 3168 // FALL THROUGH. 3169 default: 3170 // ARM doesn't support any R+R*scale+imm addr modes. 3171 if (AM.BaseOffs) 3172 return false; 3173 3174 if (!VT.isSimple()) 3175 return false; 3176 3177 int Scale = AM.Scale; 3178 switch (VT.getSimpleVT().SimpleTy) { 3179 default: return false; 3180 case MVT::i1: 3181 case MVT::i8: 3182 case MVT::i32: 3183 case MVT::i64: 3184 // This assumes i64 is legalized to a pair of i32. If not (i.e. 3185 // ldrd / strd are used, then its address mode is same as i16. 3186 // r + r 3187 if (Scale < 0) Scale = -Scale; 3188 if (Scale == 1) 3189 return true; 3190 // r + r << imm 3191 return isPowerOf2_32(Scale & ~1); 3192 case MVT::i16: 3193 // r + r 3194 if (((unsigned)AM.HasBaseReg + Scale) <= 2) 3195 return true; 3196 return false; 3197 3198 case MVT::isVoid: 3199 // Note, we allow "void" uses (basically, uses that aren't loads or 3200 // stores), because arm allows folding a scale into many arithmetic 3201 // operations. This should be made more precise and revisited later. 3202 3203 // Allow r << imm, but the imm has to be a multiple of two. 3204 if (AM.Scale & 1) return false; 3205 return isPowerOf2_32(AM.Scale); 3206 } 3207 break; 3208 } 3209 return true; 3210} 3211 3212static bool getARMIndexedAddressParts(SDNode *Ptr, EVT VT, 3213 bool isSEXTLoad, SDValue &Base, 3214 SDValue &Offset, bool &isInc, 3215 SelectionDAG &DAG) { 3216 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB) 3217 return false; 3218 3219 if (VT == MVT::i16 || ((VT == MVT::i8 || VT == MVT::i1) && isSEXTLoad)) { 3220 // AddressingMode 3 3221 Base = Ptr->getOperand(0); 3222 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) { 3223 int RHSC = (int)RHS->getZExtValue(); 3224 if (RHSC < 0 && RHSC > -256) { 3225 assert(Ptr->getOpcode() == ISD::ADD); 3226 isInc = false; 3227 Offset = DAG.getConstant(-RHSC, RHS->getValueType(0)); 3228 return true; 3229 } 3230 } 3231 isInc = (Ptr->getOpcode() == ISD::ADD); 3232 Offset = Ptr->getOperand(1); 3233 return true; 3234 } else if (VT == MVT::i32 || VT == MVT::i8 || VT == MVT::i1) { 3235 // AddressingMode 2 3236 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) { 3237 int RHSC = (int)RHS->getZExtValue(); 3238 if (RHSC < 0 && RHSC > -0x1000) { 3239 assert(Ptr->getOpcode() == ISD::ADD); 3240 isInc = false; 3241 Offset = DAG.getConstant(-RHSC, RHS->getValueType(0)); 3242 Base = Ptr->getOperand(0); 3243 return true; 3244 } 3245 } 3246 3247 if (Ptr->getOpcode() == ISD::ADD) { 3248 isInc = true; 3249 ARM_AM::ShiftOpc ShOpcVal= ARM_AM::getShiftOpcForNode(Ptr->getOperand(0)); 3250 if (ShOpcVal != ARM_AM::no_shift) { 3251 Base = Ptr->getOperand(1); 3252 Offset = Ptr->getOperand(0); 3253 } else { 3254 Base = Ptr->getOperand(0); 3255 Offset = Ptr->getOperand(1); 3256 } 3257 return true; 3258 } 3259 3260 isInc = (Ptr->getOpcode() == ISD::ADD); 3261 Base = Ptr->getOperand(0); 3262 Offset = Ptr->getOperand(1); 3263 return true; 3264 } 3265 3266 // FIXME: Use FLDM / FSTM to emulate indexed FP load / store. 3267 return false; 3268} 3269 3270static bool getT2IndexedAddressParts(SDNode *Ptr, EVT VT, 3271 bool isSEXTLoad, SDValue &Base, 3272 SDValue &Offset, bool &isInc, 3273 SelectionDAG &DAG) { 3274 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB) 3275 return false; 3276 3277 Base = Ptr->getOperand(0); 3278 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) { 3279 int RHSC = (int)RHS->getZExtValue(); 3280 if (RHSC < 0 && RHSC > -0x100) { // 8 bits. 3281 assert(Ptr->getOpcode() == ISD::ADD); 3282 isInc = false; 3283 Offset = DAG.getConstant(-RHSC, RHS->getValueType(0)); 3284 return true; 3285 } else if (RHSC > 0 && RHSC < 0x100) { // 8 bit, no zero. 3286 isInc = Ptr->getOpcode() == ISD::ADD; 3287 Offset = DAG.getConstant(RHSC, RHS->getValueType(0)); 3288 return true; 3289 } 3290 } 3291 3292 return false; 3293} 3294 3295/// getPreIndexedAddressParts - returns true by value, base pointer and 3296/// offset pointer and addressing mode by reference if the node's address 3297/// can be legally represented as pre-indexed load / store address. 3298bool 3299ARMTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base, 3300 SDValue &Offset, 3301 ISD::MemIndexedMode &AM, 3302 SelectionDAG &DAG) const { 3303 if (Subtarget->isThumb1Only()) 3304 return false; 3305 3306 EVT VT; 3307 SDValue Ptr; 3308 bool isSEXTLoad = false; 3309 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { 3310 Ptr = LD->getBasePtr(); 3311 VT = LD->getMemoryVT(); 3312 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; 3313 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { 3314 Ptr = ST->getBasePtr(); 3315 VT = ST->getMemoryVT(); 3316 } else 3317 return false; 3318 3319 bool isInc; 3320 bool isLegal = false; 3321 if (Subtarget->isThumb() && Subtarget->hasThumb2()) 3322 isLegal = getT2IndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base, 3323 Offset, isInc, DAG); 3324 else 3325 isLegal = getARMIndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base, 3326 Offset, isInc, DAG); 3327 if (!isLegal) 3328 return false; 3329 3330 AM = isInc ? ISD::PRE_INC : ISD::PRE_DEC; 3331 return true; 3332} 3333 3334/// getPostIndexedAddressParts - returns true by value, base pointer and 3335/// offset pointer and addressing mode by reference if this node can be 3336/// combined with a load / store to form a post-indexed load / store. 3337bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 3338 SDValue &Base, 3339 SDValue &Offset, 3340 ISD::MemIndexedMode &AM, 3341 SelectionDAG &DAG) const { 3342 if (Subtarget->isThumb1Only()) 3343 return false; 3344 3345 EVT VT; 3346 SDValue Ptr; 3347 bool isSEXTLoad = false; 3348 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { 3349 VT = LD->getMemoryVT(); 3350 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; 3351 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { 3352 VT = ST->getMemoryVT(); 3353 } else 3354 return false; 3355 3356 bool isInc; 3357 bool isLegal = false; 3358 if (Subtarget->isThumb() && Subtarget->hasThumb2()) 3359 isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset, 3360 isInc, DAG); 3361 else 3362 isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset, 3363 isInc, DAG); 3364 if (!isLegal) 3365 return false; 3366 3367 AM = isInc ? ISD::POST_INC : ISD::POST_DEC; 3368 return true; 3369} 3370 3371void ARMTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, 3372 const APInt &Mask, 3373 APInt &KnownZero, 3374 APInt &KnownOne, 3375 const SelectionDAG &DAG, 3376 unsigned Depth) const { 3377 KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); 3378 switch (Op.getOpcode()) { 3379 default: break; 3380 case ARMISD::CMOV: { 3381 // Bits are known zero/one if known on the LHS and RHS. 3382 DAG.ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1); 3383 if (KnownZero == 0 && KnownOne == 0) return; 3384 3385 APInt KnownZeroRHS, KnownOneRHS; 3386 DAG.ComputeMaskedBits(Op.getOperand(1), Mask, 3387 KnownZeroRHS, KnownOneRHS, Depth+1); 3388 KnownZero &= KnownZeroRHS; 3389 KnownOne &= KnownOneRHS; 3390 return; 3391 } 3392 } 3393} 3394 3395//===----------------------------------------------------------------------===// 3396// ARM Inline Assembly Support 3397//===----------------------------------------------------------------------===// 3398 3399/// getConstraintType - Given a constraint letter, return the type of 3400/// constraint it is for this target. 3401ARMTargetLowering::ConstraintType 3402ARMTargetLowering::getConstraintType(const std::string &Constraint) const { 3403 if (Constraint.size() == 1) { 3404 switch (Constraint[0]) { 3405 default: break; 3406 case 'l': return C_RegisterClass; 3407 case 'w': return C_RegisterClass; 3408 } 3409 } 3410 return TargetLowering::getConstraintType(Constraint); 3411} 3412 3413std::pair<unsigned, const TargetRegisterClass*> 3414ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, 3415 EVT VT) const { 3416 if (Constraint.size() == 1) { 3417 // GCC RS6000 Constraint Letters 3418 switch (Constraint[0]) { 3419 case 'l': 3420 if (Subtarget->isThumb1Only()) 3421 return std::make_pair(0U, ARM::tGPRRegisterClass); 3422 else 3423 return std::make_pair(0U, ARM::GPRRegisterClass); 3424 case 'r': 3425 return std::make_pair(0U, ARM::GPRRegisterClass); 3426 case 'w': 3427 if (VT == MVT::f32) 3428 return std::make_pair(0U, ARM::SPRRegisterClass); 3429 if (VT == MVT::f64) 3430 return std::make_pair(0U, ARM::DPRRegisterClass); 3431 break; 3432 } 3433 } 3434 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 3435} 3436 3437std::vector<unsigned> ARMTargetLowering:: 3438getRegClassForInlineAsmConstraint(const std::string &Constraint, 3439 EVT VT) const { 3440 if (Constraint.size() != 1) 3441 return std::vector<unsigned>(); 3442 3443 switch (Constraint[0]) { // GCC ARM Constraint Letters 3444 default: break; 3445 case 'l': 3446 return make_vector<unsigned>(ARM::R0, ARM::R1, ARM::R2, ARM::R3, 3447 ARM::R4, ARM::R5, ARM::R6, ARM::R7, 3448 0); 3449 case 'r': 3450 return make_vector<unsigned>(ARM::R0, ARM::R1, ARM::R2, ARM::R3, 3451 ARM::R4, ARM::R5, ARM::R6, ARM::R7, 3452 ARM::R8, ARM::R9, ARM::R10, ARM::R11, 3453 ARM::R12, ARM::LR, 0); 3454 case 'w': 3455 if (VT == MVT::f32) 3456 return make_vector<unsigned>(ARM::S0, ARM::S1, ARM::S2, ARM::S3, 3457 ARM::S4, ARM::S5, ARM::S6, ARM::S7, 3458 ARM::S8, ARM::S9, ARM::S10, ARM::S11, 3459 ARM::S12,ARM::S13,ARM::S14,ARM::S15, 3460 ARM::S16,ARM::S17,ARM::S18,ARM::S19, 3461 ARM::S20,ARM::S21,ARM::S22,ARM::S23, 3462 ARM::S24,ARM::S25,ARM::S26,ARM::S27, 3463 ARM::S28,ARM::S29,ARM::S30,ARM::S31, 0); 3464 if (VT == MVT::f64) 3465 return make_vector<unsigned>(ARM::D0, ARM::D1, ARM::D2, ARM::D3, 3466 ARM::D4, ARM::D5, ARM::D6, ARM::D7, 3467 ARM::D8, ARM::D9, ARM::D10,ARM::D11, 3468 ARM::D12,ARM::D13,ARM::D14,ARM::D15, 0); 3469 break; 3470 } 3471 3472 return std::vector<unsigned>(); 3473} 3474 3475/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops 3476/// vector. If it is invalid, don't add anything to Ops. 3477void ARMTargetLowering::LowerAsmOperandForConstraint(SDValue Op, 3478 char Constraint, 3479 bool hasMemory, 3480 std::vector<SDValue>&Ops, 3481 SelectionDAG &DAG) const { 3482 SDValue Result(0, 0); 3483 3484 switch (Constraint) { 3485 default: break; 3486 case 'I': case 'J': case 'K': case 'L': 3487 case 'M': case 'N': case 'O': 3488 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op); 3489 if (!C) 3490 return; 3491 3492 int64_t CVal64 = C->getSExtValue(); 3493 int CVal = (int) CVal64; 3494 // None of these constraints allow values larger than 32 bits. Check 3495 // that the value fits in an int. 3496 if (CVal != CVal64) 3497 return; 3498 3499 switch (Constraint) { 3500 case 'I': 3501 if (Subtarget->isThumb1Only()) { 3502 // This must be a constant between 0 and 255, for ADD 3503 // immediates. 3504 if (CVal >= 0 && CVal <= 255) 3505 break; 3506 } else if (Subtarget->isThumb2()) { 3507 // A constant that can be used as an immediate value in a 3508 // data-processing instruction. 3509 if (ARM_AM::getT2SOImmVal(CVal) != -1) 3510 break; 3511 } else { 3512 // A constant that can be used as an immediate value in a 3513 // data-processing instruction. 3514 if (ARM_AM::getSOImmVal(CVal) != -1) 3515 break; 3516 } 3517 return; 3518 3519 case 'J': 3520 if (Subtarget->isThumb()) { // FIXME thumb2 3521 // This must be a constant between -255 and -1, for negated ADD 3522 // immediates. This can be used in GCC with an "n" modifier that 3523 // prints the negated value, for use with SUB instructions. It is 3524 // not useful otherwise but is implemented for compatibility. 3525 if (CVal >= -255 && CVal <= -1) 3526 break; 3527 } else { 3528 // This must be a constant between -4095 and 4095. It is not clear 3529 // what this constraint is intended for. Implemented for 3530 // compatibility with GCC. 3531 if (CVal >= -4095 && CVal <= 4095) 3532 break; 3533 } 3534 return; 3535 3536 case 'K': 3537 if (Subtarget->isThumb1Only()) { 3538 // A 32-bit value where only one byte has a nonzero value. Exclude 3539 // zero to match GCC. This constraint is used by GCC internally for 3540 // constants that can be loaded with a move/shift combination. 3541 // It is not useful otherwise but is implemented for compatibility. 3542 if (CVal != 0 && ARM_AM::isThumbImmShiftedVal(CVal)) 3543 break; 3544 } else if (Subtarget->isThumb2()) { 3545 // A constant whose bitwise inverse can be used as an immediate 3546 // value in a data-processing instruction. This can be used in GCC 3547 // with a "B" modifier that prints the inverted value, for use with 3548 // BIC and MVN instructions. It is not useful otherwise but is 3549 // implemented for compatibility. 3550 if (ARM_AM::getT2SOImmVal(~CVal) != -1) 3551 break; 3552 } else { 3553 // A constant whose bitwise inverse can be used as an immediate 3554 // value in a data-processing instruction. This can be used in GCC 3555 // with a "B" modifier that prints the inverted value, for use with 3556 // BIC and MVN instructions. It is not useful otherwise but is 3557 // implemented for compatibility. 3558 if (ARM_AM::getSOImmVal(~CVal) != -1) 3559 break; 3560 } 3561 return; 3562 3563 case 'L': 3564 if (Subtarget->isThumb1Only()) { 3565 // This must be a constant between -7 and 7, 3566 // for 3-operand ADD/SUB immediate instructions. 3567 if (CVal >= -7 && CVal < 7) 3568 break; 3569 } else if (Subtarget->isThumb2()) { 3570 // A constant whose negation can be used as an immediate value in a 3571 // data-processing instruction. This can be used in GCC with an "n" 3572 // modifier that prints the negated value, for use with SUB 3573 // instructions. It is not useful otherwise but is implemented for 3574 // compatibility. 3575 if (ARM_AM::getT2SOImmVal(-CVal) != -1) 3576 break; 3577 } else { 3578 // A constant whose negation can be used as an immediate value in a 3579 // data-processing instruction. This can be used in GCC with an "n" 3580 // modifier that prints the negated value, for use with SUB 3581 // instructions. It is not useful otherwise but is implemented for 3582 // compatibility. 3583 if (ARM_AM::getSOImmVal(-CVal) != -1) 3584 break; 3585 } 3586 return; 3587 3588 case 'M': 3589 if (Subtarget->isThumb()) { // FIXME thumb2 3590 // This must be a multiple of 4 between 0 and 1020, for 3591 // ADD sp + immediate. 3592 if ((CVal >= 0 && CVal <= 1020) && ((CVal & 3) == 0)) 3593 break; 3594 } else { 3595 // A power of two or a constant between 0 and 32. This is used in 3596 // GCC for the shift amount on shifted register operands, but it is 3597 // useful in general for any shift amounts. 3598 if ((CVal >= 0 && CVal <= 32) || ((CVal & (CVal - 1)) == 0)) 3599 break; 3600 } 3601 return; 3602 3603 case 'N': 3604 if (Subtarget->isThumb()) { // FIXME thumb2 3605 // This must be a constant between 0 and 31, for shift amounts. 3606 if (CVal >= 0 && CVal <= 31) 3607 break; 3608 } 3609 return; 3610 3611 case 'O': 3612 if (Subtarget->isThumb()) { // FIXME thumb2 3613 // This must be a multiple of 4 between -508 and 508, for 3614 // ADD/SUB sp = sp + immediate. 3615 if ((CVal >= -508 && CVal <= 508) && ((CVal & 3) == 0)) 3616 break; 3617 } 3618 return; 3619 } 3620 Result = DAG.getTargetConstant(CVal, Op.getValueType()); 3621 break; 3622 } 3623 3624 if (Result.getNode()) { 3625 Ops.push_back(Result); 3626 return; 3627 } 3628 return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, hasMemory, 3629 Ops, DAG); 3630} 3631