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