1bb481f882093fb738d2bb15610c79364bada5496Jia Liu//===-- MipsISelLowering.cpp - Mips DAG Lowering Implementation -----------===//
2972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
3972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//                     The LLVM Compiler Infrastructure
4972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
84552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
9972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
10972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// This file defines the interfaces that Mips uses to lower LLVM code into a
11972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// selection DAG.
12972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
134552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
14972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#define DEBUG_TYPE "mips-lower"
15972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "MipsISelLowering.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "InstPrinter/MipsInstPrinter.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/MipsBaseInfo.h"
18a2b1bb5296624d32a200f9c53d6f26c0c9c3bddcBruno Cardoso Lopes#include "MipsMachineFunction.h"
19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MipsSubtarget.h"
20972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "MipsTargetMachine.h"
21b71b909bc76f48377fc96547d53a088346852600Chris Lattner#include "MipsTargetObjectFile.h"
222b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka#include "llvm/ADT/Statistic.h"
23972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/CallingConvLower.h"
24972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/MachineFrameInfo.h"
25972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/MachineFunction.h"
26972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/MachineInstrBuilder.h"
2784bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h"
28972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/SelectionDAGISel.h"
29972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/ValueTypes.h"
300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h"
310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h"
330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h"
342b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka#include "llvm/Support/CommandLine.h"
35972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/Support/Debug.h"
36c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
378959393533bfbdcbbfe3c5f336729394896100ceNAKAMURA Takumi#include "llvm/Support/raw_ostream.h"
388959393533bfbdcbbfe3c5f336729394896100ceNAKAMURA Takumi
39972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopesusing namespace llvm;
40972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
412b861be96ef18174c201ce6a94c5130445bc5b40Akira HatanakaSTATISTIC(NumTailCalls, "Number of tail calls");
422b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka
432b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanakastatic cl::opt<bool>
4481784cb374d7e3cbcd86f19315052d30cb7c49f9Akira HatanakaLargeGOT("mxgot", cl::Hidden,
4581784cb374d7e3cbcd86f19315052d30cb7c49f9Akira Hatanaka         cl::desc("MIPS: Enable GOT larger than 64k."), cl::init(false));
4681784cb374d7e3cbcd86f19315052d30cb7c49f9Akira Hatanaka
47fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanakastatic const uint16_t O32IntRegs[4] = {
48fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  Mips::A0, Mips::A1, Mips::A2, Mips::A3
49fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka};
50fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka
51fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanakastatic const uint16_t Mips64IntRegs[8] = {
52fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
53fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64
54fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka};
55fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka
56fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanakastatic const uint16_t Mips64DPRegs[8] = {
57fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,
58fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64
59fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka};
60fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka
61bb481f882093fb738d2bb15610c79364bada5496Jia Liu// If I is a shifted mask, set the size (Size) and the first bit of the
62dbe9a316834c79a2a3404fd484424e6c4bf49f5fAkira Hatanaka// mask (Pos), and return true.
63bb481f882093fb738d2bb15610c79364bada5496Jia Liu// For example, if I is 0x003ff800, (Pos, Size) = (11, 11).
64f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic bool isShiftedMask(uint64_t I, uint64_t &Pos, uint64_t &Size) {
65d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  if (!isShiftedMask_64(I))
66854a7db117707658625c22e546810d564f3e20eaAkira Hatanaka     return false;
67bb15e117d328bd991b0723dd1b586c8437d9dcedAkira Hatanaka
68d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  Size = CountPopulation_64(I);
69d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  Pos = CountTrailingZeros_64(I);
70dbe9a316834c79a2a3404fd484424e6c4bf49f5fAkira Hatanaka  return true;
71bb15e117d328bd991b0723dd1b586c8437d9dcedAkira Hatanaka}
72bb15e117d328bd991b0723dd1b586c8437d9dcedAkira Hatanaka
735ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaSDValue MipsTargetLowering::getGlobalReg(SelectionDAG &DAG, EVT Ty) const {
74648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka  MipsFunctionInfo *FI = DAG.getMachineFunction().getInfo<MipsFunctionInfo>();
75648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka  return DAG.getRegister(FI->getGlobalBaseReg(), Ty);
76648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka}
77648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka
786b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanakastatic SDValue getTargetNode(SDValue Op, SelectionDAG &DAG, unsigned Flag) {
796b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  EVT Ty = Op.getValueType();
806b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka
816b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  if (GlobalAddressSDNode *N = dyn_cast<GlobalAddressSDNode>(Op))
826b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka    return DAG.getTargetGlobalAddress(N->getGlobal(), Op.getDebugLoc(), Ty, 0,
836b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                                      Flag);
846b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  if (ExternalSymbolSDNode *N = dyn_cast<ExternalSymbolSDNode>(Op))
856b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka    return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag);
866b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  if (BlockAddressSDNode *N = dyn_cast<BlockAddressSDNode>(Op))
876b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka    return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, 0, Flag);
886b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  if (JumpTableSDNode *N = dyn_cast<JumpTableSDNode>(Op))
896b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka    return DAG.getTargetJumpTable(N->getIndex(), Ty, Flag);
906b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  if (ConstantPoolSDNode *N = dyn_cast<ConstantPoolSDNode>(Op))
916b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka    return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlignment(),
926b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                                     N->getOffset(), Flag);
936b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka
946b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  llvm_unreachable("Unexpected node type.");
956b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  return SDValue();
966b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka}
976b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka
986b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanakastatic SDValue getAddrNonPIC(SDValue Op, SelectionDAG &DAG) {
996b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1006b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  EVT Ty = Op.getValueType();
1016b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  SDValue Hi = getTargetNode(Op, DAG, MipsII::MO_ABS_HI);
1026b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  SDValue Lo = getTargetNode(Op, DAG, MipsII::MO_ABS_LO);
1036b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  return DAG.getNode(ISD::ADD, DL, Ty,
1046b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                     DAG.getNode(MipsISD::Hi, DL, Ty, Hi),
1056b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                     DAG.getNode(MipsISD::Lo, DL, Ty, Lo));
1066b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka}
1076b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka
1085ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaSDValue MipsTargetLowering::getAddrLocal(SDValue Op, SelectionDAG &DAG,
1095ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                         bool HasMips64) const {
1106b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1116b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  EVT Ty = Op.getValueType();
1126b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
113f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
1146b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                            getTargetNode(Op, DAG, GOTFlag));
1156b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  SDValue Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), GOT,
1166b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                             MachinePointerInfo::getGOT(), false, false, false,
1176b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                             0);
1186b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  unsigned LoFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
1196b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty, getTargetNode(Op, DAG, LoFlag));
1206b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  return DAG.getNode(ISD::ADD, DL, Ty, Load, Lo);
1216b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka}
1226b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka
1235ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaSDValue MipsTargetLowering::getAddrGlobal(SDValue Op, SelectionDAG &DAG,
1245ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                          unsigned Flag) const {
1256b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1266b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  EVT Ty = Op.getValueType();
127f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
1286b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                            getTargetNode(Op, DAG, Flag));
1296b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Tgt,
1306b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                     MachinePointerInfo::getGOT(), false, false, false, 0);
1316b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka}
1326b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka
1335ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaSDValue MipsTargetLowering::getAddrGlobalLargeGOT(SDValue Op, SelectionDAG &DAG,
1345ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                                  unsigned HiFlag,
1355ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                                  unsigned LoFlag) const {
1366b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1376b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  EVT Ty = Op.getValueType();
1386b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  SDValue Hi = DAG.getNode(MipsISD::Hi, DL, Ty, getTargetNode(Op, DAG, HiFlag));
139f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty));
1406b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
1416b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                                getTargetNode(Op, DAG, LoFlag));
1426b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka  return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Wrapper,
1436b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka                     MachinePointerInfo::getGOT(), false, false, false, 0);
1446b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka}
1456b28b80791c742f4c561eeeae399338a8903dd6dAkira Hatanaka
146f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattnerconst char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
147f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner  switch (Opcode) {
148bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::JmpLink:           return "MipsISD::JmpLink";
14958d1e3f72a61b5f8ace620c9e16baaecbb3f53f1Akira Hatanaka  case MipsISD::TailCall:          return "MipsISD::TailCall";
150bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::Hi:                return "MipsISD::Hi";
151bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::Lo:                return "MipsISD::Lo";
152bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::GPRel:             return "MipsISD::GPRel";
153d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes  case MipsISD::ThreadPointer:     return "MipsISD::ThreadPointer";
154bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::Ret:               return "MipsISD::Ret";
155544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  case MipsISD::EH_RETURN:         return "MipsISD::EH_RETURN";
156bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::FPBrcond:          return "MipsISD::FPBrcond";
157bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::FPCmp:             return "MipsISD::FPCmp";
158bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::CMovFP_T:          return "MipsISD::CMovFP_T";
159bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::CMovFP_F:          return "MipsISD::CMovFP_F";
160bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::FPRound:           return "MipsISD::FPRound";
161bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::MAdd:              return "MipsISD::MAdd";
162bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::MAddu:             return "MipsISD::MAddu";
163bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::MSub:              return "MipsISD::MSub";
164bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::MSubu:             return "MipsISD::MSubu";
165bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::DivRem:            return "MipsISD::DivRem";
166bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::DivRemU:           return "MipsISD::DivRemU";
167bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::BuildPairF64:      return "MipsISD::BuildPairF64";
168bdd2ce9741643bab00ba2869852f6babbe072cf0Akira Hatanaka  case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64";
169bfcb83fa328422d59945cbf3d72c0721e3f2f385Akira Hatanaka  case MipsISD::Wrapper:           return "MipsISD::Wrapper";
170db54826f20c6cbcb9b195c4b49c946d6488156ddAkira Hatanaka  case MipsISD::Sync:              return "MipsISD::Sync";
171bb15e117d328bd991b0723dd1b586c8437d9dcedAkira Hatanaka  case MipsISD::Ext:               return "MipsISD::Ext";
172bb15e117d328bd991b0723dd1b586c8437d9dcedAkira Hatanaka  case MipsISD::Ins:               return "MipsISD::Ins";
173b6f1dc2f09a3d633c43f3160625e3e57319443a2Akira Hatanaka  case MipsISD::LWL:               return "MipsISD::LWL";
174b6f1dc2f09a3d633c43f3160625e3e57319443a2Akira Hatanaka  case MipsISD::LWR:               return "MipsISD::LWR";
175b6f1dc2f09a3d633c43f3160625e3e57319443a2Akira Hatanaka  case MipsISD::SWL:               return "MipsISD::SWL";
176b6f1dc2f09a3d633c43f3160625e3e57319443a2Akira Hatanaka  case MipsISD::SWR:               return "MipsISD::SWR";
177b6f1dc2f09a3d633c43f3160625e3e57319443a2Akira Hatanaka  case MipsISD::LDL:               return "MipsISD::LDL";
178b6f1dc2f09a3d633c43f3160625e3e57319443a2Akira Hatanaka  case MipsISD::LDR:               return "MipsISD::LDR";
179b6f1dc2f09a3d633c43f3160625e3e57319443a2Akira Hatanaka  case MipsISD::SDL:               return "MipsISD::SDL";
180b6f1dc2f09a3d633c43f3160625e3e57319443a2Akira Hatanaka  case MipsISD::SDR:               return "MipsISD::SDR";
1816fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::EXTP:              return "MipsISD::EXTP";
1826fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::EXTPDP:            return "MipsISD::EXTPDP";
1836fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::EXTR_S_H:          return "MipsISD::EXTR_S_H";
1846fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::EXTR_W:            return "MipsISD::EXTR_W";
1856fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::EXTR_R_W:          return "MipsISD::EXTR_R_W";
1866fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::EXTR_RS_W:         return "MipsISD::EXTR_RS_W";
1876fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::SHILO:             return "MipsISD::SHILO";
1886fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::MTHLIP:            return "MipsISD::MTHLIP";
1896fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::MULT:              return "MipsISD::MULT";
1906fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::MULTU:             return "MipsISD::MULTU";
191b3ea880a706cde45818e1a0f5b162358ac8bb5bdJia Liu  case MipsISD::MADD_DSP:          return "MipsISD::MADD_DSP";
1926fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::MADDU_DSP:         return "MipsISD::MADDU_DSP";
1936fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::MSUB_DSP:          return "MipsISD::MSUB_DSP";
1946fad5e742d0213bdd68daa7d376387bcec80b5fdAkira Hatanaka  case MipsISD::MSUBU_DSP:         return "MipsISD::MSUBU_DSP";
1950f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka  default:                         return NULL;
196972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  }
197972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
198972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
199972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso LopesMipsTargetLowering::
200f0144127b98425d214e59e4a1a4b342b78e3642bChris LattnerMipsTargetLowering(MipsTargetMachine &TM)
2018b4198da9d5884f9e33c54a9537b9a8eed4deff7Akira Hatanaka  : TargetLowering(TM, new MipsTargetObjectFile()),
2028b4198da9d5884f9e33c54a9537b9a8eed4deff7Akira Hatanaka    Subtarget(&TM.getSubtarget<MipsSubtarget>()),
2032ec69faf2615ccdffffacff9033b2228c589971cAkira Hatanaka    HasMips64(Subtarget->hasMips64()), IsN64(Subtarget->isABI_N64()),
2042ec69faf2615ccdffffacff9033b2228c589971cAkira Hatanaka    IsO32(Subtarget->isABI_O32()) {
205972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // Mips does not have i1 type, so use i32 for
206bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // setcc operations results (slt, sgt, ...).
20703228089d5235f8c90477f88809139464e9c6ea5Duncan Sands  setBooleanContents(ZeroOrOneBooleanContent);
20828b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
209972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
210bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // Load extented operations for i1 types must be promoted
211825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setLoadExtAction(ISD::EXTLOAD,  MVT::i1,  Promote);
212825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setLoadExtAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
213825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setLoadExtAction(ISD::SEXTLOAD, MVT::i1,  Promote);
214972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2156055a6adb792f857fe04d8880a6cfb8914828046Eli Friedman  // MIPS doesn't have extending float->double load/store
216825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
217825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setTruncStoreAction(MVT::f64, MVT::f32, Expand);
21810a365910158a1c3749cd614f29109f78d62beecEli Friedman
219bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // Used by legalize types to correctly generate the setcc result.
220bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // Without this, every float setcc comes with a AND/OR with the result,
221bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // we don't want this, since the fpcmp result goes to a flag register,
222772837778b831a52231ff33ef42d7970e9aa8467Bruno Cardoso Lopes  // which is used implicitly by brcond and select operations.
223825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
224772837778b831a52231ff33ef42d7970e9aa8467Bruno Cardoso Lopes
22597c2537269e8c654bc9b3c471ebab927e9cf0b2aBruno Cardoso Lopes  // Mips Custom Operations
226b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  setOperationAction(ISD::BR_JT,              MVT::Other, Custom);
227825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::GlobalAddress,      MVT::i32,   Custom);
228ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes  setOperationAction(ISD::BlockAddress,       MVT::i32,   Custom);
229825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::GlobalTLSAddress,   MVT::i32,   Custom);
230825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::JumpTable,          MVT::i32,   Custom);
231825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ConstantPool,       MVT::i32,   Custom);
232825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,             MVT::f32,   Custom);
233825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,             MVT::f64,   Custom);
234825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,             MVT::i32,   Custom);
2353fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka  setOperationAction(ISD::SELECT_CC,          MVT::f32,   Custom);
2363fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka  setOperationAction(ISD::SELECT_CC,          MVT::f64,   Custom);
2370a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka  setOperationAction(ISD::SETCC,              MVT::f32,   Custom);
2380a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka  setOperationAction(ISD::SETCC,              MVT::f64,   Custom);
239825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BRCOND,             MVT::Other, Custom);
2406059b8551dc1ddc24bb5830426bf7e11d394a426Bruno Cardoso Lopes  setOperationAction(ISD::VASTART,            MVT::Other, Custom);
241d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka  setOperationAction(ISD::FCOPYSIGN,          MVT::f32,   Custom);
242d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka  setOperationAction(ISD::FCOPYSIGN,          MVT::f64,   Custom);
243d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka
244c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  if (!TM.Options.NoNaNsFPMath) {
245c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    setOperationAction(ISD::FABS,             MVT::f32,   Custom);
246c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    setOperationAction(ISD::FABS,             MVT::f64,   Custom);
247c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  }
248c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
249d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka  if (HasMips64) {
250d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka    setOperationAction(ISD::GlobalAddress,      MVT::i64,   Custom);
251d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka    setOperationAction(ISD::BlockAddress,       MVT::i64,   Custom);
252d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka    setOperationAction(ISD::GlobalTLSAddress,   MVT::i64,   Custom);
253d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka    setOperationAction(ISD::JumpTable,          MVT::i64,   Custom);
254d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka    setOperationAction(ISD::ConstantPool,       MVT::i64,   Custom);
255d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka    setOperationAction(ISD::SELECT,             MVT::i64,   Custom);
2567664f05326f8426b6f9b978fd1f79aca91135703Akira Hatanaka    setOperationAction(ISD::LOAD,               MVT::i64,   Custom);
2577664f05326f8426b6f9b978fd1f79aca91135703Akira Hatanaka    setOperationAction(ISD::STORE,              MVT::i64,   Custom);
258d229b7b8f4495a0471f3d2812050bfaa3a209e39Akira Hatanaka  }
2596059b8551dc1ddc24bb5830426bf7e11d394a426Bruno Cardoso Lopes
260a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  if (!HasMips64) {
261a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka    setOperationAction(ISD::SHL_PARTS,          MVT::i32,   Custom);
262a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka    setOperationAction(ISD::SRA_PARTS,          MVT::i32,   Custom);
263a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka    setOperationAction(ISD::SRL_PARTS,          MVT::i32,   Custom);
264a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  }
265a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka
266e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  setOperationAction(ISD::ADD,                MVT::i32,   Custom);
267e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  if (HasMips64)
268e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka    setOperationAction(ISD::ADD,                MVT::i64,   Custom);
269e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka
27038b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  setOperationAction(ISD::SDIV, MVT::i32, Expand);
27138b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  setOperationAction(ISD::SREM, MVT::i32, Expand);
27238b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  setOperationAction(ISD::UDIV, MVT::i32, Expand);
27338b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  setOperationAction(ISD::UREM, MVT::i32, Expand);
274dda4a07cd818fdfe2b49412e32e0e12d9e566e31Akira Hatanaka  setOperationAction(ISD::SDIV, MVT::i64, Expand);
275dda4a07cd818fdfe2b49412e32e0e12d9e566e31Akira Hatanaka  setOperationAction(ISD::SREM, MVT::i64, Expand);
276dda4a07cd818fdfe2b49412e32e0e12d9e566e31Akira Hatanaka  setOperationAction(ISD::UDIV, MVT::i64, Expand);
277dda4a07cd818fdfe2b49412e32e0e12d9e566e31Akira Hatanaka  setOperationAction(ISD::UREM, MVT::i64, Expand);
27838b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes
27997c2537269e8c654bc9b3c471ebab927e9cf0b2aBruno Cardoso Lopes  // Operations not directly supported by Mips.
2803ef5383b3537a420c5e2ab3e657c378e5185549dTom Stellard  setOperationAction(ISD::BR_CC,             MVT::f32,   Expand);
2813ef5383b3537a420c5e2ab3e657c378e5185549dTom Stellard  setOperationAction(ISD::BR_CC,             MVT::f64,   Expand);
2823ef5383b3537a420c5e2ab3e657c378e5185549dTom Stellard  setOperationAction(ISD::BR_CC,             MVT::i32,   Expand);
2833ef5383b3537a420c5e2ab3e657c378e5185549dTom Stellard  setOperationAction(ISD::BR_CC,             MVT::i64,   Expand);
284825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,         MVT::Other, Expand);
285825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UINT_TO_FP,        MVT::i32,   Expand);
286e1bcd6b5c67968910d0262cd9bebd39db6887357Akira Hatanaka  setOperationAction(ISD::UINT_TO_FP,        MVT::i64,   Expand);
287825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FP_TO_UINT,        MVT::i32,   Expand);
288e1bcd6b5c67968910d0262cd9bebd39db6887357Akira Hatanaka  setOperationAction(ISD::FP_TO_UINT,        MVT::i64,   Expand);
289825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1,    Expand);
290825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,             MVT::i32,   Expand);
2917f162743fc7d68b19a6e21bba2a0aa810fc7897fAkira Hatanaka  setOperationAction(ISD::CTPOP,             MVT::i64,   Expand);
292825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,              MVT::i32,   Expand);
2937f162743fc7d68b19a6e21bba2a0aa810fc7897fAkira Hatanaka  setOperationAction(ISD::CTTZ,              MVT::i64,   Expand);
29463974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTTZ_ZERO_UNDEF,   MVT::i32,   Expand);
29563974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTTZ_ZERO_UNDEF,   MVT::i64,   Expand);
29663974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTLZ_ZERO_UNDEF,   MVT::i32,   Expand);
29763974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTLZ_ZERO_UNDEF,   MVT::i64,   Expand);
298825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,              MVT::i32,   Expand);
299c7bafe9241c0742e71f7fd1b83e0c5b3acee0dacAkira Hatanaka  setOperationAction(ISD::ROTL,              MVT::i64,   Expand);
3001d165f1c252d1541b4788bf81092a9299cc764e5Akira Hatanaka  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32,  Expand);
3011d165f1c252d1541b4788bf81092a9299cc764e5Akira Hatanaka  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64,  Expand);
302908b6ddad6dac40c4c0453d690f0db9422b48b10Bruno Cardoso Lopes
30356633441271106376b39a47bbe5b59f85144b64dAkira Hatanaka  if (!Subtarget->hasMips32r2())
304908b6ddad6dac40c4c0453d690f0db9422b48b10Bruno Cardoso Lopes    setOperationAction(ISD::ROTR, MVT::i32,   Expand);
305908b6ddad6dac40c4c0453d690f0db9422b48b10Bruno Cardoso Lopes
306c7bafe9241c0742e71f7fd1b83e0c5b3acee0dacAkira Hatanaka  if (!Subtarget->hasMips64r2())
307c7bafe9241c0742e71f7fd1b83e0c5b3acee0dacAkira Hatanaka    setOperationAction(ISD::ROTR, MVT::i64,   Expand);
308c7bafe9241c0742e71f7fd1b83e0c5b3acee0dacAkira Hatanaka
309825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FSIN,              MVT::f32,   Expand);
3105d6fb5db908c90fde727b6d07c4f0b8be7d91797Bruno Cardoso Lopes  setOperationAction(ISD::FSIN,              MVT::f64,   Expand);
311825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FCOS,              MVT::f32,   Expand);
3125d6fb5db908c90fde727b6d07c4f0b8be7d91797Bruno Cardoso Lopes  setOperationAction(ISD::FCOS,              MVT::f64,   Expand);
3138688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng  setOperationAction(ISD::FSINCOS,           MVT::f32,   Expand);
3148688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng  setOperationAction(ISD::FSINCOS,           MVT::f64,   Expand);
315825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FPOWI,             MVT::f32,   Expand);
316825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FPOW,              MVT::f32,   Expand);
31746da136ec79f484decce7c6cfeef42fb25888996Akira Hatanaka  setOperationAction(ISD::FPOW,              MVT::f64,   Expand);
318825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FLOG,              MVT::f32,   Expand);
319825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FLOG2,             MVT::f32,   Expand);
320825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FLOG10,            MVT::f32,   Expand);
321825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::FEXP,              MVT::f32,   Expand);
32233390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich  setOperationAction(ISD::FMA,               MVT::f32,   Expand);
32333390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich  setOperationAction(ISD::FMA,               MVT::f64,   Expand);
32421ecc2f4edbbc2c4ec1c2e2c87dc5a5ee6f58a68Akira Hatanaka  setOperationAction(ISD::FREM,              MVT::f32,   Expand);
32521ecc2f4edbbc2c4ec1c2e2c87dc5a5ee6f58a68Akira Hatanaka  setOperationAction(ISD::FREM,              MVT::f64,   Expand);
32697c2537269e8c654bc9b3c471ebab927e9cf0b2aBruno Cardoso Lopes
3271cc6333161be8bbeb516bc7c74d4400dca58b997Akira Hatanaka  if (!TM.Options.NoNaNsFPMath) {
3281cc6333161be8bbeb516bc7c74d4400dca58b997Akira Hatanaka    setOperationAction(ISD::FNEG,             MVT::f32,   Expand);
3291cc6333161be8bbeb516bc7c74d4400dca58b997Akira Hatanaka    setOperationAction(ISD::FNEG,             MVT::f64,   Expand);
3301cc6333161be8bbeb516bc7c74d4400dca58b997Akira Hatanaka  }
3311cc6333161be8bbeb516bc7c74d4400dca58b997Akira Hatanaka
332cf0cd8005c81853ddea3ce26b71491c48dc4984eAkira Hatanaka  setOperationAction(ISD::EXCEPTIONADDR,     MVT::i32, Expand);
333590baca06c1e87a18070d606b36e0985e9b61afcAkira Hatanaka  setOperationAction(ISD::EXCEPTIONADDR,     MVT::i64, Expand);
334cf0cd8005c81853ddea3ce26b71491c48dc4984eAkira Hatanaka  setOperationAction(ISD::EHSELECTION,       MVT::i32, Expand);
335590baca06c1e87a18070d606b36e0985e9b61afcAkira Hatanaka  setOperationAction(ISD::EHSELECTION,       MVT::i64, Expand);
336471e4224809f51652c71f319532697a879a75a0dEric Christopher
337544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
338544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
339954dac0f88bcb27c06ce467c43e913ff0aa511bbBruno Cardoso Lopes  setOperationAction(ISD::VAARG,             MVT::Other, Expand);
340954dac0f88bcb27c06ce467c43e913ff0aa511bbBruno Cardoso Lopes  setOperationAction(ISD::VACOPY,            MVT::Other, Expand);
341954dac0f88bcb27c06ce467c43e913ff0aa511bbBruno Cardoso Lopes  setOperationAction(ISD::VAEND,             MVT::Other, Expand);
342954dac0f88bcb27c06ce467c43e913ff0aa511bbBruno Cardoso Lopes
343b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
344b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka  setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
345b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka
34697c2537269e8c654bc9b3c471ebab927e9cf0b2aBruno Cardoso Lopes  // Use the default for now
347825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::STACKSAVE,         MVT::Other, Expand);
348825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::STACKRESTORE,      MVT::Other, Expand);
34914648468011c92a4210f8118721d58c25043daf8Eli Friedman
350bb481f882093fb738d2bb15610c79364bada5496Jia Liu  setOperationAction(ISD::ATOMIC_LOAD,       MVT::i32,    Expand);
351bb481f882093fb738d2bb15610c79364bada5496Jia Liu  setOperationAction(ISD::ATOMIC_LOAD,       MVT::i64,    Expand);
352bb481f882093fb738d2bb15610c79364bada5496Jia Liu  setOperationAction(ISD::ATOMIC_STORE,      MVT::i32,    Expand);
353bb481f882093fb738d2bb15610c79364bada5496Jia Liu  setOperationAction(ISD::ATOMIC_STORE,      MVT::i64,    Expand);
3544db5acaf48c119b2bb7ad93b10dfcfe8b58dcfdbEli Friedman
35526689ac37ebec3b358588089415509285e558de9Eli Friedman  setInsertFencesForAtomic(true);
35626689ac37ebec3b358588089415509285e558de9Eli Friedman
3577728f7e890fd326af6948c52092fc9ea4f38c986Bruno Cardoso Lopes  if (!Subtarget->hasSEInReg()) {
358825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8,  Expand);
359825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
360225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  }
361225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes
362c79507a4dd0c64e3d96fee6c57d0b2e3d14f4b77Akira Hatanaka  if (!Subtarget->hasBitCount()) {
363825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    setOperationAction(ISD::CTLZ, MVT::i32, Expand);
364c79507a4dd0c64e3d96fee6c57d0b2e3d14f4b77Akira Hatanaka    setOperationAction(ISD::CTLZ, MVT::i64, Expand);
365c79507a4dd0c64e3d96fee6c57d0b2e3d14f4b77Akira Hatanaka  }
36665ad452536526fe9a80023abc3703a7cc7987858Bruno Cardoso Lopes
367c0ea04389c9fc0b73d0cbd90ec3a5bc076d25d7bAkira Hatanaka  if (!Subtarget->hasSwap()) {
368825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    setOperationAction(ISD::BSWAP, MVT::i32, Expand);
369c0ea04389c9fc0b73d0cbd90ec3a5bc076d25d7bAkira Hatanaka    setOperationAction(ISD::BSWAP, MVT::i64, Expand);
370c0ea04389c9fc0b73d0cbd90ec3a5bc076d25d7bAkira Hatanaka  }
371739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes
3727664f05326f8426b6f9b978fd1f79aca91135703Akira Hatanaka  if (HasMips64) {
3737664f05326f8426b6f9b978fd1f79aca91135703Akira Hatanaka    setLoadExtAction(ISD::SEXTLOAD, MVT::i32, Custom);
3747664f05326f8426b6f9b978fd1f79aca91135703Akira Hatanaka    setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, Custom);
3757664f05326f8426b6f9b978fd1f79aca91135703Akira Hatanaka    setLoadExtAction(ISD::EXTLOAD, MVT::i32, Custom);
3767664f05326f8426b6f9b978fd1f79aca91135703Akira Hatanaka    setTruncStoreAction(MVT::i64, MVT::i32, Custom);
3777664f05326f8426b6f9b978fd1f79aca91135703Akira Hatanaka  }
3787664f05326f8426b6f9b978fd1f79aca91135703Akira Hatanaka
3798be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  setTargetDAGCombine(ISD::ADDE);
3808be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  setTargetDAGCombine(ISD::SUBE);
38138b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  setTargetDAGCombine(ISD::SDIVREM);
38238b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  setTargetDAGCombine(ISD::UDIVREM);
383ee8c3b03fb96d37315544149a295c29b0d4de8c8Akira Hatanaka  setTargetDAGCombine(ISD::SELECT);
38477b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  setTargetDAGCombine(ISD::AND);
38577b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  setTargetDAGCombine(ISD::OR);
3868782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  setTargetDAGCombine(ISD::ADD);
3878be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
3885fdf50065d1b481aed3222477f61f1075459210dAkira Hatanaka  setMinFunctionAlignment(HasMips64 ? 3 : 2);
389fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman
3903f5b107a4b48e469899267238dcb7e204963ce0eAkira Hatanaka  setStackPointerRegisterToSaveRestore(IsN64 ? Mips::SP_64 : Mips::SP);
391cf0cd8005c81853ddea3ce26b71491c48dc4984eAkira Hatanaka
392590baca06c1e87a18070d606b36e0985e9b61afcAkira Hatanaka  setExceptionPointerRegister(IsN64 ? Mips::A0_64 : Mips::A0);
393590baca06c1e87a18070d606b36e0985e9b61afcAkira Hatanaka  setExceptionSelectorRegister(IsN64 ? Mips::A1_64 : Mips::A1);
394e193b325837bee5f9a848a16077a6e156fe88fbaAkira Hatanaka
3953450f800aa65c91f0496816ba6061a422a74c1feJim Grosbach  MaxStoresPerMemcpy = 16;
396972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
397972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
3985ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakaconst MipsTargetLowering *MipsTargetLowering::create(MipsTargetMachine &TM) {
3995ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (TM.getSubtargetImpl()->inMips16Mode())
4005ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return llvm::createMips16TargetLowering(TM);
401bb481f882093fb738d2bb15610c79364bada5496Jia Liu
4025ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  return llvm::createMipsSETargetLowering(TM);
4035c21c9e78ebbb5b766fac31bf30433926dcc2a5dAkira Hatanaka}
4045c21c9e78ebbb5b766fac31bf30433926dcc2a5dAkira Hatanaka
40528b77e968d2b01fc9da724762bd8ddcd80650e32Duncan SandsEVT MipsTargetLowering::getSetCCResultType(EVT VT) const {
406e13f441e002b95bb64d883d173f6aff9615556fdAkira Hatanaka  if (!VT.isVector())
407e13f441e002b95bb64d883d173f6aff9615556fdAkira Hatanaka    return MVT::i32;
408e13f441e002b95bb64d883d173f6aff9615556fdAkira Hatanaka  return VT.changeVectorElementTypeToInteger();
4095b8f82e35b51bf007de07a7ca9347d804084ddf8Scott Michel}
4105b8f82e35b51bf007de07a7ca9347d804084ddf8Scott Michel
411f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka// selectMADD -
4128be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes// Transforms a subgraph in CurDAG if the following pattern is found:
4138be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes//  (addc multLo, Lo0), (adde multHi, Hi0),
4148be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes// where,
4158be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes//  multHi/Lo: product of multiplication
4168e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes//  Lo0: initial value of Lo register
4178e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes//  Hi0: initial value of Hi register
41881bd78b89779704aeb762f51c6c19b06d542b6d6Akira Hatanaka// Return true if pattern matching was successful.
419f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
4208e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes  // ADDENode's second operand must be a flag output of an ADDC node in order
4218be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // for the matching to be successful.
422864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka  SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
4238be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4248be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (ADDCNode->getOpcode() != ISD::ADDC)
4258be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
4268be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4278be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  SDValue MultHi = ADDENode->getOperand(0);
4288be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  SDValue MultLo = ADDCNode->getOperand(0);
429864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka  SDNode *MultNode = MultHi.getNode();
4308be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  unsigned MultOpc = MultHi.getOpcode();
4318be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4328be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // MultHi and MultLo must be generated by the same node,
4338be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (MultLo.getNode() != MultNode)
4348be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
4358be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4368be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // and it must be a multiplication.
4378be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
4388be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
4398e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes
4408e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes  // MultLo amd MultHi must be the first and second output of MultNode
4418e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes  // respectively.
4428be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
4438be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
4448be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4458e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes  // Transform this to a MADD only if ADDENode and ADDCNode are the only users
4468be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // of the values of MultNode, in which case MultNode will be removed in later
4478be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // phases.
4484552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka  // If there exist users other than ADDENode or ADDCNode, this function returns
4494552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka  // here, which will result in MultNode being mapped to a single MULT
4508e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes  // instruction node rather than a pair of MULT and MADD instructions being
4518be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // produced.
4528be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
4538be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
4548be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4558e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes  SDValue Chain = CurDAG->getEntryNode();
456f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = ADDENode->getDebugLoc();
4578be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4588be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // create MipsMAdd(u) node
4598be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
4608e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes
461f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Glue,
4628be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                 MultNode->getOperand(0),// Factor 0
4638be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                 MultNode->getOperand(1),// Factor 1
4648e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes                                 ADDCNode->getOperand(1),// Lo0
4658be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                 ADDENode->getOperand(1));// Hi0
4668be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4678be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // create CopyFromReg nodes
468f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue CopyFromLo = CurDAG->getCopyFromReg(Chain, DL, Mips::LO, MVT::i32,
4698be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                              MAdd);
470f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue CopyFromHi = CurDAG->getCopyFromReg(CopyFromLo.getValue(1), DL,
4718be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                              Mips::HI, MVT::i32,
4728be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                              CopyFromLo.getValue(2));
4738be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4748be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // replace uses of adde and addc here
4758be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (!SDValue(ADDCNode, 0).use_empty())
4768be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), CopyFromLo);
4778be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4788be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (!SDValue(ADDENode, 0).use_empty())
4798be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), CopyFromHi);
4808be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4818e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes  return true;
4828be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes}
4838be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
484f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka// selectMSUB -
4858be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes// Transforms a subgraph in CurDAG if the following pattern is found:
4868be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes//  (addc Lo0, multLo), (sube Hi0, multHi),
4878be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes// where,
4888be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes//  multHi/Lo: product of multiplication
4898e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes//  Lo0: initial value of Lo register
4908e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes//  Hi0: initial value of Hi register
49181bd78b89779704aeb762f51c6c19b06d542b6d6Akira Hatanaka// Return true if pattern matching was successful.
492f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
4938e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes  // SUBENode's second operand must be a flag output of an SUBC node in order
4948be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // for the matching to be successful.
495864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka  SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
4968be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
4978be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (SUBCNode->getOpcode() != ISD::SUBC)
4988be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
4998be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5008be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  SDValue MultHi = SUBENode->getOperand(1);
5018be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  SDValue MultLo = SUBCNode->getOperand(1);
502864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka  SDNode *MultNode = MultHi.getNode();
5038be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  unsigned MultOpc = MultHi.getOpcode();
5048be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5058be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // MultHi and MultLo must be generated by the same node,
5068be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (MultLo.getNode() != MultNode)
5078be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
5088be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5098be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // and it must be a multiplication.
5108be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
5118be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
5128be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5138be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // MultLo amd MultHi must be the first and second output of MultNode
5148be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // respectively.
5158be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
5168be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
5178be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5188be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
5198be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // of the values of MultNode, in which case MultNode will be removed in later
5208be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // phases.
5214552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka  // If there exist users other than SUBENode or SUBCNode, this function returns
5224552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka  // here, which will result in MultNode being mapped to a single MULT
5238be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // instruction node rather than a pair of MULT and MSUB instructions being
5248be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // produced.
5258be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
5268be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return false;
5278be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5288be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  SDValue Chain = CurDAG->getEntryNode();
529f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = SUBENode->getDebugLoc();
5308be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5318be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // create MipsSub(u) node
5328be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
5338be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
534f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
5358be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                 MultNode->getOperand(0),// Factor 0
5368be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                 MultNode->getOperand(1),// Factor 1
5378be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                 SUBCNode->getOperand(0),// Lo0
5388be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                 SUBENode->getOperand(0));// Hi0
5398be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5408be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // create CopyFromReg nodes
541f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue CopyFromLo = CurDAG->getCopyFromReg(Chain, DL, Mips::LO, MVT::i32,
5428be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                              MSub);
543f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue CopyFromHi = CurDAG->getCopyFromReg(CopyFromLo.getValue(1), DL,
5448be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                              Mips::HI, MVT::i32,
5458be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                              CopyFromLo.getValue(2));
5468be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5478be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  // replace uses of sube and subc here
5488be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (!SDValue(SUBCNode, 0).use_empty())
5498be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), CopyFromLo);
5508be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5518be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (!SDValue(SUBENode, 0).use_empty())
5528be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), CopyFromHi);
5538be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
5548be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  return true;
5558be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes}
5568be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
557f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
5588be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                  TargetLowering::DAGCombinerInfo &DCI,
559864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                                  const MipsSubtarget *Subtarget) {
5608be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (DCI.isBeforeLegalize())
5618be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return SDValue();
5628be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
563e184fec550ea249d00e058cfba34ec6913951895Akira Hatanaka  if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
564f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      selectMADD(N, &DAG))
5658be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return SDValue(N, 0);
5668e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes
5678be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  return SDValue();
5688e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes}
5698be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
570f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
5718be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes                                  TargetLowering::DAGCombinerInfo &DCI,
572864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                                  const MipsSubtarget *Subtarget) {
5738be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  if (DCI.isBeforeLegalize())
5748be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return SDValue();
5758be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
576e184fec550ea249d00e058cfba34ec6913951895Akira Hatanaka  if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
577f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      selectMSUB(N, &DAG))
5788be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes    return SDValue(N, 0);
5798e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes
5808be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  return SDValue();
5818e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso Lopes}
5828be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
583f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG,
58438b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes                                    TargetLowering::DAGCombinerInfo &DCI,
585864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                                    const MipsSubtarget *Subtarget) {
58638b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  if (DCI.isBeforeLegalizeOps())
58738b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes    return SDValue();
58838b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes
589dda4a07cd818fdfe2b49412e32e0e12d9e566e31Akira Hatanaka  EVT Ty = N->getValueType(0);
590bb481f882093fb738d2bb15610c79364bada5496Jia Liu  unsigned LO = (Ty == MVT::i32) ? Mips::LO : Mips::LO64;
591bb481f882093fb738d2bb15610c79364bada5496Jia Liu  unsigned HI = (Ty == MVT::i32) ? Mips::HI : Mips::HI64;
592f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  unsigned Opc = N->getOpcode() == ISD::SDIVREM ? MipsISD::DivRem :
59338b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes                                                  MipsISD::DivRemU;
594f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = N->getDebugLoc();
59538b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes
596f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue DivRem = DAG.getNode(Opc, DL, MVT::Glue,
59738b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes                               N->getOperand(0), N->getOperand(1));
59838b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  SDValue InChain = DAG.getEntryNode();
59938b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  SDValue InGlue = DivRem;
60038b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes
60138b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  // insert MFLO
60238b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  if (N->hasAnyUseOfValue(0)) {
603f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue CopyFromLo = DAG.getCopyFromReg(InChain, DL, LO, Ty,
60438b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes                                            InGlue);
60538b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes    DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), CopyFromLo);
60638b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes    InChain = CopyFromLo.getValue(1);
60738b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes    InGlue = CopyFromLo.getValue(2);
60838b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  }
60938b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes
61038b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  // insert MFHI
61138b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  if (N->hasAnyUseOfValue(1)) {
612f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue CopyFromHi = DAG.getCopyFromReg(InChain, DL,
613dda4a07cd818fdfe2b49412e32e0e12d9e566e31Akira Hatanaka                                            HI, Ty, InGlue);
61438b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes    DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), CopyFromHi);
61538b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  }
61638b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes
61738b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  return SDValue();
61838b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes}
61938b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes
6201d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanakastatic Mips::CondCode FPCondCCodeToFCC(ISD::CondCode CC) {
6211d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  switch (CC) {
6221d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  default: llvm_unreachable("Unknown fp condition code!");
6231d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETEQ:
6241d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETOEQ: return Mips::FCOND_OEQ;
6251d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETUNE: return Mips::FCOND_UNE;
6261d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETLT:
6271d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETOLT: return Mips::FCOND_OLT;
6281d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETGT:
6291d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETOGT: return Mips::FCOND_OGT;
6301d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETLE:
6311d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETOLE: return Mips::FCOND_OLE;
6321d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETGE:
6331d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETOGE: return Mips::FCOND_OGE;
6341d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETULT: return Mips::FCOND_ULT;
6351d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETULE: return Mips::FCOND_ULE;
6361d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETUGT: return Mips::FCOND_UGT;
6371d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETUGE: return Mips::FCOND_UGE;
6381d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETUO:  return Mips::FCOND_UN;
6391d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETO:   return Mips::FCOND_OR;
6401d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETNE:
6411d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETONE: return Mips::FCOND_ONE;
6421d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  case ISD::SETUEQ: return Mips::FCOND_UEQ;
6431d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  }
6441d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka}
6451d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
6461d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
6471d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka// Returns true if condition code has to be inverted.
648f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic bool invertFPCondCode(Mips::CondCode CC) {
6491d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  if (CC >= Mips::FCOND_F && CC <= Mips::FCOND_NGT)
6501d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka    return false;
6511d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
65282099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka  assert((CC >= Mips::FCOND_T && CC <= Mips::FCOND_GT) &&
65382099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka         "Illegal Condition Code");
6541d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
65582099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka  return true;
6561d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka}
6571d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
6581d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka// Creates and returns an FPCmp node from a setcc node.
6591d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka// Returns Op if setcc is not a floating point comparison.
660f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op) {
6611d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  // must be a SETCC node
6621d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  if (Op.getOpcode() != ISD::SETCC)
6631d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka    return Op;
6641d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
6651d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  SDValue LHS = Op.getOperand(0);
6661d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
6671d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  if (!LHS.getValueType().isFloatingPoint())
6681d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka    return Op;
6691d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
6701d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  SDValue RHS = Op.getOperand(1);
671f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
6721d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
6730bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka  // Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of
6740bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka  // node if necessary.
6751d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
6761d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
677f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return DAG.getNode(MipsISD::FPCmp, DL, MVT::Glue, LHS, RHS,
6781d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka                     DAG.getConstant(FPCondCCodeToFCC(CC), MVT::i32));
6791d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka}
6801d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
6811d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka// Creates and returns a CMovFPT/F node.
682f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True,
6831d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka                            SDValue False, DebugLoc DL) {
684f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  bool invert = invertFPCondCode((Mips::CondCode)
6851d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka                                 cast<ConstantSDNode>(Cond.getOperand(2))
6861d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka                                 ->getSExtValue());
6871d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
6881d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  return DAG.getNode((invert ? MipsISD::CMovFP_F : MipsISD::CMovFP_T), DL,
6891d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka                     True.getValueType(), True, False, Cond);
6901d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka}
6911d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
692f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
693e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka                                    TargetLowering::DAGCombinerInfo &DCI,
694864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                                    const MipsSubtarget *Subtarget) {
695e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  if (DCI.isBeforeLegalizeOps())
696e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka    return SDValue();
697e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka
698e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  SDValue SetCC = N->getOperand(0);
699e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka
700e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  if ((SetCC.getOpcode() != ISD::SETCC) ||
701e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka      !SetCC.getOperand(0).getValueType().isInteger())
702e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka    return SDValue();
703e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka
704e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  SDValue False = N->getOperand(2);
705e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  EVT FalseTy = False.getValueType();
706e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka
707e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  if (!FalseTy.isInteger())
708e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka    return SDValue();
709e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka
710e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  ConstantSDNode *CN = dyn_cast<ConstantSDNode>(False);
711e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka
712e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  if (!CN || CN->getZExtValue())
713e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka    return SDValue();
714e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka
715e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  const DebugLoc DL = N->getDebugLoc();
716e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  ISD::CondCode CC = cast<CondCodeSDNode>(SetCC.getOperand(2))->get();
717e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  SDValue True = N->getOperand(1);
718864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka
719e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0),
720e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka                       SetCC.getOperand(1), ISD::getSetCCInverse(CC, true));
721864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka
722e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  return DAG.getNode(ISD::SELECT, DL, FalseTy, SetCC, False, True);
723e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka}
724e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka
725f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,
72677b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka                                 TargetLowering::DAGCombinerInfo &DCI,
727864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                                 const MipsSubtarget *Subtarget) {
72877b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // Pattern match EXT.
72977b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  //  $dst = and ((sra or srl) $src , pos), (2**size - 1)
73077b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  //  => ext $dst, $src, size, pos
73156633441271106376b39a47bbe5b59f85144b64dAkira Hatanaka  if (DCI.isBeforeLegalizeOps() || !Subtarget->hasMips32r2())
73277b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
73377b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
73477b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  SDValue ShiftRight = N->getOperand(0), Mask = N->getOperand(1);
735d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  unsigned ShiftRightOpc = ShiftRight.getOpcode();
736d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka
73777b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // Op's first operand must be a shift right.
738d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  if (ShiftRightOpc != ISD::SRA && ShiftRightOpc != ISD::SRL)
73977b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
74077b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
74177b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // The second operand of the shift must be an immediate.
74277b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  ConstantSDNode *CN;
74377b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  if (!(CN = dyn_cast<ConstantSDNode>(ShiftRight.getOperand(1))))
74477b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
745bb481f882093fb738d2bb15610c79364bada5496Jia Liu
746d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  uint64_t Pos = CN->getZExtValue();
74777b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  uint64_t SMPos, SMSize;
748d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka
74977b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // Op's second operand must be a shifted mask.
75077b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  if (!(CN = dyn_cast<ConstantSDNode>(Mask)) ||
751f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      !isShiftedMask(CN->getZExtValue(), SMPos, SMSize))
75277b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
75377b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
75477b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // Return if the shifted mask does not start at bit 0 or the sum of its size
75577b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // and Pos exceeds the word's size.
756d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  EVT ValTy = N->getValueType(0);
757d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits())
75877b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
75977b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
760d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  return DAG.getNode(MipsISD::Ext, N->getDebugLoc(), ValTy,
76182099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka                     ShiftRight.getOperand(0), DAG.getConstant(Pos, MVT::i32),
762667645f814523a65cb4c775b06b97234a7b002d7Akira Hatanaka                     DAG.getConstant(SMSize, MVT::i32));
76377b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka}
764bb481f882093fb738d2bb15610c79364bada5496Jia Liu
765f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
76677b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka                                TargetLowering::DAGCombinerInfo &DCI,
767864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                                const MipsSubtarget *Subtarget) {
76877b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // Pattern match INS.
76977b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  //  $dst = or (and $src1 , mask0), (and (shl $src, pos), mask1),
770bb481f882093fb738d2bb15610c79364bada5496Jia Liu  //  where mask1 = (2**size - 1) << pos, mask0 = ~mask1
77177b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  //  => ins $dst, $src, size, pos, $src1
77256633441271106376b39a47bbe5b59f85144b64dAkira Hatanaka  if (DCI.isBeforeLegalizeOps() || !Subtarget->hasMips32r2())
77377b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
77477b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
77577b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  SDValue And0 = N->getOperand(0), And1 = N->getOperand(1);
77677b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  uint64_t SMPos0, SMSize0, SMPos1, SMSize1;
77777b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  ConstantSDNode *CN;
77877b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
77977b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // See if Op's first operand matches (and $src1 , mask0).
78077b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  if (And0.getOpcode() != ISD::AND)
78177b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
78277b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
78377b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  if (!(CN = dyn_cast<ConstantSDNode>(And0.getOperand(1))) ||
784f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      !isShiftedMask(~CN->getSExtValue(), SMPos0, SMSize0))
78577b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
78677b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
78777b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // See if Op's second operand matches (and (shl $src, pos), mask1).
78877b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  if (And1.getOpcode() != ISD::AND)
78977b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
790bb481f882093fb738d2bb15610c79364bada5496Jia Liu
79177b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  if (!(CN = dyn_cast<ConstantSDNode>(And1.getOperand(1))) ||
792f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      !isShiftedMask(CN->getZExtValue(), SMPos1, SMSize1))
79377b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
79477b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
79577b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // The shift masks must have the same position and size.
79677b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
79777b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
79877b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
79977b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  SDValue Shl = And1.getOperand(0);
80077b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  if (Shl.getOpcode() != ISD::SHL)
80177b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
80277b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
80377b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand(1))))
80477b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
80577b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
80677b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  unsigned Shamt = CN->getZExtValue();
80777b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka
80877b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  // Return if the shift amount and the first bit position of mask are not the
809bb481f882093fb738d2bb15610c79364bada5496Jia Liu  // same.
810d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  EVT ValTy = N->getValueType(0);
811d6bc5237d8c961949fbc57dfa1a07f5833262388Akira Hatanaka  if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits()))
81277b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka    return SDValue();
813bb481f882093fb738d2bb15610c79364bada5496Jia Liu
81482099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka  return DAG.getNode(MipsISD::Ins, N->getDebugLoc(), ValTy, Shl.getOperand(0),
81577b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka                     DAG.getConstant(SMPos0, MVT::i32),
81682099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka                     DAG.getConstant(SMSize0, MVT::i32), And0.getOperand(0));
81777b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka}
818bb481f882093fb738d2bb15610c79364bada5496Jia Liu
819f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue performADDCombine(SDNode *N, SelectionDAG &DAG,
8208782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka                                 TargetLowering::DAGCombinerInfo &DCI,
821864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                                 const MipsSubtarget *Subtarget) {
8228782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  // (add v0, (add v1, abs_lo(tjt))) => (add (add v0, v1), abs_lo(tjt))
8238782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka
8248782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  if (DCI.isBeforeLegalizeOps())
8258782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka    return SDValue();
8268782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka
8278782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  SDValue Add = N->getOperand(1);
8288782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka
8298782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  if (Add.getOpcode() != ISD::ADD)
8308782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka    return SDValue();
8318782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka
8328782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  SDValue Lo = Add.getOperand(1);
8338782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka
8348782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  if ((Lo.getOpcode() != MipsISD::Lo) ||
8358782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka      (Lo.getOperand(0).getOpcode() != ISD::TargetJumpTable))
8368782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka    return SDValue();
8378782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka
8388782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  EVT ValTy = N->getValueType(0);
8398782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  DebugLoc DL = N->getDebugLoc();
8408782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka
8418782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  SDValue Add1 = DAG.getNode(ISD::ADD, DL, ValTy, N->getOperand(0),
8428782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka                             Add.getOperand(0));
8438782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  return DAG.getNode(ISD::ADD, DL, ValTy, Add1, Lo);
8448782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka}
8458782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka
8468e826e69db035f5e6c00393ff3f1ebc4c582b2fbBruno Cardoso LopesSDValue  MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
8478be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  const {
8488be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  SelectionDAG &DAG = DCI.DAG;
849f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  unsigned Opc = N->getOpcode();
8508be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
851f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  switch (Opc) {
8528be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  default: break;
8538be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  case ISD::ADDE:
854f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return performADDECombine(N, DAG, DCI, Subtarget);
8558be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  case ISD::SUBE:
856f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return performSUBECombine(N, DAG, DCI, Subtarget);
85738b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  case ISD::SDIVREM:
85838b5e86b9c67f601f354f8bcc11f5a515e200315Bruno Cardoso Lopes  case ISD::UDIVREM:
859f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return performDivRemCombine(N, DAG, DCI, Subtarget);
860e2bdf7fc935008dda6fba3d6fdd0a12193fd7b18Akira Hatanaka  case ISD::SELECT:
861f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return performSELECTCombine(N, DAG, DCI, Subtarget);
86277b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  case ISD::AND:
863f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return performANDCombine(N, DAG, DCI, Subtarget);
86477b85b647432765e61b9099a3560a3601cb950b7Akira Hatanaka  case ISD::OR:
865f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return performORCombine(N, DAG, DCI, Subtarget);
8668782707f5074ab3951eb6424394bc8d2a2fa584aAkira Hatanaka  case ISD::ADD:
867f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return performADDCombine(N, DAG, DCI, Subtarget);
8688be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  }
8698be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
8708be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes  return SDValue();
8718be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes}
8728be76112454e736db1815e6159644bf56ce04ac0Bruno Cardoso Lopes
873b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanakavoid
874b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira HatanakaMipsTargetLowering::LowerOperationWrapper(SDNode *N,
875b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka                                          SmallVectorImpl<SDValue> &Results,
876b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka                                          SelectionDAG &DAG) const {
877b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka  SDValue Res = LowerOperation(SDValue(N, 0), DAG);
878b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka
879b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka  for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I)
880b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka    Results.push_back(Res.getValue(I));
881b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka}
882b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka
883b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanakavoid
884b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira HatanakaMipsTargetLowering::ReplaceNodeResults(SDNode *N,
885b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka                                       SmallVectorImpl<SDValue> &Results,
886b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka                                       SelectionDAG &DAG) const {
887b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka  SDValue Res = LowerOperation(SDValue(N, 0), DAG);
888b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka
889b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka  for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I)
890b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka    Results.push_back(Res.getValue(I));
891b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka}
892b430cecc0eeaa3f916b396b9f5fdee04cf306658Akira Hatanaka
893475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue MipsTargetLowering::
894d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanLowerOperation(SDValue Op, SelectionDAG &DAG) const
895972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes{
896bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  switch (Op.getOpcode())
897972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  {
898f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::BR_JT:              return lowerBR_JT(Op, DAG);
899f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::BRCOND:             return lowerBRCOND(Op, DAG);
900f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::ConstantPool:       return lowerConstantPool(Op, DAG);
901f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::GlobalAddress:      return lowerGlobalAddress(Op, DAG);
902f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::BlockAddress:       return lowerBlockAddress(Op, DAG);
903f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::GlobalTLSAddress:   return lowerGlobalTLSAddress(Op, DAG);
904f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::JumpTable:          return lowerJumpTable(Op, DAG);
905f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::SELECT:             return lowerSELECT(Op, DAG);
906f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::SELECT_CC:          return lowerSELECT_CC(Op, DAG);
907f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::SETCC:              return lowerSETCC(Op, DAG);
908f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::VASTART:            return lowerVASTART(Op, DAG);
909f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::FCOPYSIGN:          return lowerFCOPYSIGN(Op, DAG);
910f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::FABS:               return lowerFABS(Op, DAG);
911f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::FRAMEADDR:          return lowerFRAMEADDR(Op, DAG);
912f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::RETURNADDR:         return lowerRETURNADDR(Op, DAG);
913f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::EH_RETURN:          return lowerEH_RETURN(Op, DAG);
914f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::MEMBARRIER:         return lowerMEMBARRIER(Op, DAG);
915f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::ATOMIC_FENCE:       return lowerATOMIC_FENCE(Op, DAG);
916f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::SHL_PARTS:          return lowerShiftLeftParts(Op, DAG);
917f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::SRA_PARTS:          return lowerShiftRightParts(Op, DAG, true);
918f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::SRL_PARTS:          return lowerShiftRightParts(Op, DAG, false);
919f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::LOAD:               return lowerLOAD(Op, DAG);
920f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::STORE:              return lowerSTORE(Op, DAG);
921f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
922f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::INTRINSIC_W_CHAIN:  return lowerINTRINSIC_W_CHAIN(Op, DAG);
923f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    case ISD::ADD:                return lowerADD(Op, DAG);
924972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  }
925475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return SDValue();
926972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
927972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
9284552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
929972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//  Lower helper functions
9304552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
931972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
932f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka// addLiveIn - This helper function adds the specified physical register to the
933972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// MachineFunction as a live in value.  It also creates a corresponding
934972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// virtual register for it.
935972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopesstatic unsigned
936f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaaddLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC)
937972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes{
93884bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner  unsigned VReg = MF.getRegInfo().createVirtualRegister(RC);
93984bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner  MF.getRegInfo().addLiveIn(PReg, VReg);
940972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  return VReg;
941972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
942972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
94385e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes// Get fp branch code (not opcode) from condition code.
944f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic Mips::FPBranchCode getFPBranchCodeFromCond(Mips::CondCode CC) {
94585e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes  if (CC >= Mips::FCOND_F && CC <= Mips::FCOND_NGT)
94685e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes    return Mips::BRANCH_T;
94785e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes
94882099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka  assert((CC >= Mips::FCOND_T && CC <= Mips::FCOND_GT) &&
94982099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka         "Invalid CondCode.");
95085e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes
95182099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka  return Mips::BRANCH_F;
95285e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes}
953bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
95401f7089bca51744226306e09db4954e3df02b3beAkira HatanakaMachineBasicBlock *
95514487d4f66c3127b29408aae46c1a948d348ec59Akira HatanakaMipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
95614487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka                                                MachineBasicBlock *BB) const {
95714487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  switch (MI->getOpcode()) {
958ffbe432595c78ba28c8a9d200bf92996eed5e5d9Reed Kotler  default:
959ffbe432595c78ba28c8a9d200bf92996eed5e5d9Reed Kotler    llvm_unreachable("Unexpected instr type to insert");
96014487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_ADD_I8:
96159068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_ADD_I8_P8:
962f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 1, Mips::ADDu);
96314487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_ADD_I16:
96459068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_ADD_I16_P8:
965f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 2, Mips::ADDu);
96614487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_ADD_I32:
96759068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_ADD_I32_P8:
968f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 4, Mips::ADDu);
96959068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_ADD_I64:
97059068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_ADD_I64_P8:
971f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 8, Mips::DADDu);
97214487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka
97314487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_AND_I8:
97459068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_AND_I8_P8:
975f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 1, Mips::AND);
97614487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_AND_I16:
97759068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_AND_I16_P8:
978f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 2, Mips::AND);
97914487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_AND_I32:
98059068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_AND_I32_P8:
981f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 4, Mips::AND);
98259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_AND_I64:
98359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_AND_I64_P8:
984f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 8, Mips::AND64);
98514487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka
98614487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_OR_I8:
98759068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_OR_I8_P8:
988f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 1, Mips::OR);
98914487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_OR_I16:
99059068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_OR_I16_P8:
991f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 2, Mips::OR);
99214487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_OR_I32:
99359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_OR_I32_P8:
994f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 4, Mips::OR);
99559068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_OR_I64:
99659068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_OR_I64_P8:
997f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 8, Mips::OR64);
99814487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka
99914487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_XOR_I8:
100059068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_XOR_I8_P8:
1001f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 1, Mips::XOR);
100214487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_XOR_I16:
100359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_XOR_I16_P8:
1004f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 2, Mips::XOR);
100514487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_XOR_I32:
100659068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_XOR_I32_P8:
1007f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 4, Mips::XOR);
100859068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_XOR_I64:
100959068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_XOR_I64_P8:
1010f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 8, Mips::XOR64);
101114487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka
101214487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_NAND_I8:
101359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_NAND_I8_P8:
1014f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 1, 0, true);
101514487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_NAND_I16:
101659068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_NAND_I16_P8:
1017f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 2, 0, true);
101814487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_NAND_I32:
101959068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_NAND_I32_P8:
1020f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 4, 0, true);
102159068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_NAND_I64:
102259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_NAND_I64_P8:
1023f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 8, 0, true);
102414487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka
102514487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_SUB_I8:
102659068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_SUB_I8_P8:
1027f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 1, Mips::SUBu);
102814487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_SUB_I16:
102959068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_SUB_I16_P8:
1030f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 2, Mips::SUBu);
103114487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_LOAD_SUB_I32:
103259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_SUB_I32_P8:
1033f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 4, Mips::SUBu);
103459068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_SUB_I64:
103559068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_LOAD_SUB_I64_P8:
1036f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 8, Mips::DSUBu);
103714487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka
103814487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_SWAP_I8:
103959068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_SWAP_I8_P8:
1040f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 1, 0);
104114487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_SWAP_I16:
104259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_SWAP_I16_P8:
1043f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinaryPartword(MI, BB, 2, 0);
104414487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_SWAP_I32:
104559068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_SWAP_I32_P8:
1046f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 4, 0);
104759068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_SWAP_I64:
104859068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_SWAP_I64_P8:
1049f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicBinary(MI, BB, 8, 0);
105014487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka
105114487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_CMP_SWAP_I8:
105259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_CMP_SWAP_I8_P8:
1053f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicCmpSwapPartword(MI, BB, 1);
105414487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_CMP_SWAP_I16:
105559068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_CMP_SWAP_I16_P8:
1056f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicCmpSwapPartword(MI, BB, 2);
105714487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  case Mips::ATOMIC_CMP_SWAP_I32:
105859068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_CMP_SWAP_I32_P8:
1059f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicCmpSwap(MI, BB, 4);
106059068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_CMP_SWAP_I64:
106159068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  case Mips::ATOMIC_CMP_SWAP_I64_P8:
1062f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return emitAtomicCmpSwap(MI, BB, 8);
106314487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka  }
106414487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka}
106514487d4f66c3127b29408aae46c1a948d348ec59Akira Hatanaka
10664e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes// This function also handles Mips::ATOMIC_SWAP_I32 (when BinOpcode == 0), and
10674e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes// Mips::ATOMIC_LOAD_NAND_I32 (when Nand == true)
10684e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso LopesMachineBasicBlock *
1069f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaMipsTargetLowering::emitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
1070471e4224809f51652c71f319532697a879a75a0dEric Christopher                                     unsigned Size, unsigned BinOpcode,
10710f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka                                     bool Nand) const {
107259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  assert((Size == 4 || Size == 8) && "Unsupported size for EmitAtomicBinary.");
10734e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
10744e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineFunction *MF = BB->getParent();
10754e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineRegisterInfo &RegInfo = MF->getRegInfo();
107659068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  const TargetRegisterClass *RC = getRegClassFor(MVT::getIntegerVT(Size * 8));
10774e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1078f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = MI->getDebugLoc();
107959068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  unsigned LL, SC, AND, NOR, ZERO, BEQ;
108059068067cb37322c50463102bbd6929df34c039eAkira Hatanaka
108159068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  if (Size == 4) {
108259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    LL = IsN64 ? Mips::LL_P8 : Mips::LL;
108359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    SC = IsN64 ? Mips::SC_P8 : Mips::SC;
108459068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    AND = Mips::AND;
108559068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    NOR = Mips::NOR;
108659068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    ZERO = Mips::ZERO;
108759068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    BEQ = Mips::BEQ;
108859068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  }
108959068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  else {
109059068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    LL = IsN64 ? Mips::LLD_P8 : Mips::LLD;
109159068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    SC = IsN64 ? Mips::SCD_P8 : Mips::SCD;
109259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    AND = Mips::AND64;
109359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    NOR = Mips::NOR64;
109459068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    ZERO = Mips::ZERO_64;
109559068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    BEQ = Mips::BEQ64;
109659068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  }
10974e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
10984061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned OldVal = MI->getOperand(0).getReg();
10994e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Ptr = MI->getOperand(1).getReg();
11004e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Incr = MI->getOperand(2).getReg();
11014e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11024061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned StoreVal = RegInfo.createVirtualRegister(RC);
11034061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned AndRes = RegInfo.createVirtualRegister(RC);
11044061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned Success = RegInfo.createVirtualRegister(RC);
11054e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11064e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // insert new blocks after the current block
11074e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11084e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11094e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11104e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineFunction::iterator It = BB;
11114e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  ++It;
11124e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, loopMBB);
11134e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, exitMBB);
11144e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11154e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // Transfer the remainder of BB and its successor edges to exitMBB.
11164e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  exitMBB->splice(exitMBB->begin(), BB,
11174e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes                  llvm::next(MachineBasicBlock::iterator(MI)),
11184e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes                  BB->end());
11194e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  exitMBB->transferSuccessorsAndUpdatePHIs(BB);
11204e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11214e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //  thisMBB:
11224e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //    ...
11234e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //    fallthrough --> loopMBB
11244e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  BB->addSuccessor(loopMBB);
112581b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loopMBB->addSuccessor(loopMBB);
112681b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loopMBB->addSuccessor(exitMBB);
11274e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11284e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //  loopMBB:
11294e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //    ll oldval, 0(ptr)
11304061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    <binop> storeval, oldval, incr
11314061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sc success, storeval, 0(ptr)
11324061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    beq success, $0, loopMBB
11334e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  BB = loopMBB;
1134f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
11354e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  if (Nand) {
11364061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    //  and andres, oldval, incr
11374061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    //  nor storeval, $0, andres
1138f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    BuildMI(BB, DL, TII->get(AND), AndRes).addReg(OldVal).addReg(Incr);
1139f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    BuildMI(BB, DL, TII->get(NOR), StoreVal).addReg(ZERO).addReg(AndRes);
11404e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  } else if (BinOpcode) {
11414061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    //  <binop> storeval, oldval, incr
1142f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    BuildMI(BB, DL, TII->get(BinOpcode), StoreVal).addReg(OldVal).addReg(Incr);
11434e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  } else {
11444061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    StoreVal = Incr;
11454e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  }
1146f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(SC), Success).addReg(StoreVal).addReg(Ptr).addImm(0);
1147f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(BEQ)).addReg(Success).addReg(ZERO).addMBB(loopMBB);
11484e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11494e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MI->eraseFromParent();   // The instruction is gone now.
11504e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
1151939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  return exitMBB;
11524e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes}
11534e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11544e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso LopesMachineBasicBlock *
1155f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaMipsTargetLowering::emitAtomicBinaryPartword(MachineInstr *MI,
11560f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka                                             MachineBasicBlock *BB,
11570f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka                                             unsigned Size, unsigned BinOpcode,
11580f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka                                             bool Nand) const {
11594e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  assert((Size == 1 || Size == 2) &&
11604e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes      "Unsupported size for EmitAtomicBinaryPartial.");
11614e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11624e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineFunction *MF = BB->getParent();
11634e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineRegisterInfo &RegInfo = MF->getRegInfo();
11644e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const TargetRegisterClass *RC = getRegClassFor(MVT::i32);
11654e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1166f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = MI->getDebugLoc();
116759068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  unsigned LL = IsN64 ? Mips::LL_P8 : Mips::LL;
116859068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  unsigned SC = IsN64 ? Mips::SC_P8 : Mips::SC;
11694e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11704e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Dest = MI->getOperand(0).getReg();
11714e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Ptr = MI->getOperand(1).getReg();
11724e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Incr = MI->getOperand(2).getReg();
11734e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11744061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned AlignedAddr = RegInfo.createVirtualRegister(RC);
11754061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned ShiftAmt = RegInfo.createVirtualRegister(RC);
11764e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Mask = RegInfo.createVirtualRegister(RC);
11774e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Mask2 = RegInfo.createVirtualRegister(RC);
11784061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned NewVal = RegInfo.createVirtualRegister(RC);
11794061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned OldVal = RegInfo.createVirtualRegister(RC);
11804e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Incr2 = RegInfo.createVirtualRegister(RC);
11814061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned MaskLSB2 = RegInfo.createVirtualRegister(RC);
11824061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned PtrLSB2 = RegInfo.createVirtualRegister(RC);
11834061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned MaskUpper = RegInfo.createVirtualRegister(RC);
11844061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned AndRes = RegInfo.createVirtualRegister(RC);
11854061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned BinOpRes = RegInfo.createVirtualRegister(RC);
1186bdd83fe382d6c3d6fc73aa7142e73f30cbd4dfadAkira Hatanaka  unsigned MaskedOldVal0 = RegInfo.createVirtualRegister(RC);
11874061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned StoreVal = RegInfo.createVirtualRegister(RC);
11884061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned MaskedOldVal1 = RegInfo.createVirtualRegister(RC);
11894061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned SrlRes = RegInfo.createVirtualRegister(RC);
11904061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned SllRes = RegInfo.createVirtualRegister(RC);
11914061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned Success = RegInfo.createVirtualRegister(RC);
11924e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
11934e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // insert new blocks after the current block
11944e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11954e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
1196939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11974e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11984e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineFunction::iterator It = BB;
11994e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  ++It;
12004e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, loopMBB);
1201939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  MF->insert(It, sinkMBB);
12024e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, exitMBB);
12034e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
12044e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // Transfer the remainder of BB and its successor edges to exitMBB.
12054e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  exitMBB->splice(exitMBB->begin(), BB,
120682099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka                  llvm::next(MachineBasicBlock::iterator(MI)), BB->end());
12074e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  exitMBB->transferSuccessorsAndUpdatePHIs(BB);
12084e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
120981b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  BB->addSuccessor(loopMBB);
121081b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loopMBB->addSuccessor(loopMBB);
121181b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loopMBB->addSuccessor(sinkMBB);
121281b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  sinkMBB->addSuccessor(exitMBB);
121381b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka
12144e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //  thisMBB:
12154061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    addiu   masklsb2,$0,-4                # 0xfffffffc
12164061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    and     alignedaddr,ptr,masklsb2
12174061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    andi    ptrlsb2,ptr,3
12184061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sll     shiftamt,ptrlsb2,3
12194061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    ori     maskupper,$0,255               # 0xff
12204061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sll     mask,maskupper,shiftamt
12214e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //    nor     mask2,$0,mask
12224061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sll     incr2,incr,shiftamt
12234e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
12244e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  int64_t MaskImm = (Size == 1) ? 255 : 65535;
1225f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::ADDiu), MaskLSB2)
12264061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(Mips::ZERO).addImm(-4);
1227f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::AND), AlignedAddr)
12284061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(Ptr).addReg(MaskLSB2);
1229f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2).addReg(Ptr).addImm(3);
1230f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3);
1231f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper)
12324061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(Mips::ZERO).addImm(MaskImm);
1233f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SLLV), Mask)
1234cc7ecc72909fe3f2a3eba9e7ac79cd1a13b3e8f2Akira Hatanaka    .addReg(ShiftAmt).addReg(MaskUpper);
1235f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);
1236f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SLLV), Incr2).addReg(ShiftAmt).addReg(Incr);
1237cada2d0966b649b8f04a78f35b9d6d9b4330ce74Bruno Cardoso Lopes
12380d7d0b5cb7e41173b6fff2f0c2fbdcbebc9693feAkira Hatanaka  // atomic.load.binop
12394e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // loopMBB:
12404061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   ll      oldval,0(alignedaddr)
12414061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   binop   binopres,oldval,incr2
12424061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   and     newval,binopres,mask
12434061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   and     maskedoldval0,oldval,mask2
12444061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   or      storeval,maskedoldval0,newval
12454061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   sc      success,storeval,0(alignedaddr)
12464061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   beq     success,$0,loopMBB
12474061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka
12480d7d0b5cb7e41173b6fff2f0c2fbdcbebc9693feAkira Hatanaka  // atomic.swap
12490d7d0b5cb7e41173b6fff2f0c2fbdcbebc9693feAkira Hatanaka  // loopMBB:
12504061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   ll      oldval,0(alignedaddr)
125170564a9c194aa7c86c94227639de4037bbc3cbe8Akira Hatanaka  //   and     newval,incr2,mask
12524061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   and     maskedoldval0,oldval,mask2
12534061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   or      storeval,maskedoldval0,newval
12544061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   sc      success,storeval,0(alignedaddr)
12554061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   beq     success,$0,loopMBB
12560d7d0b5cb7e41173b6fff2f0c2fbdcbebc9693feAkira Hatanaka
12574e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  BB = loopMBB;
1258f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(LL), OldVal).addReg(AlignedAddr).addImm(0);
12594e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  if (Nand) {
12604061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    //  and andres, oldval, incr2
12614061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    //  nor binopres, $0, andres
12624061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    //  and newval, binopres, mask
1263f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    BuildMI(BB, DL, TII->get(Mips::AND), AndRes).addReg(OldVal).addReg(Incr2);
1264f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    BuildMI(BB, DL, TII->get(Mips::NOR), BinOpRes)
12654061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka      .addReg(Mips::ZERO).addReg(AndRes);
1266f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    BuildMI(BB, DL, TII->get(Mips::AND), NewVal).addReg(BinOpRes).addReg(Mask);
12674e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  } else if (BinOpcode) {
12684061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    //  <binop> binopres, oldval, incr2
12694061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    //  and newval, binopres, mask
1270f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    BuildMI(BB, DL, TII->get(BinOpcode), BinOpRes).addReg(OldVal).addReg(Incr2);
1271f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    BuildMI(BB, DL, TII->get(Mips::AND), NewVal).addReg(BinOpRes).addReg(Mask);
127270564a9c194aa7c86c94227639de4037bbc3cbe8Akira Hatanaka  } else {// atomic.swap
12734061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    //  and newval, incr2, mask
1274f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    BuildMI(BB, DL, TII->get(Mips::AND), NewVal).addReg(Incr2).addReg(Mask);
127570564a9c194aa7c86c94227639de4037bbc3cbe8Akira Hatanaka  }
1276bb481f882093fb738d2bb15610c79364bada5496Jia Liu
1277f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal0)
12784061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(OldVal).addReg(Mask2);
1279f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::OR), StoreVal)
1280bdd83fe382d6c3d6fc73aa7142e73f30cbd4dfadAkira Hatanaka    .addReg(MaskedOldVal0).addReg(NewVal);
1281f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(SC), Success)
12824061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(StoreVal).addReg(AlignedAddr).addImm(0);
1283f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::BEQ))
12844061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(Success).addReg(Mips::ZERO).addMBB(loopMBB);
12854e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
1286939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  //  sinkMBB:
12874061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    and     maskedoldval1,oldval,mask
12884061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    srl     srlres,maskedoldval1,shiftamt
12894061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sll     sllres,srlres,24
12904061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sra     dest,sllres,24
1291939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  BB = sinkMBB;
12924e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  int64_t ShiftImm = (Size == 1) ? 24 : 16;
1293a308c670b44f068a660309d6daff7b35d531ddc4Akira Hatanaka
1294f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal1)
12954061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(OldVal).addReg(Mask);
1296f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes)
1297cc7ecc72909fe3f2a3eba9e7ac79cd1a13b3e8f2Akira Hatanaka      .addReg(ShiftAmt).addReg(MaskedOldVal1);
1298f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SLL), SllRes)
12994061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka      .addReg(SrlRes).addImm(ShiftImm);
1300f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SRA), Dest)
13014061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka      .addReg(SllRes).addImm(ShiftImm);
13024e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13034e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MI->eraseFromParent();   // The instruction is gone now.
13044e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
1305939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  return exitMBB;
13064e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes}
13074e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13084e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso LopesMachineBasicBlock *
1309f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaMipsTargetLowering::emitAtomicCmpSwap(MachineInstr *MI,
13100f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka                                      MachineBasicBlock *BB,
13110f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka                                      unsigned Size) const {
131259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  assert((Size == 4 || Size == 8) && "Unsupported size for EmitAtomicCmpSwap.");
13134e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13144e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineFunction *MF = BB->getParent();
13154e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineRegisterInfo &RegInfo = MF->getRegInfo();
131659068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  const TargetRegisterClass *RC = getRegClassFor(MVT::getIntegerVT(Size * 8));
13174e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1318f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = MI->getDebugLoc();
131959068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  unsigned LL, SC, ZERO, BNE, BEQ;
132059068067cb37322c50463102bbd6929df34c039eAkira Hatanaka
132159068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  if (Size == 4) {
132259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    LL = IsN64 ? Mips::LL_P8 : Mips::LL;
132359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    SC = IsN64 ? Mips::SC_P8 : Mips::SC;
132459068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    ZERO = Mips::ZERO;
132559068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    BNE = Mips::BNE;
132659068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    BEQ = Mips::BEQ;
132759068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  }
132859068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  else {
132959068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    LL = IsN64 ? Mips::LLD_P8 : Mips::LLD;
133059068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    SC = IsN64 ? Mips::SCD_P8 : Mips::SCD;
133159068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    ZERO = Mips::ZERO_64;
133259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    BNE = Mips::BNE64;
133359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    BEQ = Mips::BEQ64;
133459068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  }
13354e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13364e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Dest    = MI->getOperand(0).getReg();
13374e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Ptr     = MI->getOperand(1).getReg();
13384061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned OldVal  = MI->getOperand(2).getReg();
13394061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned NewVal  = MI->getOperand(3).getReg();
13404e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13414061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned Success = RegInfo.createVirtualRegister(RC);
13424e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13434e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // insert new blocks after the current block
13444e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const BasicBlock *LLVM_BB = BB->getBasicBlock();
13454e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
13464e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
13474e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
13484e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineFunction::iterator It = BB;
13494e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  ++It;
13504e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, loop1MBB);
13514e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, loop2MBB);
13524e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, exitMBB);
13534e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13544e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // Transfer the remainder of BB and its successor edges to exitMBB.
13554e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  exitMBB->splice(exitMBB->begin(), BB,
135682099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka                  llvm::next(MachineBasicBlock::iterator(MI)), BB->end());
13574e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  exitMBB->transferSuccessorsAndUpdatePHIs(BB);
13584e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13594e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //  thisMBB:
13604e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //    ...
13614e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //    fallthrough --> loop1MBB
13624e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  BB->addSuccessor(loop1MBB);
136381b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loop1MBB->addSuccessor(exitMBB);
136481b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loop1MBB->addSuccessor(loop2MBB);
136581b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loop2MBB->addSuccessor(loop1MBB);
136681b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loop2MBB->addSuccessor(exitMBB);
13674e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13684e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // loop1MBB:
13694e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //   ll dest, 0(ptr)
13704e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //   bne dest, oldval, exitMBB
13714e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  BB = loop1MBB;
1372f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(LL), Dest).addReg(Ptr).addImm(0);
1373f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(BNE))
13744061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(Dest).addReg(OldVal).addMBB(exitMBB);
13754e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13764e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // loop2MBB:
13774061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   sc success, newval, 0(ptr)
13784061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //   beq success, $0, loop1MBB
13794e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  BB = loop2MBB;
1380f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(SC), Success)
13814061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(NewVal).addReg(Ptr).addImm(0);
1382f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(BEQ))
138359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka    .addReg(Success).addReg(ZERO).addMBB(loop1MBB);
13844e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13854e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MI->eraseFromParent();   // The instruction is gone now.
13864e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
1387939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  return exitMBB;
13884e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes}
13894e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13904e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso LopesMachineBasicBlock *
1391f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaMipsTargetLowering::emitAtomicCmpSwapPartword(MachineInstr *MI,
13920f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka                                              MachineBasicBlock *BB,
13930f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka                                              unsigned Size) const {
13944e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  assert((Size == 1 || Size == 2) &&
13954e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes      "Unsupported size for EmitAtomicCmpSwapPartial.");
13964e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
13974e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineFunction *MF = BB->getParent();
13984e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineRegisterInfo &RegInfo = MF->getRegInfo();
13994e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const TargetRegisterClass *RC = getRegClassFor(MVT::i32);
14004e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1401f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = MI->getDebugLoc();
140259068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  unsigned LL = IsN64 ? Mips::LL_P8 : Mips::LL;
140359068067cb37322c50463102bbd6929df34c039eAkira Hatanaka  unsigned SC = IsN64 ? Mips::SC_P8 : Mips::SC;
14044e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
14054e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Dest    = MI->getOperand(0).getReg();
14064e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Ptr     = MI->getOperand(1).getReg();
14074061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned CmpVal  = MI->getOperand(2).getReg();
14084061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned NewVal  = MI->getOperand(3).getReg();
14094e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
14104061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned AlignedAddr = RegInfo.createVirtualRegister(RC);
14114061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned ShiftAmt = RegInfo.createVirtualRegister(RC);
14124e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Mask = RegInfo.createVirtualRegister(RC);
14134e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  unsigned Mask2 = RegInfo.createVirtualRegister(RC);
14144061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned ShiftedCmpVal = RegInfo.createVirtualRegister(RC);
14154061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned OldVal = RegInfo.createVirtualRegister(RC);
14164061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned MaskedOldVal0 = RegInfo.createVirtualRegister(RC);
14174061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned ShiftedNewVal = RegInfo.createVirtualRegister(RC);
14184061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned MaskLSB2 = RegInfo.createVirtualRegister(RC);
14194061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned PtrLSB2 = RegInfo.createVirtualRegister(RC);
14204061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned MaskUpper = RegInfo.createVirtualRegister(RC);
14214061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned MaskedCmpVal = RegInfo.createVirtualRegister(RC);
14224061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned MaskedNewVal = RegInfo.createVirtualRegister(RC);
14234061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned MaskedOldVal1 = RegInfo.createVirtualRegister(RC);
14244061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned StoreVal = RegInfo.createVirtualRegister(RC);
14254061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned SrlRes = RegInfo.createVirtualRegister(RC);
14264061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned SllRes = RegInfo.createVirtualRegister(RC);
14274061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  unsigned Success = RegInfo.createVirtualRegister(RC);
14284e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
14294e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // insert new blocks after the current block
14304e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  const BasicBlock *LLVM_BB = BB->getBasicBlock();
14314e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
14324e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
1433939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
14344e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
14354e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MachineFunction::iterator It = BB;
14364e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  ++It;
14374e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, loop1MBB);
14384e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, loop2MBB);
1439939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  MF->insert(It, sinkMBB);
14404e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MF->insert(It, exitMBB);
14414e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
14424e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  // Transfer the remainder of BB and its successor edges to exitMBB.
14434e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  exitMBB->splice(exitMBB->begin(), BB,
144482099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka                  llvm::next(MachineBasicBlock::iterator(MI)), BB->end());
14454e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  exitMBB->transferSuccessorsAndUpdatePHIs(BB);
14464e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
144781b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  BB->addSuccessor(loop1MBB);
144881b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loop1MBB->addSuccessor(sinkMBB);
144981b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loop1MBB->addSuccessor(loop2MBB);
145081b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loop2MBB->addSuccessor(loop1MBB);
145181b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  loop2MBB->addSuccessor(sinkMBB);
145281b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka  sinkMBB->addSuccessor(exitMBB);
145381b441151fcbf998862adec79540bed049bbfa81Akira Hatanaka
145470564a9c194aa7c86c94227639de4037bbc3cbe8Akira Hatanaka  // FIXME: computation of newval2 can be moved to loop2MBB.
14554e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //  thisMBB:
14564061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    addiu   masklsb2,$0,-4                # 0xfffffffc
14574061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    and     alignedaddr,ptr,masklsb2
14584061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    andi    ptrlsb2,ptr,3
14594061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sll     shiftamt,ptrlsb2,3
14604061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    ori     maskupper,$0,255               # 0xff
14614061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sll     mask,maskupper,shiftamt
14624e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //    nor     mask2,$0,mask
14634061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    andi    maskedcmpval,cmpval,255
14644061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sll     shiftedcmpval,maskedcmpval,shiftamt
14654061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    andi    maskednewval,newval,255
14664061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sll     shiftednewval,maskednewval,shiftamt
14674e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  int64_t MaskImm = (Size == 1) ? 255 : 65535;
1468f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::ADDiu), MaskLSB2)
14694061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(Mips::ZERO).addImm(-4);
1470f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::AND), AlignedAddr)
14714061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(Ptr).addReg(MaskLSB2);
1472f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2).addReg(Ptr).addImm(3);
1473f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3);
1474f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper)
14754061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(Mips::ZERO).addImm(MaskImm);
1476f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SLLV), Mask)
1477cc7ecc72909fe3f2a3eba9e7ac79cd1a13b3e8f2Akira Hatanaka    .addReg(ShiftAmt).addReg(MaskUpper);
1478f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);
1479f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedCmpVal)
14804061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(CmpVal).addImm(MaskImm);
1481f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedCmpVal)
1482cc7ecc72909fe3f2a3eba9e7ac79cd1a13b3e8f2Akira Hatanaka    .addReg(ShiftAmt).addReg(MaskedCmpVal);
1483f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedNewVal)
14844061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(NewVal).addImm(MaskImm);
1485f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedNewVal)
1486cc7ecc72909fe3f2a3eba9e7ac79cd1a13b3e8f2Akira Hatanaka    .addReg(ShiftAmt).addReg(MaskedNewVal);
14874e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
14884e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //  loop1MBB:
14894061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    ll      oldval,0(alginedaddr)
14904061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    and     maskedoldval0,oldval,mask
14914061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    bne     maskedoldval0,shiftedcmpval,sinkMBB
14924e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  BB = loop1MBB;
1493f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(LL), OldVal).addReg(AlignedAddr).addImm(0);
1494f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal0)
14954061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(OldVal).addReg(Mask);
1496f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::BNE))
14974061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(MaskedOldVal0).addReg(ShiftedCmpVal).addMBB(sinkMBB);
14984e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
14994e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  //  loop2MBB:
15004061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    and     maskedoldval1,oldval,mask2
15014061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    or      storeval,maskedoldval1,shiftednewval
15024061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sc      success,storeval,0(alignedaddr)
15034061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    beq     success,$0,loop1MBB
15044e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  BB = loop2MBB;
1505f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal1)
15064061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(OldVal).addReg(Mask2);
1507f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::OR), StoreVal)
15084061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka    .addReg(MaskedOldVal1).addReg(ShiftedNewVal);
1509f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(SC), Success)
15104061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka      .addReg(StoreVal).addReg(AlignedAddr).addImm(0);
1511f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::BEQ))
15124061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka      .addReg(Success).addReg(Mips::ZERO).addMBB(loop1MBB);
15134e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
1514939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  //  sinkMBB:
15154061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    srl     srlres,maskedoldval0,shiftamt
15164061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sll     sllres,srlres,24
15174061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka  //    sra     dest,sllres,24
1518939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  BB = sinkMBB;
15194e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  int64_t ShiftImm = (Size == 1) ? 24 : 16;
1520a308c670b44f068a660309d6daff7b35d531ddc4Akira Hatanaka
1521f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes)
1522cc7ecc72909fe3f2a3eba9e7ac79cd1a13b3e8f2Akira Hatanaka      .addReg(ShiftAmt).addReg(MaskedOldVal0);
1523f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SLL), SllRes)
15244061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka      .addReg(SrlRes).addImm(ShiftImm);
1525f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::SRA), Dest)
15264061da1403d8b4e00065a52606eb984f1abd5471Akira Hatanaka      .addReg(SllRes).addImm(ShiftImm);
15274e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
15284e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes  MI->eraseFromParent();   // The instruction is gone now.
15294e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
1530939ece1b5c6c2f142476b477daa573046fa1b8daAkira Hatanaka  return exitMBB;
15314e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes}
15324e694c96f1c0c2d09a287ff69bab5896e04dd3fdBruno Cardoso Lopes
15334552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
1534972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//  Misc Lower Operation implementation
15354552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
1536f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
1537b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  SDValue Chain = Op.getOperand(0);
1538b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  SDValue Table = Op.getOperand(1);
1539b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  SDValue Index = Op.getOperand(2);
1540b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1541b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  EVT PTy = getPointerTy();
1542b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  unsigned EntrySize =
1543b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka    DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(*getDataLayout());
1544b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka
1545b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  Index = DAG.getNode(ISD::MUL, DL, PTy, Index,
1546b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka                      DAG.getConstant(EntrySize, PTy));
1547b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  SDValue Addr = DAG.getNode(ISD::ADD, DL, PTy, Index, Table);
1548b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka
1549b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), EntrySize * 8);
1550b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  Addr = DAG.getExtLoad(ISD::SEXTLOAD, DL, PTy, Chain, Addr,
1551b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka                        MachinePointerInfo::getJumpTable(), MemVT, false, false,
1552b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka                        0);
1553b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  Chain = Addr.getValue(1);
1554b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka
1555b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  if ((getTargetMachine().getRelocationModel() == Reloc::PIC_) || IsN64) {
1556b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka    // For PIC, the sequence is:
1557b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka    // BRIND(load(Jumptable + index) + RelocBase)
1558b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka    // RelocBase can be JumpTable, GOT or some sort of global base.
1559b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka    Addr = DAG.getNode(ISD::ADD, DL, PTy, Addr,
1560b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka                       getPICJumpTableRelocBase(Table, DAG));
1561b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  }
1562b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka
1563b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka  return DAG.getNode(ISD::BRIND, DL, MVT::Other, Chain, Addr);
1564b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka}
1565b7656a9cc4bf36752df38e7c02b910c9390b9c39Akira Hatanaka
1566d3bdf19ce7a37e23a6c4d877fb681eb010be74f7Bruno Cardoso LopesSDValue MipsTargetLowering::
1567f635ef401786c84df32090251a8cf45981ecca33Akira HatanakalowerBRCOND(SDValue Op, SelectionDAG &DAG) const
156885e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes{
1569bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // The first operand is the chain, the second is the condition, the third is
157085e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes  // the block to branch to if the condition is true.
157185e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes  SDValue Chain = Op.getOperand(0);
157285e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes  SDValue Dest = Op.getOperand(2);
1573f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1574772837778b831a52231ff33ef42d7970e9aa8467Bruno Cardoso Lopes
1575f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue CondRes = createFPCmp(DAG, Op.getOperand(1));
15761d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka
15777a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // Return if flag is not set by a floating point comparison.
15781d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  if (CondRes.getOpcode() != MipsISD::FPCmp)
15794b877ca1c5f13f19c9b7c8142a4f7a23383b8b6aBruno Cardoso Lopes    return Op;
1580bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
1581772837778b831a52231ff33ef42d7970e9aa8467Bruno Cardoso Lopes  SDValue CCNode  = CondRes.getOperand(2);
1582f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman  Mips::CondCode CC =
1583f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    (Mips::CondCode)cast<ConstantSDNode>(CCNode)->getZExtValue();
1584f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue BrCode = DAG.getConstant(getFPBranchCodeFromCond(CC), MVT::i32);
158585e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes
1586f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return DAG.getNode(MipsISD::FPBrcond, DL, Op.getValueType(), Chain, BrCode,
15871d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka                     Dest, CondRes);
158885e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes}
158985e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso Lopes
159085e31e3a5301c31947e35258dce7efa8e788bd51Bruno Cardoso LopesSDValue MipsTargetLowering::
1591f635ef401786c84df32090251a8cf45981ecca33Akira HatanakalowerSELECT(SDValue Op, SelectionDAG &DAG) const
15926d399bdea269658a03b63de850595fbfdd487098Bruno Cardoso Lopes{
1593f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue Cond = createFPCmp(DAG, Op.getOperand(0));
15946d399bdea269658a03b63de850595fbfdd487098Bruno Cardoso Lopes
15957a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // Return if flag is not set by a floating point comparison.
15961d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka  if (Cond.getOpcode() != MipsISD::FPCmp)
15971d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka    return Op;
1598739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes
1599f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return createCMovFP(DAG, Cond, Op.getOperand(1), Op.getOperand(2),
16001d6b38d9d37d5de471f5954b23b46dac58136fecAkira Hatanaka                      Op.getDebugLoc());
16016d399bdea269658a03b63de850595fbfdd487098Bruno Cardoso Lopes}
16026d399bdea269658a03b63de850595fbfdd487098Bruno Cardoso Lopes
16033fef29d88100881e7a52e570c30052e0d44c62eeAkira HatanakaSDValue MipsTargetLowering::
1604f635ef401786c84df32090251a8cf45981ecca33Akira HatanakalowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
16053fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka{
16063fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka  DebugLoc DL = Op.getDebugLoc();
16073fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka  EVT Ty = Op.getOperand(0).getValueType();
16083fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka  SDValue Cond = DAG.getNode(ISD::SETCC, DL, getSetCCResultType(Ty),
16093fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka                             Op.getOperand(0), Op.getOperand(1),
16103fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka                             Op.getOperand(4));
16113fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka
16123fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka  return DAG.getNode(ISD::SELECT, DL, Op.getValueType(), Cond, Op.getOperand(2),
16133fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka                     Op.getOperand(3));
16143fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka}
16153fef29d88100881e7a52e570c30052e0d44c62eeAkira Hatanaka
1616f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerSETCC(SDValue Op, SelectionDAG &DAG) const {
1617f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue Cond = createFPCmp(DAG, Op);
16180a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka
16190a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka  assert(Cond.getOpcode() == MipsISD::FPCmp &&
16200a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka         "Floating point operand expected.");
16210a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka
16220a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka  SDValue True  = DAG.getConstant(1, MVT::i32);
16230a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka  SDValue False = DAG.getConstant(0, MVT::i32);
16240a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka
1625f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return createCMovFP(DAG, Cond, True, False, Op.getDebugLoc());
16260a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka}
16270a40c2353c7e95bce6aee9bc557b90d5e0789765Akira Hatanaka
1628f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op,
1629d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                               SelectionDAG &DAG) const {
1630de06470330260f5937e7ca558f5f5b3e171f2ee5Dale Johannesen  // FIXME there isn't actually debug info here
1631f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1632bb481f882093fb738d2bb15610c79364bada5496Jia Liu  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
163397843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso Lopes
1634a5903acd6bc15c6aa511068f8b79c79014c1b5d4Akira Hatanaka  if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
1635afc945b614a2bf99014d5820c8849451030ea82bAkira Hatanaka    const MipsTargetObjectFile &TLOF =
1636afc945b614a2bf99014d5820c8849451030ea82bAkira Hatanaka      (const MipsTargetObjectFile&)getObjFileLowering();
1637bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
1638e3736f86caae62b691ad5be960e724fe0bf52dbdChris Lattner    // %gp_rel relocation
1639bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (TLOF.IsGlobalInSmallSection(GV, getTargetMachine())) {
1640f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, 0,
1641c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes                                              MipsII::MO_GPREL);
1642f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, DL,
1643d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka                                      DAG.getVTList(MVT::i32), &GA, 1);
1644e7338cd550a4ccde6796d2987b482ea9f0e239efAkira Hatanaka      SDValue GPReg = DAG.getRegister(Mips::GP, MVT::i32);
1645f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      return DAG.getNode(ISD::ADD, DL, MVT::i32, GPReg, GPRelNode);
1646e3736f86caae62b691ad5be960e724fe0bf52dbdChris Lattner    }
1647d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka
164897843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso Lopes    // %hi/%lo relocation
1649d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka    return getAddrNonPIC(Op, DAG);
165097843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso Lopes  }
165197843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso Lopes
1652d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka  if (GV->hasInternalLinkage() || (GV->hasLocalLinkage() && !isa<Function>(GV)))
1653d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka    return getAddrLocal(Op, DAG, HasMips64);
1654d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka
1655f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka  if (LargeGOT)
1656f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka    return getAddrGlobalLargeGOT(Op, DAG, MipsII::MO_GOT_HI16,
1657f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka                                 MipsII::MO_GOT_LO16);
1658f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka
1659d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka  return getAddrGlobal(Op, DAG,
1660d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka                       HasMips64 ? MipsII::MO_GOT_DISP : MipsII::MO_GOT16);
166197843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso Lopes}
166297843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso Lopes
1663f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerBlockAddress(SDValue Op,
1664ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes                                              SelectionDAG &DAG) const {
1665d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka  if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64)
1666d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka    return getAddrNonPIC(Op, DAG);
1667f48eb533d56ee57afdfdf62fec6a74aa0b3bbf27Akira Hatanaka
1668d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka  return getAddrLocal(Op, DAG, HasMips64);
1669ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes}
1670ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes
167197843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso LopesSDValue MipsTargetLowering::
1672f635ef401786c84df32090251a8cf45981ecca33Akira HatanakalowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
167397843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso Lopes{
16743faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka  // If the relocation model is PIC, use the General Dynamic TLS Model or
16753faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka  // Local Dynamic TLS model, otherwise use the Initial Exec or
16763faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka  // Local Exec TLS Model.
1677d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes
1678d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
1679f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = GA->getDebugLoc();
1680d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes  const GlobalValue *GV = GA->getGlobal();
1681d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes  EVT PtrVT = getPointerTy();
1682d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes
1683fd5abd546e8e035755005a654d60d6f5f74cfe2cHans Wennborg  TLSModel::Model model = getTargetMachine().getTLSModel(GV);
1684fd5abd546e8e035755005a654d60d6f5f74cfe2cHans Wennborg
1685fd5abd546e8e035755005a654d60d6f5f74cfe2cHans Wennborg  if (model == TLSModel::GeneralDynamic || model == TLSModel::LocalDynamic) {
168670a07c7fc437045a2421d279a99b19981f08acc2Hans Wennborg    // General Dynamic and Local Dynamic TLS Model.
168770a07c7fc437045a2421d279a99b19981f08acc2Hans Wennborg    unsigned Flag = (model == TLSModel::LocalDynamic) ? MipsII::MO_TLSLDM
168870a07c7fc437045a2421d279a99b19981f08acc2Hans Wennborg                                                      : MipsII::MO_TLSGD;
168970a07c7fc437045a2421d279a99b19981f08acc2Hans Wennborg
1690f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue TGA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, Flag);
1691f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue Argument = DAG.getNode(MipsISD::Wrapper, DL, PtrVT,
1692f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                                   getGlobalReg(DAG, PtrVT), TGA);
16937a7194b5294661809ab37270c8ee5e94f8cdee18Akira Hatanaka    unsigned PtrSize = PtrVT.getSizeInBits();
16947a7194b5294661809ab37270c8ee5e94f8cdee18Akira Hatanaka    IntegerType *PtrTy = Type::getIntNTy(*DAG.getContext(), PtrSize);
16957a7194b5294661809ab37270c8ee5e94f8cdee18Akira Hatanaka
16965eccf674928a050be09d60d1b5d2a843eff5f2edBenjamin Kramer    SDValue TlsGetAddr = DAG.getExternalSymbol("__tls_get_addr", PtrVT);
1697d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes
1698d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes    ArgListTy Args;
1699d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes    ArgListEntry Entry;
1700d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes    Entry.Node = Argument;
1701ca0747917d3daa85287fd7ea6f91349b8d5a5b29Akira Hatanaka    Entry.Ty = PtrTy;
1702d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes    Args.push_back(Entry);
1703bb481f882093fb738d2bb15610c79364bada5496Jia Liu
1704d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski    TargetLowering::CallLoweringInfo CLI(DAG.getEntryNode(), PtrTy,
17054bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng                  false, false, false, false, 0, CallingConv::C,
1706f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                  /*IsTailCall=*/false, /*doesNotRet=*/false,
17074bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng                  /*isReturnValueUsed=*/true,
1708f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                  TlsGetAddr, Args, DAG, DL);
1709d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski    std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
1710d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes
17113faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka    SDValue Ret = CallResult.first;
17123faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka
1713fd5abd546e8e035755005a654d60d6f5f74cfe2cHans Wennborg    if (model != TLSModel::LocalDynamic)
17143faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka      return Ret;
17153faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka
1716f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue TGAHi = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
17173faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka                                               MipsII::MO_DTPREL_HI);
1718f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue Hi = DAG.getNode(MipsISD::Hi, DL, PtrVT, TGAHi);
1719f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue TGALo = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
17203faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka                                               MipsII::MO_DTPREL_LO);
1721f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue Lo = DAG.getNode(MipsISD::Lo, DL, PtrVT, TGALo);
1722f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue Add = DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Ret);
1723f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return DAG.getNode(ISD::ADD, DL, PtrVT, Add, Lo);
17245f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka  }
1725d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes
17265f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka  SDValue Offset;
1727fd5abd546e8e035755005a654d60d6f5f74cfe2cHans Wennborg  if (model == TLSModel::InitialExec) {
17285f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka    // Initial Exec TLS Model
1729f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue TGA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
17305f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka                                             MipsII::MO_GOTTPREL);
1731f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    TGA = DAG.getNode(MipsISD::Wrapper, DL, PtrVT, getGlobalReg(DAG, PtrVT),
1732648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka                      TGA);
1733f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    Offset = DAG.getLoad(PtrVT, DL,
17345f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka                         DAG.getEntryNode(), TGA, MachinePointerInfo(),
1735d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                         false, false, false, 0);
17365f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka  } else {
17375f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka    // Local Exec TLS Model
1738fd5abd546e8e035755005a654d60d6f5f74cfe2cHans Wennborg    assert(model == TLSModel::LocalExec);
1739f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue TGAHi = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
17405f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka                                               MipsII::MO_TPREL_HI);
1741f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue TGALo = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
17425f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka                                               MipsII::MO_TPREL_LO);
1743f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue Hi = DAG.getNode(MipsISD::Hi, DL, PtrVT, TGAHi);
1744f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue Lo = DAG.getNode(MipsISD::Lo, DL, PtrVT, TGALo);
1745f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    Offset = DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
1746d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes  }
17475f7451ff6e6967553588716d8630ef3bf8e78120Akira Hatanaka
1748f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue ThreadPointer = DAG.getNode(MipsISD::ThreadPointer, DL, PtrVT);
1749f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return DAG.getNode(ISD::ADD, DL, PtrVT, ThreadPointer, Offset);
175097843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso Lopes}
175197843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso Lopes
175297843cdb0b63735a4ade07cf7270c9a2198e0dc7Bruno Cardoso LopesSDValue MipsTargetLowering::
1753f635ef401786c84df32090251a8cf45981ecca33Akira HatanakalowerJumpTable(SDValue Op, SelectionDAG &DAG) const
1754753a98740bfe3164fd0961a1959306c46135cf19Bruno Cardoso Lopes{
1755d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka  if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64)
1756d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka    return getAddrNonPIC(Op, DAG);
1757753a98740bfe3164fd0961a1959306c46135cf19Bruno Cardoso Lopes
1758d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka  return getAddrLocal(Op, DAG, HasMips64);
1759753a98740bfe3164fd0961a1959306c46135cf19Bruno Cardoso Lopes}
1760753a98740bfe3164fd0961a1959306c46135cf19Bruno Cardoso Lopes
1761475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue MipsTargetLowering::
1762f635ef401786c84df32090251a8cf45981ecca33Akira HatanakalowerConstantPool(SDValue Op, SelectionDAG &DAG) const
176397c2537269e8c654bc9b3c471ebab927e9cf0b2aBruno Cardoso Lopes{
176492e87f23791851efb8f6a13c29bffe48f2850527Bruno Cardoso Lopes  // gp_rel relocation
1765bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // FIXME: we should reference the constant pool using small data sections,
17667a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // but the asm printer currently doesn't support this feature without
1767bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // hacking it. This feature should come soon so we can uncomment the
1768f33bc43c9a2a903e1cccefb616ed07d5a2ae4204Bruno Cardoso Lopes  // stuff below.
1769e2c74081998af2e64ed498d65cf501704796ccc0Eli Friedman  //if (IsInSmallSection(C->getType())) {
1770825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  //  SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, MVT::i32, CP);
1771825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  //  SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
1772bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  //  ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode);
1773d71cebf57591e2dc27930d3002848dddc76c3f92Bruno Cardoso Lopes
1774d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka  if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64)
1775d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka    return getAddrNonPIC(Op, DAG);
177692e87f23791851efb8f6a13c29bffe48f2850527Bruno Cardoso Lopes
1777d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka  return getAddrLocal(Op, DAG, HasMips64);
177897c2537269e8c654bc9b3c471ebab927e9cf0b2aBruno Cardoso Lopes}
177997c2537269e8c654bc9b3c471ebab927e9cf0b2aBruno Cardoso Lopes
1780f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const {
17811e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  MachineFunction &MF = DAG.getMachineFunction();
17821e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
17831e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman
1784f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
17851e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
17861e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman                                 getPointerTy());
17876059b8551dc1ddc24bb5830426bf7e11d394a426Bruno Cardoso Lopes
17886059b8551dc1ddc24bb5830426bf7e11d394a426Bruno Cardoso Lopes  // vastart just stores the address of the VarArgsFrameIndex slot into the
17896059b8551dc1ddc24bb5830426bf7e11d394a426Bruno Cardoso Lopes  // memory location argument.
17906059b8551dc1ddc24bb5830426bf7e11d394a426Bruno Cardoso Lopes  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1791f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
179282099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka                      MachinePointerInfo(SV), false, false, 0);
17936059b8551dc1ddc24bb5830426bf7e11d394a426Bruno Cardoso Lopes}
1794bb481f882093fb738d2bb15610c79364bada5496Jia Liu
1795f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue lowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG, bool HasR2) {
1796056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  EVT TyX = Op.getOperand(0).getValueType();
1797056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  EVT TyY = Op.getOperand(1).getValueType();
1798056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue Const1 = DAG.getConstant(1, MVT::i32);
1799056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue Const31 = DAG.getConstant(31, MVT::i32);
1800056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1801056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue Res;
1802056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka
1803056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  // If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it
1804056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  // to i32.
1805056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue X = (TyX == MVT::f32) ?
1806056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(0)) :
1807056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
1808056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka                Const1);
1809056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue Y = (TyY == MVT::f32) ?
1810056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(1)) :
1811056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(1),
1812056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka                Const1);
1813056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka
1814056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  if (HasR2) {
1815056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    // ext  E, Y, 31, 1  ; extract bit31 of Y
1816056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    // ins  X, E, 31, 1  ; insert extracted bit at bit31 of X
1817056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    SDValue E = DAG.getNode(MipsISD::Ext, DL, MVT::i32, Y, Const31, Const1);
1818056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    Res = DAG.getNode(MipsISD::Ins, DL, MVT::i32, E, Const31, Const1, X);
1819056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  } else {
1820056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    // sll SllX, X, 1
1821056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    // srl SrlX, SllX, 1
1822056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    // srl SrlY, Y, 31
1823056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    // sll SllY, SrlX, 31
1824056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    // or  Or, SrlX, SllY
1825056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    SDValue SllX = DAG.getNode(ISD::SHL, DL, MVT::i32, X, Const1);
1826056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    SDValue SrlX = DAG.getNode(ISD::SRL, DL, MVT::i32, SllX, Const1);
1827056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    SDValue SrlY = DAG.getNode(ISD::SRL, DL, MVT::i32, Y, Const31);
1828056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    SDValue SllY = DAG.getNode(ISD::SHL, DL, MVT::i32, SrlY, Const31);
1829056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    Res = DAG.getNode(ISD::OR, DL, MVT::i32, SrlX, SllY);
1830056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  }
18319c3d57c45e0ea788d9c6351345b91d2b8dea0a82Akira Hatanaka
1832056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  if (TyX == MVT::f32)
1833056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), Res);
1834471e4224809f51652c71f319532697a879a75a0dEric Christopher
1835056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue LowX = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
1836056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka                             Op.getOperand(0), DAG.getConstant(0, MVT::i32));
1837056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, LowX, Res);
1838056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka}
18399c3d57c45e0ea788d9c6351345b91d2b8dea0a82Akira Hatanaka
1840f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue lowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG, bool HasR2) {
1841056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  unsigned WidthX = Op.getOperand(0).getValueSizeInBits();
1842056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  unsigned WidthY = Op.getOperand(1).getValueSizeInBits();
1843056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  EVT TyX = MVT::getIntegerVT(WidthX), TyY = MVT::getIntegerVT(WidthY);
1844056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue Const1 = DAG.getConstant(1, MVT::i32);
1845056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1846056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka
1847056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  // Bitcast to integer nodes.
1848056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue X = DAG.getNode(ISD::BITCAST, DL, TyX, Op.getOperand(0));
1849056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue Y = DAG.getNode(ISD::BITCAST, DL, TyY, Op.getOperand(1));
1850056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka
1851056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  if (HasR2) {
1852056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    // ext  E, Y, width(Y) - 1, 1  ; extract bit width(Y)-1 of Y
1853056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    // ins  X, E, width(X) - 1, 1  ; insert extracted bit at bit width(X)-1 of X
1854056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    SDValue E = DAG.getNode(MipsISD::Ext, DL, TyY, Y,
1855056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka                            DAG.getConstant(WidthY - 1, MVT::i32), Const1);
1856056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka
1857056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    if (WidthX > WidthY)
1858056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka      E = DAG.getNode(ISD::ZERO_EXTEND, DL, TyX, E);
1859056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    else if (WidthY > WidthX)
1860056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka      E = DAG.getNode(ISD::TRUNCATE, DL, TyX, E);
1861056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka
1862056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    SDValue I = DAG.getNode(MipsISD::Ins, DL, TyX, E,
1863056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka                            DAG.getConstant(WidthX - 1, MVT::i32), Const1, X);
1864056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), I);
1865056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  }
1866056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka
1867056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  // (d)sll SllX, X, 1
1868056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  // (d)srl SrlX, SllX, 1
1869056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  // (d)srl SrlY, Y, width(Y)-1
1870056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  // (d)sll SllY, SrlX, width(Y)-1
1871056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  // or     Or, SrlX, SllY
1872056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue SllX = DAG.getNode(ISD::SHL, DL, TyX, X, Const1);
1873056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue SrlX = DAG.getNode(ISD::SRL, DL, TyX, SllX, Const1);
1874056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue SrlY = DAG.getNode(ISD::SRL, DL, TyY, Y,
1875056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka                             DAG.getConstant(WidthY - 1, MVT::i32));
1876056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka
1877056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  if (WidthX > WidthY)
1878056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    SrlY = DAG.getNode(ISD::ZERO_EXTEND, DL, TyX, SrlY);
1879056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  else if (WidthY > WidthX)
1880056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka    SrlY = DAG.getNode(ISD::TRUNCATE, DL, TyX, SrlY);
1881056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka
1882056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue SllY = DAG.getNode(ISD::SHL, DL, TyX, SrlY,
1883056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka                             DAG.getConstant(WidthX - 1, MVT::i32));
1884056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  SDValue Or = DAG.getNode(ISD::OR, DL, TyX, SrlX, SllY);
1885056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), Or);
18869c3d57c45e0ea788d9c6351345b91d2b8dea0a82Akira Hatanaka}
18879c3d57c45e0ea788d9c6351345b91d2b8dea0a82Akira Hatanaka
188882099683060abb1f74453d06e78a3729a75ef7eeAkira HatanakaSDValue
1889f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaMipsTargetLowering::lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
1890056c51e59820c4c36d3b9d2f22acb6fd121b798eAkira Hatanaka  if (Subtarget->hasMips64())
1891f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerFCOPYSIGN64(Op, DAG, Subtarget->hasMips32r2());
1892bb481f882093fb738d2bb15610c79364bada5496Jia Liu
1893f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return lowerFCOPYSIGN32(Op, DAG, Subtarget->hasMips32r2());
18949c3d57c45e0ea788d9c6351345b91d2b8dea0a82Akira Hatanaka}
18959c3d57c45e0ea788d9c6351345b91d2b8dea0a82Akira Hatanaka
1896f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG, bool HasR2) {
1897c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  SDValue Res, Const1 = DAG.getConstant(1, MVT::i32);
1898c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1899c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1900c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  // If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it
1901c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  // to i32.
1902c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  SDValue X = (Op.getValueType() == MVT::f32) ?
1903c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(0)) :
1904c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
1905c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka                Const1);
1906c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1907c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  // Clear MSB.
1908c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  if (HasR2)
1909c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    Res = DAG.getNode(MipsISD::Ins, DL, MVT::i32,
1910c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka                      DAG.getRegister(Mips::ZERO, MVT::i32),
1911c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka                      DAG.getConstant(31, MVT::i32), Const1, X);
1912c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  else {
1913c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    SDValue SllX = DAG.getNode(ISD::SHL, DL, MVT::i32, X, Const1);
1914c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    Res = DAG.getNode(ISD::SRL, DL, MVT::i32, SllX, Const1);
1915c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  }
1916c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1917c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  if (Op.getValueType() == MVT::f32)
1918c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    return DAG.getNode(ISD::BITCAST, DL, MVT::f32, Res);
1919c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1920c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  SDValue LowX = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
1921c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka                             Op.getOperand(0), DAG.getConstant(0, MVT::i32));
1922c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, LowX, Res);
1923c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka}
1924c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1925f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG, bool HasR2) {
1926c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  SDValue Res, Const1 = DAG.getConstant(1, MVT::i32);
1927c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1928c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1929c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  // Bitcast to integer node.
1930c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  SDValue X = DAG.getNode(ISD::BITCAST, DL, MVT::i64, Op.getOperand(0));
1931c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1932c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  // Clear MSB.
1933c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  if (HasR2)
1934c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    Res = DAG.getNode(MipsISD::Ins, DL, MVT::i64,
1935c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka                      DAG.getRegister(Mips::ZERO_64, MVT::i64),
1936c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka                      DAG.getConstant(63, MVT::i32), Const1, X);
1937c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  else {
1938c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    SDValue SllX = DAG.getNode(ISD::SHL, DL, MVT::i64, X, Const1);
1939c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka    Res = DAG.getNode(ISD::SRL, DL, MVT::i64, SllX, Const1);
1940c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  }
1941c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1942c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  return DAG.getNode(ISD::BITCAST, DL, MVT::f64, Res);
1943c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka}
1944c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1945c12a6e6b53bb6df62a0020bda91206fd149c430aAkira HatanakaSDValue
1946f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaMipsTargetLowering::lowerFABS(SDValue Op, SelectionDAG &DAG) const {
1947c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka  if (Subtarget->hasMips64() && (Op.getValueType() == MVT::f64))
1948f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerFABS64(Op, DAG, Subtarget->hasMips32r2());
1949c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
1950f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return lowerFABS32(Op, DAG, Subtarget->hasMips32r2());
1951c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka}
1952c12a6e6b53bb6df62a0020bda91206fd149c430aAkira Hatanaka
19532e591477af1ef8e3c5ba6d51e8aeee8c99c7fa8eAkira HatanakaSDValue MipsTargetLowering::
1954f635ef401786c84df32090251a8cf45981ecca33Akira HatanakalowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
1955e0b5cfcae88190bd45778e11d20bc676823098a7Bruno Cardoso Lopes  // check the depth
1956e0b5cfcae88190bd45778e11d20bc676823098a7Bruno Cardoso Lopes  assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
19570f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka         "Frame address can only be determined for current frame.");
19582e591477af1ef8e3c5ba6d51e8aeee8c99c7fa8eAkira Hatanaka
19592e591477af1ef8e3c5ba6d51e8aeee8c99c7fa8eAkira Hatanaka  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
19602e591477af1ef8e3c5ba6d51e8aeee8c99c7fa8eAkira Hatanaka  MFI->setFrameAddressIsTaken(true);
19612e591477af1ef8e3c5ba6d51e8aeee8c99c7fa8eAkira Hatanaka  EVT VT = Op.getValueType();
1962f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
1963f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL,
196446ac4399b13d46baa9e6280d540c468d8feba8adAkira Hatanaka                                         IsN64 ? Mips::FP_64 : Mips::FP, VT);
19652e591477af1ef8e3c5ba6d51e8aeee8c99c7fa8eAkira Hatanaka  return FrameAddr;
19662e591477af1ef8e3c5ba6d51e8aeee8c99c7fa8eAkira Hatanaka}
19672e591477af1ef8e3c5ba6d51e8aeee8c99c7fa8eAkira Hatanaka
1968f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerRETURNADDR(SDValue Op,
1969ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka                                            SelectionDAG &DAG) const {
1970ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka  // check the depth
1971ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka  assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
1972ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka         "Return address can be determined only for current frame.");
1973ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka
1974ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka  MachineFunction &MF = DAG.getMachineFunction();
1975ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka  MachineFrameInfo *MFI = MF.getFrameInfo();
1976a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund  MVT VT = Op.getSimpleValueType();
1977ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka  unsigned RA = IsN64 ? Mips::RA_64 : Mips::RA;
1978ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka  MFI->setReturnAddressIsTaken(true);
1979ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka
1980ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka  // Return RA, which contains the return address. Mark it an implicit live-in.
1981ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka  unsigned Reg = MF.addLiveIn(RA, getRegClassFor(VT));
1982ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka  return DAG.getCopyFromReg(DAG.getEntryNode(), Op.getDebugLoc(), Reg, VT);
1983ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka}
1984ba584fe8feb840a82ad5966cb9eca6df0eeaafc2Akira Hatanaka
1985544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka// An EH_RETURN is the result of lowering llvm.eh.return which in turn is
1986544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka// generated from __builtin_eh_return (offset, handler)
1987544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka// The effect of this is to adjust the stack pointer by "offset"
1988544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka// and then branch to "handler".
1989f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerEH_RETURN(SDValue Op, SelectionDAG &DAG)
1990544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka                                                                     const {
1991544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  MachineFunction &MF = DAG.getMachineFunction();
1992544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
1993544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
1994544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  MipsFI->setCallsEhReturn();
1995544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  SDValue Chain     = Op.getOperand(0);
1996544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  SDValue Offset    = Op.getOperand(1);
1997544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  SDValue Handler   = Op.getOperand(2);
1998544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  DebugLoc DL       = Op.getDebugLoc();
1999544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  EVT Ty = IsN64 ? MVT::i64 : MVT::i32;
2000544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
2001544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  // Store stack offset in V1, store jump target in V0. Glue CopyToReg and
2002544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  // EH_RETURN nodes, so that instructions are emitted back-to-back.
2003544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  unsigned OffsetReg = IsN64 ? Mips::V1_64 : Mips::V1;
2004544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  unsigned AddrReg = IsN64 ? Mips::V0_64 : Mips::V0;
2005544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  Chain = DAG.getCopyToReg(Chain, DL, OffsetReg, Offset, SDValue());
2006544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  Chain = DAG.getCopyToReg(Chain, DL, AddrReg, Handler, Chain.getValue(1));
2007544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  return DAG.getNode(MipsISD::EH_RETURN, DL, MVT::Other, Chain,
2008544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka                     DAG.getRegister(OffsetReg, Ty),
2009544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka                     DAG.getRegister(AddrReg, getPointerTy()),
2010544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka                     Chain.getValue(1));
2011544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka}
2012544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
2013db54826f20c6cbcb9b195c4b49c946d6488156ddAkira Hatanaka// TODO: set SType according to the desired memory barrier behavior.
201482099683060abb1f74453d06e78a3729a75ef7eeAkira HatanakaSDValue
2015f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaMipsTargetLowering::lowerMEMBARRIER(SDValue Op, SelectionDAG &DAG) const {
2016db54826f20c6cbcb9b195c4b49c946d6488156ddAkira Hatanaka  unsigned SType = 0;
2017f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
2018f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return DAG.getNode(MipsISD::Sync, DL, MVT::Other, Op.getOperand(0),
2019db54826f20c6cbcb9b195c4b49c946d6488156ddAkira Hatanaka                     DAG.getConstant(SType, MVT::i32));
2020db54826f20c6cbcb9b195c4b49c946d6488156ddAkira Hatanaka}
2021db54826f20c6cbcb9b195c4b49c946d6488156ddAkira Hatanaka
2022f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerATOMIC_FENCE(SDValue Op,
2023864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                                              SelectionDAG &DAG) const {
202414648468011c92a4210f8118721d58c25043daf8Eli Friedman  // FIXME: Need pseudo-fence for 'singlethread' fences
202514648468011c92a4210f8118721d58c25043daf8Eli Friedman  // FIXME: Set SType for weaker fences where supported/appropriate.
202614648468011c92a4210f8118721d58c25043daf8Eli Friedman  unsigned SType = 0;
2027f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
2028f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return DAG.getNode(MipsISD::Sync, DL, MVT::Other, Op.getOperand(0),
202914648468011c92a4210f8118721d58c25043daf8Eli Friedman                     DAG.getConstant(SType, MVT::i32));
203014648468011c92a4210f8118721d58c25043daf8Eli Friedman}
203114648468011c92a4210f8118721d58c25043daf8Eli Friedman
2032f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op,
2033864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                                                SelectionDAG &DAG) const {
2034a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
2035a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
2036a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Shamt = Op.getOperand(2);
2037a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka
2038a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  // if shamt < 32:
2039a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //  lo = (shl lo, shamt)
2040a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //  hi = (or (shl hi, shamt) (srl (srl lo, 1), ~shamt))
2041a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  // else:
2042a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //  lo = 0
2043a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //  hi = (shl lo, shamt[4:0])
2044a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
2045a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                            DAG.getConstant(-1, MVT::i32));
2046a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, MVT::i32, Lo,
2047a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                                      DAG.getConstant(1, MVT::i32));
2048a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, MVT::i32, ShiftRight1Lo,
2049a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                                     Not);
2050a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi, Shamt);
2051a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Or = DAG.getNode(ISD::OR, DL, MVT::i32, ShiftLeftHi, ShiftRightLo);
2052a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, MVT::i32, Lo, Shamt);
2053a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
2054a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                             DAG.getConstant(0x20, MVT::i32));
2055864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka  Lo = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond,
2056864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                   DAG.getConstant(0, MVT::i32), ShiftLeftLo);
2057a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  Hi = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, ShiftLeftLo, Or);
2058a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka
2059a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Ops[2] = {Lo, Hi};
2060a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  return DAG.getMergeValues(Ops, 2, DL);
2061a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka}
2062a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka
2063f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerShiftRightParts(SDValue Op, SelectionDAG &DAG,
2064a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                                                 bool IsSRA) const {
2065a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
2066a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
2067a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Shamt = Op.getOperand(2);
2068a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka
2069a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  // if shamt < 32:
2070a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //  lo = (or (shl (shl hi, 1), ~shamt) (srl lo, shamt))
2071a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //  if isSRA:
2072a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //    hi = (sra hi, shamt)
2073a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //  else:
2074a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //    hi = (srl hi, shamt)
2075a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  // else:
2076a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //  if isSRA:
2077a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //   lo = (sra hi, shamt[4:0])
2078a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //   hi = (sra hi, 31)
2079a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //  else:
2080a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //   lo = (srl hi, shamt[4:0])
2081a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  //   hi = 0
2082a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
2083a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                            DAG.getConstant(-1, MVT::i32));
2084a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi,
2085a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                                     DAG.getConstant(1, MVT::i32));
2086a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, MVT::i32, ShiftLeft1Hi, Not);
2087a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, MVT::i32, Lo, Shamt);
2088a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Or = DAG.getNode(ISD::OR, DL, MVT::i32, ShiftLeftHi, ShiftRightLo);
2089a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL, DL, MVT::i32,
2090a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                                     Hi, Shamt);
2091a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
2092a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                             DAG.getConstant(0x20, MVT::i32));
2093a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Shift31 = DAG.getNode(ISD::SRA, DL, MVT::i32, Hi,
2094a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                                DAG.getConstant(31, MVT::i32));
2095a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  Lo = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, ShiftRightHi, Or);
2096a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  Hi = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond,
2097a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                   IsSRA ? Shift31 : DAG.getConstant(0, MVT::i32),
2098a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka                   ShiftRightHi);
2099a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka
2100a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  SDValue Ops[2] = {Lo, Hi};
2101a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka  return DAG.getMergeValues(Ops, 2, DL);
2102a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka}
2103a284acb8a79468f378452826b2426b4bcdc27e94Akira Hatanaka
21041cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanakastatic SDValue CreateLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD,
21051cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                            SDValue Chain, SDValue Src, unsigned Offset) {
21062bd7e532b49cb461f7e16acb01124b56aa169844Akira Hatanaka  SDValue Ptr = LD->getBasePtr();
21071cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  EVT VT = LD->getValueType(0), MemVT = LD->getMemoryVT();
21082bd7e532b49cb461f7e16acb01124b56aa169844Akira Hatanaka  EVT BasePtrVT = Ptr.getValueType();
21091cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  DebugLoc DL = LD->getDebugLoc();
21101cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDVTList VTList = DAG.getVTList(VT, MVT::Other);
21111cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21121cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  if (Offset)
21132bd7e532b49cb461f7e16acb01124b56aa169844Akira Hatanaka    Ptr = DAG.getNode(ISD::ADD, DL, BasePtrVT, Ptr,
21141cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                      DAG.getConstant(Offset, BasePtrVT));
21151cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21161cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDValue Ops[] = { Chain, Ptr, Src };
21171cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  return DAG.getMemIntrinsicNode(Opc, DL, VTList, Ops, 3, MemVT,
21181cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                                 LD->getMemOperand());
21191cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka}
21201cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21211cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka// Expand an unaligned 32 or 64-bit integer load node.
2122f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
21231cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  LoadSDNode *LD = cast<LoadSDNode>(Op);
21241cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  EVT MemVT = LD->getMemoryVT();
21251cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21261cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // Return if load is aligned or if MemVT is neither i32 nor i64.
21271cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  if ((LD->getAlignment() >= MemVT.getSizeInBits() / 8) ||
21281cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka      ((MemVT != MVT::i32) && (MemVT != MVT::i64)))
21291cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka    return SDValue();
21301cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21311cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  bool IsLittle = Subtarget->isLittle();
21321cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  EVT VT = Op.getValueType();
21331cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  ISD::LoadExtType ExtType = LD->getExtensionType();
21341cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDValue Chain = LD->getChain(), Undef = DAG.getUNDEF(VT);
21351cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21361cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  assert((VT == MVT::i32) || (VT == MVT::i64));
21371cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21381cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // Expand
21391cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set dst, (i64 (load baseptr)))
21401cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // to
21411cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set tmp, (ldl (add baseptr, 7), undef))
21421cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set dst, (ldr baseptr, tmp))
21431cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  if ((VT == MVT::i64) && (ExtType == ISD::NON_EXTLOAD)) {
21441cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka    SDValue LDL = CreateLoadLR(MipsISD::LDL, DAG, LD, Chain, Undef,
21451cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                               IsLittle ? 7 : 0);
21461cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka    return CreateLoadLR(MipsISD::LDR, DAG, LD, LDL.getValue(1), LDL,
21471cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                        IsLittle ? 0 : 7);
21481cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  }
21491cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21501cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDValue LWL = CreateLoadLR(MipsISD::LWL, DAG, LD, Chain, Undef,
21511cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                             IsLittle ? 3 : 0);
21521cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDValue LWR = CreateLoadLR(MipsISD::LWR, DAG, LD, LWL.getValue(1), LWL,
21531cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                             IsLittle ? 0 : 3);
21541cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21551cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // Expand
21561cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set dst, (i32 (load baseptr))) or
21571cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set dst, (i64 (sextload baseptr))) or
21581cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set dst, (i64 (extload baseptr)))
21591cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // to
21601cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set tmp, (lwl (add baseptr, 3), undef))
21611cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set dst, (lwr baseptr, tmp))
21621cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  if ((VT == MVT::i32) || (ExtType == ISD::SEXTLOAD) ||
21631cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka      (ExtType == ISD::EXTLOAD))
21641cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka    return LWR;
21651cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21661cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  assert((VT == MVT::i64) && (ExtType == ISD::ZEXTLOAD));
21671cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21681cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // Expand
21691cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set dst, (i64 (zextload baseptr)))
21701cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // to
21711cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set tmp0, (lwl (add baseptr, 3), undef))
21721cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set tmp1, (lwr baseptr, tmp0))
21731cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set tmp2, (shl tmp1, 32))
21741cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (set dst, (srl tmp2, 32))
21751cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  DebugLoc DL = LD->getDebugLoc();
21761cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDValue Const32 = DAG.getConstant(32, MVT::i32);
21771cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDValue SLL = DAG.getNode(ISD::SHL, DL, MVT::i64, LWR, Const32);
217894ccee2222fa841d7ca3b13305934a570d90767fAkira Hatanaka  SDValue SRL = DAG.getNode(ISD::SRL, DL, MVT::i64, SLL, Const32);
217994ccee2222fa841d7ca3b13305934a570d90767fAkira Hatanaka  SDValue Ops[] = { SRL, LWR.getValue(1) };
21801cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  return DAG.getMergeValues(Ops, 2, DL);
21811cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka}
21821cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21831cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanakastatic SDValue CreateStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD,
21841cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                             SDValue Chain, unsigned Offset) {
21852bd7e532b49cb461f7e16acb01124b56aa169844Akira Hatanaka  SDValue Ptr = SD->getBasePtr(), Value = SD->getValue();
21862bd7e532b49cb461f7e16acb01124b56aa169844Akira Hatanaka  EVT MemVT = SD->getMemoryVT(), BasePtrVT = Ptr.getValueType();
21871cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  DebugLoc DL = SD->getDebugLoc();
21881cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDVTList VTList = DAG.getVTList(MVT::Other);
21891cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21901cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  if (Offset)
21912bd7e532b49cb461f7e16acb01124b56aa169844Akira Hatanaka    Ptr = DAG.getNode(ISD::ADD, DL, BasePtrVT, Ptr,
21921cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                      DAG.getConstant(Offset, BasePtrVT));
21931cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21941cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDValue Ops[] = { Chain, Value, Ptr };
21951cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  return DAG.getMemIntrinsicNode(Opc, DL, VTList, Ops, 3, MemVT,
21961cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                                 SD->getMemOperand());
21971cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka}
21981cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
21991cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka// Expand an unaligned 32 or 64-bit integer store node.
2200f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
22011cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  StoreSDNode *SD = cast<StoreSDNode>(Op);
22021cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  EVT MemVT = SD->getMemoryVT();
22031cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
22041cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // Return if store is aligned or if MemVT is neither i32 nor i64.
22051cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  if ((SD->getAlignment() >= MemVT.getSizeInBits() / 8) ||
22061cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka      ((MemVT != MVT::i32) && (MemVT != MVT::i64)))
22071cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka    return SDValue();
22081cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
22091cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  bool IsLittle = Subtarget->isLittle();
22101cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDValue Value = SD->getValue(), Chain = SD->getChain();
22111cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  EVT VT = Value.getValueType();
22121cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
22131cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // Expand
22141cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (store val, baseptr) or
22151cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (truncstore val, baseptr)
22161cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // to
22171cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (swl val, (add baseptr, 3))
22181cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (swr val, baseptr)
22191cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  if ((VT == MVT::i32) || SD->isTruncatingStore()) {
22201cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka    SDValue SWL = CreateStoreLR(MipsISD::SWL, DAG, SD, Chain,
22211cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka                                IsLittle ? 3 : 0);
22221cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka    return CreateStoreLR(MipsISD::SWR, DAG, SD, SWL, IsLittle ? 0 : 3);
22231cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  }
22241cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
22251cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  assert(VT == MVT::i64);
22261cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
22271cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // Expand
22281cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (store val, baseptr)
22291cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  // to
22301cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (sdl val, (add baseptr, 7))
22311cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  //  (sdr val, baseptr)
22321cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  SDValue SDL = CreateStoreLR(MipsISD::SDL, DAG, SD, Chain, IsLittle ? 7 : 0);
22331cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka  return CreateStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7);
22341cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka}
22351cd0ec007a4bdce4acf2ba99fe9231fd0859ea80Akira Hatanaka
2236fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// This function expands mips intrinsic nodes which have 64-bit input operands
2237fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// or output values.
2238fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka//
2239fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// out64 = intrinsic-node in64
2240fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// =>
2241fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// lo = copy (extract-element (in64, 0))
2242fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// hi = copy (extract-element (in64, 1))
2243fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// mips-specific-node
2244fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// v0 = copy lo
2245fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// v1 = copy hi
2246fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka// out64 = merge-values (v0, v1)
2247fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka//
2248f635ef401786c84df32090251a8cf45981ecca33Akira Hatanakastatic SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG,
2249fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                            unsigned Opc, bool HasI64In, bool HasI64Out) {
2250fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  DebugLoc DL = Op.getDebugLoc();
2251fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
2252fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  SDValue Chain = HasChainIn ? Op->getOperand(0) : DAG.getEntryNode();
2253fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  SmallVector<SDValue, 3> Ops;
2254fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2255fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  if (HasI64In) {
2256fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32,
2257fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                               Op->getOperand(1 + HasChainIn),
2258fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                               DAG.getConstant(0, MVT::i32));
2259fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32,
2260fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                               Op->getOperand(1 + HasChainIn),
2261fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                               DAG.getConstant(1, MVT::i32));
2262fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2263fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    Chain = DAG.getCopyToReg(Chain, DL, Mips::LO, InLo, SDValue());
2264fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    Chain = DAG.getCopyToReg(Chain, DL, Mips::HI, InHi, Chain.getValue(1));
2265fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2266fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    Ops.push_back(Chain);
2267fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    Ops.append(Op->op_begin() + HasChainIn + 2, Op->op_end());
2268fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    Ops.push_back(Chain.getValue(1));
2269fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  } else {
2270fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    Ops.push_back(Chain);
2271fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    Ops.append(Op->op_begin() + HasChainIn + 1, Op->op_end());
2272fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  }
2273fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2274fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  if (!HasI64Out)
2275fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    return DAG.getNode(Opc, DL, Op->value_begin(), Op->getNumValues(),
2276fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                       Ops.begin(), Ops.size());
2277fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2278fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  SDValue Intr = DAG.getNode(Opc, DL, DAG.getVTList(MVT::Other, MVT::Glue),
2279fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                             Ops.begin(), Ops.size());
2280fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  SDValue OutLo = DAG.getCopyFromReg(Intr.getValue(0), DL, Mips::LO, MVT::i32,
2281fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                                     Intr.getValue(1));
2282fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  SDValue OutHi = DAG.getCopyFromReg(OutLo.getValue(1), DL, Mips::HI, MVT::i32,
2283fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                                     OutLo.getValue(2));
2284fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  SDValue Out = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, OutLo, OutHi);
2285fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2286fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  if (!HasChainIn)
2287fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    return Out;
2288fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2289fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  SDValue Vals[] = { Out, OutHi.getValue(1) };
2290fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  return DAG.getMergeValues(Vals, 2, DL);
2291fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka}
2292fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2293f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
2294fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                                                    SelectionDAG &DAG) const {
2295fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
2296fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  default:
2297fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    return SDValue();
22982df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_shilo:
2299f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::SHILO, true, true);
23002df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpau_h_qbl:
2301f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL, true, true);
23022df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpau_h_qbr:
2303f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR, true, true);
23042df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpsu_h_qbl:
2305f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL, true, true);
23062df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpsu_h_qbr:
2307f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR, true, true);
23082df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpa_w_ph:
2309f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH, true, true);
23102df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dps_w_ph:
2311f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH, true, true);
23122df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpax_w_ph:
2313f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH, true, true);
23142df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpsx_w_ph:
2315f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH, true, true);
23162df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_mulsa_w_ph:
2317f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH, true, true);
23182df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_mult:
2319f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MULT, false, true);
23202df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_multu:
2321f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MULTU, false, true);
23222df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_madd:
2323f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MADD_DSP, true, true);
23242df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_maddu:
2325f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MADDU_DSP, true, true);
23262df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_msub:
2327f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MSUB_DSP, true, true);
23282df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_msubu:
2329f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MSUBU_DSP, true, true);
2330fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  }
2331fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka}
2332fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2333f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
2334fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka                                                   SelectionDAG &DAG) const {
2335fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  switch (cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue()) {
2336fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  default:
2337fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka    return SDValue();
2338fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  case Intrinsic::mips_extp:
2339f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTP, true, false);
2340fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  case Intrinsic::mips_extpdp:
2341f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP, true, false);
2342fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  case Intrinsic::mips_extr_w:
2343f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W, true, false);
2344fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  case Intrinsic::mips_extr_r_w:
2345f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W, true, false);
2346fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  case Intrinsic::mips_extr_rs_w:
2347f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W, true, false);
2348fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  case Intrinsic::mips_extr_s_h:
2349f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H, true, false);
23502df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_mthlip:
2351f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP, true, true);
23522df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_mulsaq_s_w_ph:
2353f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH, true, true);
23542df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_maq_s_w_phl:
2355f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL, true, true);
23562df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_maq_s_w_phr:
2357f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR, true, true);
23582df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_maq_sa_w_phl:
2359f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL, true, true);
23602df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_maq_sa_w_phr:
2361f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR, true, true);
23622df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpaq_s_w_ph:
2363f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH, true, true);
23642df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpsq_s_w_ph:
2365f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH, true, true);
23662df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpaq_sa_l_w:
2367f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W, true, true);
23682df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpsq_sa_l_w:
2369f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W, true, true);
23702df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpaqx_s_w_ph:
2371f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH, true, true);
23722df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpaqx_sa_w_ph:
2373f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH, true, true);
23742df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpsqx_s_w_ph:
2375f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH, true, true);
23762df483efb3a3d99dd82eb88e13490ae464bf0e43Akira Hatanaka  case Intrinsic::mips_dpsqx_sa_w_ph:
2377f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH, true, true);
2378fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka  }
2379fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka}
2380fd89e6ffdab95ae6b4568b8a4153064952f61ea6Akira Hatanaka
2381f635ef401786c84df32090251a8cf45981ecca33Akira HatanakaSDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const {
2382e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  if (Op->getOperand(0).getOpcode() != ISD::FRAMEADDR
2383e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka      || cast<ConstantSDNode>
2384e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka        (Op->getOperand(0).getOperand(0))->getZExtValue() != 0
2385e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka      || Op->getOperand(1).getOpcode() != ISD::FRAME_TO_ARGS_OFFSET)
2386e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka    return SDValue();
2387e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka
2388e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  // The pattern
2389e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  //   (add (frameaddr 0), (frame_to_args_offset))
2390e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  // results from lowering llvm.eh.dwarf.cfa intrinsic. Transform it to
2391e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  //   (add FrameObject, 0)
2392e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  // where FrameObject is a fixed StackObject with offset 0 which points to
2393e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  // the old stack pointer.
2394e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
2395e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  EVT ValTy = Op->getValueType(0);
2396e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  int FI = MFI->CreateFixedObject(Op.getValueSizeInBits() / 8, 0, false);
2397e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  SDValue InArgsAddr = DAG.getFrameIndex(FI, ValTy);
2398e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka  return DAG.getNode(ISD::ADD, Op->getDebugLoc(), ValTy, InArgsAddr,
2399e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka                     DAG.getConstant(0, ValTy));
2400e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka}
2401e90a3bcae1cd936aa760cffe5607266279b210d1Akira Hatanaka
24024552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
2403972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//                      Calling Convention Implementation
24044552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
2405972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
24064552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
2407bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck// TODO: Implement a generic logic using tblgen that can support this.
2408b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes// Mips O32 ABI rules:
2409b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes// ---
2410b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes// i32 - Passed in A0, A1, A2, A3 and stack
2411bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck// f32 - Only passed in f32 registers if no int reg has been used yet to hold
2412b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes//       an argument. Otherwise, passed in A1, A2, A3 and stack.
2413bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck// f64 - Only passed in two aliased f32 registers if no int reg has been used
2414bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck//       yet to hold an argument. Otherwise, use A2, A3 and stack. If A1 is
2415b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes//       not used, it must be shadowed. If only A3 is avaiable, shadow it and
2416b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes//       go to stack.
241795b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka//
241895b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka//  For vararg functions, all arguments are passed in A0, A1, A2, A3 and stack.
24194552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
2420b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes
24211e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sandsstatic bool CC_MipsO32(unsigned ValNo, MVT ValVT,
24221440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands                       MVT LocVT, CCValAssign::LocInfo LocInfo,
2423b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes                       ISD::ArgFlagsTy ArgFlags, CCState &State) {
2424b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes
2425bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  static const unsigned IntRegsSize=4, FloatRegsSize=2;
2426b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes
2427c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper  static const uint16_t IntRegs[] = {
2428b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes      Mips::A0, Mips::A1, Mips::A2, Mips::A3
2429b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes  };
2430c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper  static const uint16_t F32Regs[] = {
2431b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes      Mips::F12, Mips::F14
2432b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes  };
2433c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper  static const uint16_t F64Regs[] = {
2434b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes      Mips::D6, Mips::D7
2435b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes  };
2436b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes
2437fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  // Do not process byval args here.
2438fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  if (ArgFlags.isByVal())
2439fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka    return true;
24404231c7ea6d278b6a07ce51c28d7e00e1d300d210Akira Hatanaka
2441b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes  // Promote i8 and i16
2442b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes  if (LocVT == MVT::i8 || LocVT == MVT::i16) {
2443b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes    LocVT = MVT::i32;
2444b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes    if (ArgFlags.isSExt())
2445b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes      LocInfo = CCValAssign::SExt;
2446b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes    else if (ArgFlags.isZExt())
2447b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes      LocInfo = CCValAssign::ZExt;
2448b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes    else
2449b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes      LocInfo = CCValAssign::AExt;
2450b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes  }
2451b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes
2452c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes  unsigned Reg;
2453b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes
245495b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka  // f32 and f64 are allocated in A0, A1, A2, A3 when either of the following
245595b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka  // is true: function is vararg, argument is 3rd or higher, there is previous
245695b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka  // argument which is not f32 or f64.
245795b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka  bool AllocateFloatsInIntReg = State.isVarArg() || ValNo > 1
245895b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka      || State.getFirstUnallocated(F32Regs, FloatRegsSize) != ValNo;
2459a1a7ba838230b4b77604cc9a9fbd22f40f354ba2Akira Hatanaka  unsigned OrigAlign = ArgFlags.getOrigAlign();
2460a1a7ba838230b4b77604cc9a9fbd22f40f354ba2Akira Hatanaka  bool isI64 = (ValVT == MVT::i32 && OrigAlign == 8);
246195b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka
246295b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka  if (ValVT == MVT::i32 || (ValVT == MVT::f32 && AllocateFloatsInIntReg)) {
2463c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes    Reg = State.AllocateReg(IntRegs, IntRegsSize);
2464a1a7ba838230b4b77604cc9a9fbd22f40f354ba2Akira Hatanaka    // If this is the first part of an i64 arg,
2465a1a7ba838230b4b77604cc9a9fbd22f40f354ba2Akira Hatanaka    // the allocated register must be either A0 or A2.
2466a1a7ba838230b4b77604cc9a9fbd22f40f354ba2Akira Hatanaka    if (isI64 && (Reg == Mips::A1 || Reg == Mips::A3))
2467a1a7ba838230b4b77604cc9a9fbd22f40f354ba2Akira Hatanaka      Reg = State.AllocateReg(IntRegs, IntRegsSize);
2468c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes    LocVT = MVT::i32;
246995b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka  } else if (ValVT == MVT::f64 && AllocateFloatsInIntReg) {
247095b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka    // Allocate int register and shadow next int register. If first
247195b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka    // available register is Mips::A1 or Mips::A3, shadow it too.
2472c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes    Reg = State.AllocateReg(IntRegs, IntRegsSize);
2473c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes    if (Reg == Mips::A1 || Reg == Mips::A3)
2474c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes      Reg = State.AllocateReg(IntRegs, IntRegsSize);
2475c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes    State.AllocateReg(IntRegs, IntRegsSize);
2476c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes    LocVT = MVT::i32;
247795b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka  } else if (ValVT.isFloatingPoint() && !AllocateFloatsInIntReg) {
247895b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka    // we are guaranteed to find an available float register
247995b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka    if (ValVT == MVT::f32) {
248095b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka      Reg = State.AllocateReg(F32Regs, FloatRegsSize);
248195b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka      // Shadow int register
248295b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka      State.AllocateReg(IntRegs, IntRegsSize);
248395b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka    } else {
248495b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka      Reg = State.AllocateReg(F64Regs, FloatRegsSize);
248595b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka      // Shadow int registers
248695b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka      unsigned Reg2 = State.AllocateReg(IntRegs, IntRegsSize);
248795b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka      if (Reg2 == Mips::A1 || Reg2 == Mips::A3)
248895b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka        State.AllocateReg(IntRegs, IntRegsSize);
248995b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka      State.AllocateReg(IntRegs, IntRegsSize);
249095b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717Akira Hatanaka    }
2491c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes  } else
2492c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes    llvm_unreachable("Cannot handle this ValVT.");
2493b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes
2494fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  if (!Reg) {
2495fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka    unsigned Offset = State.AllocateStack(ValVT.getSizeInBits() >> 3,
2496fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka                                          OrigAlign);
2497c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes    State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
2498fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  } else
2499c42fb5f81c80c0d2713ca34d2216ced764ff8b14Bruno Cardoso Lopes    State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
2500b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes
2501fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  return false;
25022c5d65202e690bd46f69aa142342c0d61b7ac42aAkira Hatanaka}
25032c5d65202e690bd46f69aa142342c0d61b7ac42aAkira Hatanaka
25042c5d65202e690bd46f69aa142342c0d61b7ac42aAkira Hatanaka#include "MipsGenCallingConv.inc"
25052c5d65202e690bd46f69aa142342c0d61b7ac42aAkira Hatanaka
25064552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
250798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman//                  Call Calling Convention Implementation
25084552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
2509972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
25104231c7ea6d278b6a07ce51c28d7e00e1d300d210Akira Hatanakastatic const unsigned O32IntRegsSize = 4;
25114231c7ea6d278b6a07ce51c28d7e00e1d300d210Akira Hatanaka
2512373e3a4091c85d62eb2ee10dd106ddb4d28be566Akira Hatanaka// Return next O32 integer argument register.
2513373e3a4091c85d62eb2ee10dd106ddb4d28be566Akira Hatanakastatic unsigned getNextIntArgReg(unsigned Reg) {
2514373e3a4091c85d62eb2ee10dd106ddb4d28be566Akira Hatanaka  assert((Reg == Mips::A0) || (Reg == Mips::A2));
2515373e3a4091c85d62eb2ee10dd106ddb4d28be566Akira Hatanaka  return (Reg == Mips::A0) ? Mips::A1 : Mips::A3;
2516373e3a4091c85d62eb2ee10dd106ddb4d28be566Akira Hatanaka}
2517373e3a4091c85d62eb2ee10dd106ddb4d28be566Akira Hatanaka
25187d71209912bb55856f34df7013382e6dd310983bAkira HatanakaSDValue
25197d71209912bb55856f34df7013382e6dd310983bAkira HatanakaMipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset,
25207d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka                                   SDValue Chain, SDValue Arg, DebugLoc DL,
25217d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka                                   bool IsTailCall, SelectionDAG &DAG) const {
25227d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka  if (!IsTailCall) {
25237d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka    SDValue PtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr,
25247d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka                                 DAG.getIntPtrConstant(Offset));
25257d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka    return DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo(), false,
25267d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka                        false, 0);
25277d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka  }
25287d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka
25297d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
25307d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka  int FI = MFI->CreateFixedObject(Arg.getValueSizeInBits() / 8, Offset, false);
25317d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka  SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
25327d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka  return DAG.getStore(Chain, DL, Arg, FIN, MachinePointerInfo(),
25337d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka                      /*isVolatile=*/ true, false, 0);
25347d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka}
25357d71209912bb55856f34df7013382e6dd310983bAkira Hatanaka
25365ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakavoid MipsTargetLowering::
25375ac065a79767cc112eba63136183b7103765d0d3Akira HatanakagetOpndList(SmallVectorImpl<SDValue> &Ops,
25385ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka            std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
25395ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka            bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
25405ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka            CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
25415ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Insert node "GP copy globalreg" before call to function.
25425ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //
25435ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // R_MIPS_CALL* operators (emitted when non-internal functions are called
25445ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // in PIC mode) allow symbols to be resolved via lazy binding.
25455ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // The lazy binding stub requires GP to point to the GOT.
25465ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (IsPICCall && !InternalLinkage) {
25475ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    unsigned GPReg = IsN64 ? Mips::GP_64 : Mips::GP;
25485ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    EVT Ty = IsN64 ? MVT::i64 : MVT::i32;
25495ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    RegsToPass.push_back(std::make_pair(GPReg, getGlobalReg(CLI.DAG, Ty)));
25508453b3f66a3c3200ea828491ef5cf162db9ccfb2Reed Kotler  }
25518453b3f66a3c3200ea828491ef5cf162db9ccfb2Reed Kotler
25525ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Build a sequence of copy-to-reg nodes chained together with token
25535ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // chain and flag operands which copy the outgoing args into registers.
25545ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // The InFlag in necessary since all emitted instructions must be
25555ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // stuck together.
25565ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  SDValue InFlag;
25575ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
25585ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
25595ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    Chain = CLI.DAG.getCopyToReg(Chain, CLI.DL, RegsToPass[i].first,
25605ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                 RegsToPass[i].second, InFlag);
25615ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    InFlag = Chain.getValue(1);
25628453b3f66a3c3200ea828491ef5cf162db9ccfb2Reed Kotler  }
25635ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
25645ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Add argument registers to the end of the list so that they are
25655ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // known live into the call.
25665ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
25675ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    Ops.push_back(CLI.DAG.getRegister(RegsToPass[i].first,
25685ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                      RegsToPass[i].second.getValueType()));
25695ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
25705ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Add a register mask operand representing the call-preserved registers.
25715ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo();
25725ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  const uint32_t *Mask = TRI->getCallPreservedMask(CLI.CallConv);
25735ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  assert(Mask && "Missing call preserved mask for calling convention");
25745ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  Ops.push_back(CLI.DAG.getRegisterMask(Mask));
25755ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
25765ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (InFlag.getNode())
25775ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    Ops.push_back(InFlag);
25788453b3f66a3c3200ea828491ef5cf162db9ccfb2Reed Kotler}
25798453b3f66a3c3200ea828491ef5cf162db9ccfb2Reed Kotler
258098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCall - functions arguments are copied from virtual regs to
25815bf4b7556f025587a8d1a14bd0fb39c12fc9c170Nate Begeman/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
258298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
2583d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
2584d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                              SmallVectorImpl<SDValue> &InVals) const {
2585d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SelectionDAG &DAG                     = CLI.DAG;
2586f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  DebugLoc &DL                          = CLI.DL;
2587d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
2588d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<SDValue, 32> &OutVals     = CLI.OutVals;
2589d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<ISD::InputArg, 32> &Ins   = CLI.Ins;
2590e2d529ac1111f153628a9c5c654f4a514e841b47Akira Hatanaka  SDValue Chain                         = CLI.Chain;
2591d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Callee                        = CLI.Callee;
2592f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  bool &IsTailCall                      = CLI.IsTailCall;
2593d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  CallingConv::ID CallConv              = CLI.CallConv;
2594f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  bool IsVarArg                         = CLI.IsVarArg;
2595d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski
259698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  MachineFunction &MF = DAG.getMachineFunction();
25972ab22d1b9313dea627162309fb434b990d4dd6d6Bruno Cardoso Lopes  MachineFrameInfo *MFI = MF.getFrameInfo();
2598d37776d1c15977d9d86cab08250b6cfd847b7caeAkira Hatanaka  const TargetFrameLowering *TFL = MF.getTarget().getFrameLowering();
2599c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes  bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
2600972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2601972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // Analyze operands of the call, assigning locations to each operand.
2602972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  SmallVector<CCValAssign, 16> ArgLocs;
2603f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
260482099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka                 getTargetMachine(), ArgLocs, *DAG.getContext());
2605ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  MipsCC MipsCCInfo(CallConv, IsO32, CCInfo);
26062ab22d1b9313dea627162309fb434b990d4dd6d6Bruno Cardoso Lopes
2607f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  MipsCCInfo.analyzeCallOperands(Outs, IsVarArg,
2608cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka                                 getTargetMachine().Options.UseSoftFloat,
2609cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka                                 Callee.getNode(), CLI.Args);
2610bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
2611972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // Get a count of how many bytes are to be pushed on the stack.
26123d21c2495d481f42bab9f8313b46e7bcf0e2d7acAkira Hatanaka  unsigned NextStackOffset = CCInfo.getNextStackOffset();
2613480eeb54315e35b9d18213c2d56d2166e154b62dAkira Hatanaka
26142b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka  // Check if it's really possible to do a tail call.
2615f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  if (IsTailCall)
2616f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    IsTailCall =
2617f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      isEligibleForTailCallOptimization(MipsCCInfo, NextStackOffset,
26182f34d754d00fbe2e4a98762d71d0fae5f4b0cf45Akira Hatanaka                                        *MF.getInfo<MipsFunctionInfo>());
26192b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka
2620f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  if (IsTailCall)
26212b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka    ++NumTailCalls;
26222b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka
2623da7f5f1c1df1869460bffaa358bf5a607781388bAkira Hatanaka  // Chain is the output chain of the last Load/Store or CopyToReg node.
2624da7f5f1c1df1869460bffaa358bf5a607781388bAkira Hatanaka  // ByValChain is the output chain of the last Memcpy node created for copying
2625da7f5f1c1df1869460bffaa358bf5a607781388bAkira Hatanaka  // byval arguments to the stack.
26262f34d754d00fbe2e4a98762d71d0fae5f4b0cf45Akira Hatanaka  unsigned StackAlignment = TFL->getStackAlignment();
26272f34d754d00fbe2e4a98762d71d0fae5f4b0cf45Akira Hatanaka  NextStackOffset = RoundUpToAlignment(NextStackOffset, StackAlignment);
2628da7f5f1c1df1869460bffaa358bf5a607781388bAkira Hatanaka  SDValue NextStackOffsetVal = DAG.getIntPtrConstant(NextStackOffset, true);
26292b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka
2630f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  if (!IsTailCall)
26312b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka    Chain = DAG.getCALLSEQ_START(Chain, NextStackOffsetVal);
2632e2d529ac1111f153628a9c5c654f4a514e841b47Akira Hatanaka
2633f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  SDValue StackPtr = DAG.getCopyFromReg(Chain, DL,
2634e2d529ac1111f153628a9c5c654f4a514e841b47Akira Hatanaka                                        IsN64 ? Mips::SP_64 : Mips::SP,
2635e2d529ac1111f153628a9c5c654f4a514e841b47Akira Hatanaka                                        getPointerTy());
2636972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
26373d21c2495d481f42bab9f8313b46e7bcf0e2d7acAkira Hatanaka  // With EABI is it possible to have 16 args on registers.
2638bf6a77b98715012c0fa3bdbb3ba55fa7c24c1548Akira Hatanaka  std::deque< std::pair<unsigned, SDValue> > RegsToPass;
26393d21c2495d481f42bab9f8313b46e7bcf0e2d7acAkira Hatanaka  SmallVector<SDValue, 8> MemOpChains;
2640fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  MipsCC::byval_iterator ByValArg = MipsCCInfo.byval_begin();
26413d21c2495d481f42bab9f8313b46e7bcf0e2d7acAkira Hatanaka
2642972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // Walk the register/memloc assignments, inserting copies/loads.
2643972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
2644c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman    SDValue Arg = OutVals[i];
2645972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    CCValAssign &VA = ArgLocs[i];
2646e42f33bd159413e48d75c4c4783e52224c0b5532Akira Hatanaka    MVT ValVT = VA.getValVT(), LocVT = VA.getLocVT();
26476df3e7b1620372cf89b31eb5ff007fc4d1e721cfAkira Hatanaka    ISD::ArgFlagsTy Flags = Outs[i].Flags;
26486df3e7b1620372cf89b31eb5ff007fc4d1e721cfAkira Hatanaka
26496df3e7b1620372cf89b31eb5ff007fc4d1e721cfAkira Hatanaka    // ByVal Arg.
26506df3e7b1620372cf89b31eb5ff007fc4d1e721cfAkira Hatanaka    if (Flags.isByVal()) {
26516df3e7b1620372cf89b31eb5ff007fc4d1e721cfAkira Hatanaka      assert(Flags.getByValSize() &&
26526df3e7b1620372cf89b31eb5ff007fc4d1e721cfAkira Hatanaka             "ByVal args of size 0 should have been ignored by front-end.");
2653fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka      assert(ByValArg != MipsCCInfo.byval_end());
2654f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      assert(!IsTailCall &&
26552f34d754d00fbe2e4a98762d71d0fae5f4b0cf45Akira Hatanaka             "Do not tail-call optimize if there is a byval argument.");
2656f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      passByValArg(Chain, DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg,
2657fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka                   MipsCCInfo, *ByValArg, Flags, Subtarget->isLittle());
2658fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka      ++ByValArg;
26596df3e7b1620372cf89b31eb5ff007fc4d1e721cfAkira Hatanaka      continue;
26606df3e7b1620372cf89b31eb5ff007fc4d1e721cfAkira Hatanaka    }
2661bb481f882093fb738d2bb15610c79364bada5496Jia Liu
2662972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    // Promote the value if needed.
2663972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    switch (VA.getLocInfo()) {
2664c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown loc info!");
2665bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    case CCValAssign::Full:
2666e42f33bd159413e48d75c4c4783e52224c0b5532Akira Hatanaka      if (VA.isRegLoc()) {
2667e42f33bd159413e48d75c4c4783e52224c0b5532Akira Hatanaka        if ((ValVT == MVT::f32 && LocVT == MVT::i32) ||
2668cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka            (ValVT == MVT::f64 && LocVT == MVT::i64) ||
2669cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka            (ValVT == MVT::i64 && LocVT == MVT::f64))
2670f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka          Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg);
2671e42f33bd159413e48d75c4c4783e52224c0b5532Akira Hatanaka        else if (ValVT == MVT::f64 && LocVT == MVT::i32) {
2672f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka          SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
26734552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka                                   Arg, DAG.getConstant(0, MVT::i32));
2674f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka          SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
26750bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka                                   Arg, DAG.getConstant(1, MVT::i32));
267699a2e98eddf00c4afd3817564cb8c914a6f66ae9Akira Hatanaka          if (!Subtarget->isLittle())
267799a2e98eddf00c4afd3817564cb8c914a6f66ae9Akira Hatanaka            std::swap(Lo, Hi);
2678bb481f882093fb738d2bb15610c79364bada5496Jia Liu          unsigned LocRegLo = VA.getLocReg();
2679373e3a4091c85d62eb2ee10dd106ddb4d28be566Akira Hatanaka          unsigned LocRegHigh = getNextIntArgReg(LocRegLo);
2680373e3a4091c85d62eb2ee10dd106ddb4d28be566Akira Hatanaka          RegsToPass.push_back(std::make_pair(LocRegLo, Lo));
2681373e3a4091c85d62eb2ee10dd106ddb4d28be566Akira Hatanaka          RegsToPass.push_back(std::make_pair(LocRegHigh, Hi));
2682b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes          continue;
2683bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck        }
2684b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes      }
2685b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes      break;
2686e0b1215a9299119f064245db1b28bfde55e8950aChris Lattner    case CCValAssign::SExt:
2687f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, LocVT, Arg);
2688e0b1215a9299119f064245db1b28bfde55e8950aChris Lattner      break;
2689e0b1215a9299119f064245db1b28bfde55e8950aChris Lattner    case CCValAssign::ZExt:
2690f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, LocVT, Arg);
2691e0b1215a9299119f064245db1b28bfde55e8950aChris Lattner      break;
2692e0b1215a9299119f064245db1b28bfde55e8950aChris Lattner    case CCValAssign::AExt:
2693f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      Arg = DAG.getNode(ISD::ANY_EXTEND, DL, LocVT, Arg);
2694e0b1215a9299119f064245db1b28bfde55e8950aChris Lattner      break;
2695972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    }
2696bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
2697bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    // Arguments that can be passed on register must be kept at
2698c7db5618f9e5e708b87d9ae6595b3fd510a2a0c0Bruno Cardoso Lopes    // RegsToPass vector
2699972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    if (VA.isRegLoc()) {
2700972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
2701e0b1215a9299119f064245db1b28bfde55e8950aChris Lattner      continue;
2702972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    }
2703bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
2704b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes    // Register can't get to this point...
2705e0b1215a9299119f064245db1b28bfde55e8950aChris Lattner    assert(VA.isMemLoc());
2706bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
2707bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    // emit ISD::STORE whichs stores the
2708e0b1215a9299119f064245db1b28bfde55e8950aChris Lattner    // parameter value to a stack Location
27092f34d754d00fbe2e4a98762d71d0fae5f4b0cf45Akira Hatanaka    MemOpChains.push_back(passArgOnStack(StackPtr, VA.getLocMemOffset(),
2710f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                                         Chain, Arg, DL, IsTailCall, DAG));
2711972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  }
2712972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2713225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // Transform all store nodes into one single node because all store
2714225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // nodes are independent of each other.
2715bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  if (!MemOpChains.empty())
2716f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
2717972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes                        &MemOpChains[0], MemOpChains.size());
2718972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2719056292fd738924f3f7703725d8f630983794b5a5Bill Wendling  // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
2720bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
2721bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // node so that legalize doesn't hack it.
2722e42f33bd159413e48d75c4c4783e52224c0b5532Akira Hatanaka  bool IsPICCall = (IsN64 || IsPIC); // true if calls are translated to jalr $25
2723ed185daba7432e9df717f0199336889784b10da3Akira Hatanaka  bool GlobalOrExternal = false, InternalLinkage = false;
27249777e7afd4a9a348f043e914192d491b620659f1Akira Hatanaka  SDValue CalleeLo;
2725f49fde28772cf73502d31e2755b7c75c0e90a05cAkira Hatanaka
2726f49fde28772cf73502d31e2755b7c75c0e90a05cAkira Hatanaka  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2727d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka    if (IsPICCall) {
2728ed185daba7432e9df717f0199336889784b10da3Akira Hatanaka      InternalLinkage = G->getGlobal()->hasInternalLinkage();
2729ed185daba7432e9df717f0199336889784b10da3Akira Hatanaka
2730ed185daba7432e9df717f0199336889784b10da3Akira Hatanaka      if (InternalLinkage)
2731d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka        Callee = getAddrLocal(Callee, DAG, HasMips64);
2732f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka      else if (LargeGOT)
2733f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka        Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16,
2734f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka                                       MipsII::MO_CALL_LO16);
2735d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka      else
2736d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka        Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_CALL);
2737d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka    } else
2738f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0,
2739d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka                                          MipsII::MO_NO_FLAG);
27400dca9456c55787cd5a5f11b388aa76586b4fcdf6Akira Hatanaka    GlobalOrExternal = true;
2741f49fde28772cf73502d31e2755b7c75c0e90a05cAkira Hatanaka  }
2742f49fde28772cf73502d31e2755b7c75c0e90a05cAkira Hatanaka  else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2743f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka    if (!IsN64 && !IsPIC) // !N64 && static
2744d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka      Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(),
2745d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka                                            MipsII::MO_NO_FLAG);
2746f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka    else if (LargeGOT)
2747f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka      Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16,
2748f09a03776dbbc882c9b15eeccb8ec847058fbfa0Akira Hatanaka                                     MipsII::MO_CALL_LO16);
2749606893294095e214f50937e8f8e9770efaab07a7Akira Hatanaka    else // N64 || PIC
2750d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka      Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_CALL);
2751d43e06de594e734513eb4e24193eb2dd5288c0c4Akira Hatanaka
27520dca9456c55787cd5a5f11b388aa76586b4fcdf6Akira Hatanaka    GlobalOrExternal = true;
2753f49fde28772cf73502d31e2755b7c75c0e90a05cAkira Hatanaka  }
2754f49fde28772cf73502d31e2755b7c75c0e90a05cAkira Hatanaka
2755bf6a77b98715012c0fa3bdbb3ba55fa7c24c1548Akira Hatanaka  SmallVector<SDValue, 8> Ops(1, Chain);
27565ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
2757bf6a77b98715012c0fa3bdbb3ba55fa7c24c1548Akira Hatanaka
27585ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage,
27595ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka              CLI, Callee, Chain);
2760972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2761f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  if (IsTailCall)
2762f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    return DAG.getNode(MipsISD::TailCall, DL, MVT::Other, &Ops[0], Ops.size());
27632b861be96ef18174c201ce6a94c5130445bc5b40Akira Hatanaka
2764f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  Chain  = DAG.getNode(MipsISD::JmpLink, DL, NodeTys, &Ops[0], Ops.size());
27655ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  SDValue InFlag = Chain.getValue(1);
2766972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
27673ed6f876c8c30d82dceccfdd7e3f1774a85adc7cBruno Cardoso Lopes  // Create the CALLSEQ_END node.
2768480eeb54315e35b9d18213c2d56d2166e154b62dAkira Hatanaka  Chain = DAG.getCALLSEQ_END(Chain, NextStackOffsetVal,
27693ed6f876c8c30d82dceccfdd7e3f1774a85adc7cBruno Cardoso Lopes                             DAG.getIntPtrConstant(0, true), InFlag);
27703ed6f876c8c30d82dceccfdd7e3f1774a85adc7cBruno Cardoso Lopes  InFlag = Chain.getValue(1);
27713ed6f876c8c30d82dceccfdd7e3f1774a85adc7cBruno Cardoso Lopes
2772972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // Handle result values, copying them out of physregs into vregs that we
2773972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // return.
2774f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return LowerCallResult(Chain, InFlag, CallConv, IsVarArg,
2775f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                         Ins, DL, DAG, InVals, CLI.Callee.getNode(), CLI.RetTy);
2776972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
2777972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
277898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the
277998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers.
278098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
278198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
2782f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                                    CallingConv::ID CallConv, bool IsVarArg,
278398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                    const SmallVectorImpl<ISD::InputArg> &Ins,
2784f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                                    DebugLoc DL, SelectionDAG &DAG,
27857433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka                                    SmallVectorImpl<SDValue> &InVals,
27867433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka                                    const SDNode *CallNode,
27877433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka                                    const Type *RetTy) const {
2788972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // Assign locations to each value returned by this call.
2789972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  SmallVector<CCValAssign, 16> RVLocs;
2790f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
2791864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka                 getTargetMachine(), RVLocs, *DAG.getContext());
27927433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  MipsCC MipsCCInfo(CallConv, IsO32, CCInfo);
27932ab22d1b9313dea627162309fb434b990d4dd6d6Bruno Cardoso Lopes
27947433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  MipsCCInfo.analyzeCallResult(Ins, getTargetMachine().Options.UseSoftFloat,
27957433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka                               CallNode, RetTy);
2796972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2797972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // Copy all of the result registers out of their specified physreg.
2798972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  for (unsigned i = 0; i != RVLocs.size(); ++i) {
2799f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue Val = DAG.getCopyFromReg(Chain, DL, RVLocs[i].getLocReg(),
28007433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka                                     RVLocs[i].getLocVT(), InFlag);
28017433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    Chain = Val.getValue(1);
28027433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    InFlag = Val.getValue(2);
28037433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka
28047433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    if (RVLocs[i].getValVT() != RVLocs[i].getLocVT())
2805f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      Val = DAG.getNode(ISD::BITCAST, DL, RVLocs[i].getValVT(), Val);
28067433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka
28077433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    InVals.push_back(Val);
2808972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  }
2809c7db5618f9e5e708b87d9ae6595b3fd510a2a0c0Bruno Cardoso Lopes
281098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
2811972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
2812972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
28134552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
281498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman//             Formal Arguments Calling Convention Implementation
28154552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
2816bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck/// LowerFormalArguments - transform physical registers into virtual registers
2817b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes/// and generate load operations for arguments places on the stack.
281898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
281998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMipsTargetLowering::LowerFormalArguments(SDValue Chain,
28200bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka                                         CallingConv::ID CallConv,
2821f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                                         bool IsVarArg,
282282099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka                                      const SmallVectorImpl<ISD::InputArg> &Ins,
2823f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                                         DebugLoc DL, SelectionDAG &DAG,
28240bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka                                         SmallVectorImpl<SDValue> &InVals)
28254552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka                                          const {
2826f7f3b50cd8c10c20f68045c5322f134bd83b06c7Bruno Cardoso Lopes  MachineFunction &MF = DAG.getMachineFunction();
2827972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  MachineFrameInfo *MFI = MF.getFrameInfo();
2828a2b1bb5296624d32a200f9c53d6f26c0c9c3bddcBruno Cardoso Lopes  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
28292ab22d1b9313dea627162309fb434b990d4dd6d6Bruno Cardoso Lopes
28301e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman  MipsFI->setVarArgsFrameIndex(0);
2831972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2832b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes  // Used with vargs to acumulate store chains.
2833b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes  std::vector<SDValue> OutChains;
2834b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes
2835972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // Assign locations to all of the incoming arguments.
2836972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  SmallVector<CCValAssign, 16> ArgLocs;
2837f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
283882099683060abb1f74453d06e78a3729a75ef7eeAkira Hatanaka                 getTargetMachine(), ArgLocs, *DAG.getContext());
2839ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  MipsCC MipsCCInfo(CallConv, IsO32, CCInfo);
28405fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka  Function::const_arg_iterator FuncArg =
28415fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka    DAG.getMachineFunction().getFunction()->arg_begin();
28425fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka  bool UseSoftFloat = getTargetMachine().Options.UseSoftFloat;
28432ab22d1b9313dea627162309fb434b990d4dd6d6Bruno Cardoso Lopes
28445fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka  MipsCCInfo.analyzeFormalArguments(Ins, UseSoftFloat, FuncArg);
2845b33b34a7dc447cf52702b8892c9829344e81f73aAkira Hatanaka  MipsFI->setFormalArgInfo(CCInfo.getNextStackOffset(),
2846b33b34a7dc447cf52702b8892c9829344e81f73aAkira Hatanaka                           MipsCCInfo.hasByValArg());
2847b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes
28484618e0b574bf879d062a39b5867d9c314a4639e0Akira Hatanaka  unsigned CurArgIdx = 0;
2849fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka  MipsCC::byval_iterator ByValArg = MipsCCInfo.byval_begin();
2850225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes
28514618e0b574bf879d062a39b5867d9c314a4639e0Akira Hatanaka  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
2852972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    CCValAssign &VA = ArgLocs[i];
28534618e0b574bf879d062a39b5867d9c314a4639e0Akira Hatanaka    std::advance(FuncArg, Ins[i].OrigArgIndex - CurArgIdx);
28544618e0b574bf879d062a39b5867d9c314a4639e0Akira Hatanaka    CurArgIdx = Ins[i].OrigArgIndex;
2855feaa4c316f125144b6978073885fbd25c8b369aaAkira Hatanaka    EVT ValVT = VA.getValVT();
28563a5257de21216125bddaa0e5f87c00d32e054cd0Akira Hatanaka    ISD::ArgFlagsTy Flags = Ins[i].Flags;
28573a5257de21216125bddaa0e5f87c00d32e054cd0Akira Hatanaka    bool IsRegLoc = VA.isRegLoc();
28583a5257de21216125bddaa0e5f87c00d32e054cd0Akira Hatanaka
28593a5257de21216125bddaa0e5f87c00d32e054cd0Akira Hatanaka    if (Flags.isByVal()) {
28603a5257de21216125bddaa0e5f87c00d32e054cd0Akira Hatanaka      assert(Flags.getByValSize() &&
28613a5257de21216125bddaa0e5f87c00d32e054cd0Akira Hatanaka             "ByVal args of size 0 should have been ignored by front-end.");
2862fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka      assert(ByValArg != MipsCCInfo.byval_end());
2863f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg,
2864fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka                    MipsCCInfo, *ByValArg);
2865fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka      ++ByValArg;
28663a5257de21216125bddaa0e5f87c00d32e054cd0Akira Hatanaka      continue;
28673a5257de21216125bddaa0e5f87c00d32e054cd0Akira Hatanaka    }
2868972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2869972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    // Arguments stored on registers
28703a5257de21216125bddaa0e5f87c00d32e054cd0Akira Hatanaka    if (IsRegLoc) {
2871e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT RegVT = VA.getLocVT();
2872b4d8d31e59b11e7a4d560c01377ce02f1245f056Akira Hatanaka      unsigned ArgReg = VA.getLocReg();
287344d23825d61d530b8d562329ec8fc2d4f843bb8dCraig Topper      const TargetRegisterClass *RC;
2874b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes
2875825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      if (RegVT == MVT::i32)
2876bacbf1c2cb58af7d839027768a7a67e117a6cc5fReed Kotler        RC = Subtarget->inMips16Mode()? &Mips::CPU16RegsRegClass :
2877bacbf1c2cb58af7d839027768a7a67e117a6cc5fReed Kotler                                        &Mips::CPURegsRegClass;
287895934844e3614adf949b09085be21f41ea4218ceAkira Hatanaka      else if (RegVT == MVT::i64)
2879420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        RC = &Mips::CPU64RegsRegClass;
2880bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      else if (RegVT == MVT::f32)
2881420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        RC = &Mips::FGR32RegClass;
288209dd60feef61bc59a71585e05580c142a15bbcf0Akira Hatanaka      else if (RegVT == MVT::f64)
2883420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        RC = HasMips64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
288409dd60feef61bc59a71585e05580c142a15bbcf0Akira Hatanaka      else
2885b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes        llvm_unreachable("RegVT not supported by FormalArguments Lowering");
2886972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2887bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      // Transform the arguments stored on
2888972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      // physical registers into virtual ones
2889f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      unsigned Reg = addLiveIn(DAG.getMachineFunction(), ArgReg, RC);
2890f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT);
2891bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
2892bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      // If this is an 8 or 16-bit value, it has been passed promoted
2893bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      // to 32 bits.  Insert an assert[sz]ext to capture this, then
2894972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      // truncate to the right size.
2895b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes      if (VA.getLocInfo() != CCValAssign::Full) {
2896d4015074e47a6716e7dc0d82296a9d2e55437987Chris Lattner        unsigned Opcode = 0;
2897b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes        if (VA.getLocInfo() == CCValAssign::SExt)
2898b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes          Opcode = ISD::AssertSext;
2899b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes        else if (VA.getLocInfo() == CCValAssign::ZExt)
2900b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes          Opcode = ISD::AssertZext;
2901d4015074e47a6716e7dc0d82296a9d2e55437987Chris Lattner        if (Opcode)
2902f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka          ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue,
2903feaa4c316f125144b6978073885fbd25c8b369aaAkira Hatanaka                                 DAG.getValueType(ValVT));
2904f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka        ArgValue = DAG.getNode(ISD::TRUNCATE, DL, ValVT, ArgValue);
2905b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes      }
2906b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes
29075fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka      // Handle floating point arguments passed in integer registers and
29085fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka      // long double arguments passed in floating point registers.
2909feaa4c316f125144b6978073885fbd25c8b369aaAkira Hatanaka      if ((RegVT == MVT::i32 && ValVT == MVT::f32) ||
29105fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka          (RegVT == MVT::i64 && ValVT == MVT::f64) ||
29115fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka          (RegVT == MVT::f64 && ValVT == MVT::i64))
2912f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka        ArgValue = DAG.getNode(ISD::BITCAST, DL, ValVT, ArgValue);
2913feaa4c316f125144b6978073885fbd25c8b369aaAkira Hatanaka      else if (IsO32 && RegVT == MVT::i32 && ValVT == MVT::f64) {
2914f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka        unsigned Reg2 = addLiveIn(DAG.getMachineFunction(),
2915feaa4c316f125144b6978073885fbd25c8b369aaAkira Hatanaka                                  getNextIntArgReg(ArgReg), RC);
2916f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka        SDValue ArgValue2 = DAG.getCopyFromReg(Chain, DL, Reg2, RegVT);
2917feaa4c316f125144b6978073885fbd25c8b369aaAkira Hatanaka        if (!Subtarget->isLittle())
2918feaa4c316f125144b6978073885fbd25c8b369aaAkira Hatanaka          std::swap(ArgValue, ArgValue2);
2919f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka        ArgValue = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64,
2920feaa4c316f125144b6978073885fbd25c8b369aaAkira Hatanaka                               ArgValue, ArgValue2);
2921b53db4fb321823a8a1f6abc372bdc7c36ef1447fBruno Cardoso Lopes      }
2922972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
292398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman      InVals.push_back(ArgValue);
2924225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes    } else { // VA.isRegLoc()
2925225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes
2926972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      // sanity check
2927972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      assert(VA.isMemLoc());
2928b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes
2929bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      // The stack pointer offset is relative to the caller stack frame.
2930fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka      int FI = MFI->CreateFixedObject(ValVT.getSizeInBits()/8,
2931b4d8d31e59b11e7a4d560c01377ce02f1245f056Akira Hatanaka                                      VA.getLocMemOffset(), true);
2932972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2933972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      // Create load nodes to retrieve arguments from the stack
2934fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka      SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
2935f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      InVals.push_back(DAG.getLoad(ValVT, DL, Chain, FIN,
2936fe30a9be40a6bc22ccfab96915f4a71966f53023Akira Hatanaka                                   MachinePointerInfo::getFixedStack(FI),
2937d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                                   false, false, false, 0));
2938972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    }
2939972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  }
2940225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes
2941225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // The mips ABIs for returning structs by value requires that we copy
2942225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // the sret argument into $v0 for the return. Save the argument into
2943225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // a virtual register so that we can access it from the return points.
2944225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  if (DAG.getMachineFunction().getFunction()->hasStructRetAttr()) {
2945225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes    unsigned Reg = MipsFI->getSRetReturnReg();
2946225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes    if (!Reg) {
294730580cea43ac9108627e0616df6a30518ee7c0efAkira Hatanaka      Reg = MF.getRegInfo().
294830580cea43ac9108627e0616df6a30518ee7c0efAkira Hatanaka        createVirtualRegister(getRegClassFor(IsN64 ? MVT::i64 : MVT::i32));
2949225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes      MipsFI->setSRetReturnReg(Reg);
2950225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes    }
2951f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[0]);
2952f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain);
2953225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  }
2954225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes
2955f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  if (IsVarArg)
2956f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    writeVarArgRegs(OutChains, MipsCCInfo, Chain, DL, DAG);
2957b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes
2958bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // All stores are grouped in one node to allow the matching between
2959b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes  // the size of Ins and InVals. This only happens when on varg functions
2960b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes  if (!OutChains.empty()) {
2961b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes    OutChains.push_back(Chain);
2962f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
2963b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes                        &OutChains[0], OutChains.size());
2964b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes  }
2965b37a742333b9d624f2c42b737352a30fd02fbd98Bruno Cardoso Lopes
296698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
2967972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
2968972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
29694552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
2970972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//               Return Value Calling Convention Implementation
29714552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
2972972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
297397d9f081a92c18bb4fd1c069dccde7c99301150aAkira Hatanakabool
297497d9f081a92c18bb4fd1c069dccde7c99301150aAkira HatanakaMipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
2975f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                                   MachineFunction &MF, bool IsVarArg,
297697d9f081a92c18bb4fd1c069dccde7c99301150aAkira Hatanaka                                   const SmallVectorImpl<ISD::OutputArg> &Outs,
297797d9f081a92c18bb4fd1c069dccde7c99301150aAkira Hatanaka                                   LLVMContext &Context) const {
297897d9f081a92c18bb4fd1c069dccde7c99301150aAkira Hatanaka  SmallVector<CCValAssign, 16> RVLocs;
2979f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  CCState CCInfo(CallConv, IsVarArg, MF, getTargetMachine(),
298097d9f081a92c18bb4fd1c069dccde7c99301150aAkira Hatanaka                 RVLocs, Context);
298197d9f081a92c18bb4fd1c069dccde7c99301150aAkira Hatanaka  return CCInfo.CheckReturn(Outs, RetCC_Mips);
298297d9f081a92c18bb4fd1c069dccde7c99301150aAkira Hatanaka}
298397d9f081a92c18bb4fd1c069dccde7c99301150aAkira Hatanaka
298498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
298598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMipsTargetLowering::LowerReturn(SDValue Chain,
2986f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                                CallingConv::ID CallConv, bool IsVarArg,
298798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                const SmallVectorImpl<ISD::OutputArg> &Outs,
2988c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                const SmallVectorImpl<SDValue> &OutVals,
2989f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka                                DebugLoc DL, SelectionDAG &DAG) const {
2990972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // CCValAssign - represent the assignment of
2991972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // the return value to a location
2992972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  SmallVector<CCValAssign, 16> RVLocs;
29937433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  MachineFunction &MF = DAG.getMachineFunction();
2994972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
2995972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // CCState - Info about the registers and stack slot.
2996f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  CCState CCInfo(CallConv, IsVarArg, MF, getTargetMachine(), RVLocs,
29977433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka                 *DAG.getContext());
29987433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  MipsCC MipsCCInfo(CallConv, IsO32, CCInfo);
2999972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
3000f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  // Analyze return values.
30017433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  MipsCCInfo.analyzeReturn(Outs, getTargetMachine().Options.UseSoftFloat,
30027433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka                           MF.getFunction()->getReturnType());
3003972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
3004475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Flag;
3005d07359667118ab1e889c3b9163b5e6a12414c38bJakob Stoklund Olesen  SmallVector<SDValue, 4> RetOps(1, Chain);
3006972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
3007972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  // Copy the result values into the output registers.
3008972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  for (unsigned i = 0; i != RVLocs.size(); ++i) {
30097433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    SDValue Val = OutVals[i];
3010972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    CCValAssign &VA = RVLocs[i];
3011972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    assert(VA.isRegLoc() && "Can only return in registers!");
3012972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
30137433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    if (RVLocs[i].getValVT() != RVLocs[i].getLocVT())
3014f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka      Val = DAG.getNode(ISD::BITCAST, DL, RVLocs[i].getLocVT(), Val);
30157433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka
3016f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Flag);
3017972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
3018d07359667118ab1e889c3b9163b5e6a12414c38bJakob Stoklund Olesen    // Guarantee that all emitted copies are stuck together with flags.
3019972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    Flag = Chain.getValue(1);
3020d07359667118ab1e889c3b9163b5e6a12414c38bJakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3021972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  }
3022972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
3023225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // The mips ABIs for returning structs by value requires that we copy
3024225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // the sret argument into $v0 for the return. We saved the argument into
3025225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // a virtual register in the entry block, so now we copy the value out
3026225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // and into $v0.
30277433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  if (MF.getFunction()->hasStructRetAttr()) {
3028225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes    MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
3029225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes    unsigned Reg = MipsFI->getSRetReturnReg();
3030225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes
3031bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (!Reg)
3032c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      llvm_unreachable("sret virtual register not created in the entry block");
3033f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy());
30342ef5bd3ba685704bc9c0d03654cb0b7fd1b071e6Akira Hatanaka    unsigned V0 = IsN64 ? Mips::V0_64 : Mips::V0;
3035225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes
3036f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    Chain = DAG.getCopyToReg(Chain, DL, V0, Val, Flag);
3037225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes    Flag = Chain.getValue(1);
3038d07359667118ab1e889c3b9163b5e6a12414c38bJakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(V0, getPointerTy()));
3039225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  }
3040225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes
3041d07359667118ab1e889c3b9163b5e6a12414c38bJakob Stoklund Olesen  RetOps[0] = Chain;  // Update chain.
3042d07359667118ab1e889c3b9163b5e6a12414c38bJakob Stoklund Olesen
3043d07359667118ab1e889c3b9163b5e6a12414c38bJakob Stoklund Olesen  // Add the flag if we have it.
3044ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (Flag.getNode())
3045d07359667118ab1e889c3b9163b5e6a12414c38bJakob Stoklund Olesen    RetOps.push_back(Flag);
3046182ef6fcaacbf44e17a96ea6614cbb5e1af1c3c2Akira Hatanaka
3047d07359667118ab1e889c3b9163b5e6a12414c38bJakob Stoklund Olesen  // Return on Mips is always a "jr $ra"
3048f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka  return DAG.getNode(MipsISD::Ret, DL, MVT::Other, &RetOps[0], RetOps.size());
3049972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
305084f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes
30514552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
305284f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes//                           Mips Inline Assembly Support
30534552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
305484f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes
305584f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes/// getConstraintType - Given a constraint letter, return the type of
305684f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes/// constraint it is for this target.
305784f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso LopesMipsTargetLowering::ConstraintType MipsTargetLowering::
3058bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckgetConstraintType(const std::string &Constraint) const
305984f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes{
3060bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // Mips specific constrainy
3061225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  // GCC config/mips/constraints.md
3062225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  //
3063bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // 'd' : An address register. Equivalent to r
3064bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  //       unless generating MIPS16 code.
3065bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  // 'y' : Equivalent to r; retained for
3066bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  //       backwards compatibility.
30671d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher  // 'c' : A register suitable for use in an indirect
30681d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher  //       jump. This will always be $25 for -mabicalls.
3069af97f73ca03d16ffa069af65a494d0933665ce11Eric Christopher  // 'l' : The lo register. 1 word storage.
3070af97f73ca03d16ffa069af65a494d0933665ce11Eric Christopher  // 'x' : The hilo register pair. Double word storage.
307184f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes  if (Constraint.size() == 1) {
307284f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes    switch (Constraint[0]) {
307384f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes      default : break;
3074bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      case 'd':
3075bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      case 'y':
3076225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes      case 'f':
30771d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher      case 'c':
30784adbefebd2eeeab4d7007b697b4cc20e40ba06b8Eric Christopher      case 'l':
3079af97f73ca03d16ffa069af65a494d0933665ce11Eric Christopher      case 'x':
308084f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes        return C_RegisterClass;
30810b9675d631a33ecde9e11febea48a2c6551bfeecJack Carter      case 'R':
30820b9675d631a33ecde9e11febea48a2c6551bfeecJack Carter        return C_Memory;
308384f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes    }
308484f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes  }
308584f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes  return TargetLowering::getConstraintType(Constraint);
308684f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes}
308784f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes
308844ab89eb376af838d1123293a79975aede501464John Thompson/// Examine constraint type and operand type and determine a weight value.
308944ab89eb376af838d1123293a79975aede501464John Thompson/// This object must already have been set up with the operand type
309044ab89eb376af838d1123293a79975aede501464John Thompson/// and the current alternative constraint selected.
309144ab89eb376af838d1123293a79975aede501464John ThompsonTargetLowering::ConstraintWeight
309244ab89eb376af838d1123293a79975aede501464John ThompsonMipsTargetLowering::getSingleConstraintMatchWeight(
309344ab89eb376af838d1123293a79975aede501464John Thompson    AsmOperandInfo &info, const char *constraint) const {
309444ab89eb376af838d1123293a79975aede501464John Thompson  ConstraintWeight weight = CW_Invalid;
309544ab89eb376af838d1123293a79975aede501464John Thompson  Value *CallOperandVal = info.CallOperandVal;
309644ab89eb376af838d1123293a79975aede501464John Thompson    // If we don't have a value, we can't do a match,
309744ab89eb376af838d1123293a79975aede501464John Thompson    // but allow it at the lowest weight.
309844ab89eb376af838d1123293a79975aede501464John Thompson  if (CallOperandVal == NULL)
309944ab89eb376af838d1123293a79975aede501464John Thompson    return CW_Default;
3100db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *type = CallOperandVal->getType();
310144ab89eb376af838d1123293a79975aede501464John Thompson  // Look at the constraint type.
310244ab89eb376af838d1123293a79975aede501464John Thompson  switch (*constraint) {
310344ab89eb376af838d1123293a79975aede501464John Thompson  default:
310444ab89eb376af838d1123293a79975aede501464John Thompson    weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
310544ab89eb376af838d1123293a79975aede501464John Thompson    break;
3106bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case 'd':
3107bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case 'y':
310844ab89eb376af838d1123293a79975aede501464John Thompson    if (type->isIntegerTy())
310944ab89eb376af838d1123293a79975aede501464John Thompson      weight = CW_Register;
311044ab89eb376af838d1123293a79975aede501464John Thompson    break;
311144ab89eb376af838d1123293a79975aede501464John Thompson  case 'f':
311244ab89eb376af838d1123293a79975aede501464John Thompson    if (type->isFloatTy())
311344ab89eb376af838d1123293a79975aede501464John Thompson      weight = CW_Register;
311444ab89eb376af838d1123293a79975aede501464John Thompson    break;
31151d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher  case 'c': // $25 for indirect jumps
31164adbefebd2eeeab4d7007b697b4cc20e40ba06b8Eric Christopher  case 'l': // lo register
3117af97f73ca03d16ffa069af65a494d0933665ce11Eric Christopher  case 'x': // hilo register pair
31181d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher      if (type->isIntegerTy())
31191d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher      weight = CW_SpecificReg;
31201d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher      break;
312150ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  case 'I': // signed 16 bit immediate
3122e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher  case 'J': // integer zero
3123f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher  case 'K': // unsigned 16 bit immediate
31245ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher  case 'L': // signed 32 bit immediate where lower 16 bits are 0
312560cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher  case 'N': // immediate in the range of -65535 to -1 (inclusive)
31261ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher  case 'O': // signed 15 bit immediate (+- 16383)
312754412a789a35386e11612739dd3b30ab382e5127Eric Christopher  case 'P': // immediate in the range of 65535 to 1 (inclusive)
312850ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher    if (isa<ConstantInt>(CallOperandVal))
312950ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher      weight = CW_Constant;
313050ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher    break;
31310b9675d631a33ecde9e11febea48a2c6551bfeecJack Carter  case 'R':
31320b9675d631a33ecde9e11febea48a2c6551bfeecJack Carter    weight = CW_Memory;
31330b9675d631a33ecde9e11febea48a2c6551bfeecJack Carter    break;
313444ab89eb376af838d1123293a79975aede501464John Thompson  }
313544ab89eb376af838d1123293a79975aede501464John Thompson  return weight;
313644ab89eb376af838d1123293a79975aede501464John Thompson}
313744ab89eb376af838d1123293a79975aede501464John Thompson
313838d642652320ae84bfd948ab1bfc2fd4b8399bbaEric Christopher/// Given a register class constraint, like 'r', if this corresponds directly
313938d642652320ae84bfd948ab1bfc2fd4b8399bbaEric Christopher/// to an LLVM register class, return a register of 0 and the register class
314038d642652320ae84bfd948ab1bfc2fd4b8399bbaEric Christopher/// pointer.
314184f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopesstd::pair<unsigned, const TargetRegisterClass*> MipsTargetLowering::
3142e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersongetRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const
314384f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes{
314484f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes  if (Constraint.size() == 1) {
314584f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes    switch (Constraint[0]) {
3146314aff1474034140a4c5bf3a855963d5259bf90dEric Christopher    case 'd': // Address register. Same as 'r' unless generating MIPS16 code.
3147314aff1474034140a4c5bf3a855963d5259bf90dEric Christopher    case 'y': // Same as 'r'. Exists for compatibility.
314884f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes    case 'r':
3149afc945b614a2bf99014d5820c8849451030ea82bAkira Hatanaka      if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8) {
3150afc945b614a2bf99014d5820c8849451030ea82bAkira Hatanaka        if (Subtarget->inMips16Mode())
3151afc945b614a2bf99014d5820c8849451030ea82bAkira Hatanaka          return std::make_pair(0U, &Mips::CPU16RegsRegClass);
3152420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        return std::make_pair(0U, &Mips::CPURegsRegClass);
3153afc945b614a2bf99014d5820c8849451030ea82bAkira Hatanaka      }
315410de025a67aa37112d5d4cd703925a7c1996422aJack Carter      if (VT == MVT::i64 && !HasMips64)
315510de025a67aa37112d5d4cd703925a7c1996422aJack Carter        return std::make_pair(0U, &Mips::CPURegsRegClass);
31560ed1f764f4e0d4cc940052e8ccca260bf5c39407Eric Christopher      if (VT == MVT::i64 && HasMips64)
31570ed1f764f4e0d4cc940052e8ccca260bf5c39407Eric Christopher        return std::make_pair(0U, &Mips::CPU64RegsRegClass);
31580ed1f764f4e0d4cc940052e8ccca260bf5c39407Eric Christopher      // This will generate an error message
31590ed1f764f4e0d4cc940052e8ccca260bf5c39407Eric Christopher      return std::make_pair(0u, static_cast<const TargetRegisterClass*>(0));
3160225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes    case 'f':
3161825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      if (VT == MVT::f32)
3162420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        return std::make_pair(0U, &Mips::FGR32RegClass);
3163cb9dd72fdc9adc6daed870429cb412bcdb39a6d3Akira Hatanaka      if ((VT == MVT::f64) && (!Subtarget->isSingleFloat())) {
3164cb9dd72fdc9adc6daed870429cb412bcdb39a6d3Akira Hatanaka        if (Subtarget->isFP64bit())
3165420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper          return std::make_pair(0U, &Mips::FGR64RegClass);
3166420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        return std::make_pair(0U, &Mips::AFGR64RegClass);
3167cb9dd72fdc9adc6daed870429cb412bcdb39a6d3Akira Hatanaka      }
31681d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher      break;
31691d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher    case 'c': // register suitable for indirect jump
31701d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher      if (VT == MVT::i32)
31711d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher        return std::make_pair((unsigned)Mips::T9, &Mips::CPURegsRegClass);
31721d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher      assert(VT == MVT::i64 && "Unexpected type.");
31731d5a392e2cff41488e47e038231fb114ea0eb941Eric Christopher      return std::make_pair((unsigned)Mips::T9_64, &Mips::CPU64RegsRegClass);
31744adbefebd2eeeab4d7007b697b4cc20e40ba06b8Eric Christopher    case 'l': // register suitable for indirect jump
31754adbefebd2eeeab4d7007b697b4cc20e40ba06b8Eric Christopher      if (VT == MVT::i32)
31764adbefebd2eeeab4d7007b697b4cc20e40ba06b8Eric Christopher        return std::make_pair((unsigned)Mips::LO, &Mips::HILORegClass);
31774adbefebd2eeeab4d7007b697b4cc20e40ba06b8Eric Christopher      return std::make_pair((unsigned)Mips::LO64, &Mips::HILO64RegClass);
3178af97f73ca03d16ffa069af65a494d0933665ce11Eric Christopher    case 'x': // register suitable for indirect jump
3179af97f73ca03d16ffa069af65a494d0933665ce11Eric Christopher      // Fixme: Not triggering the use of both hi and low
3180af97f73ca03d16ffa069af65a494d0933665ce11Eric Christopher      // This will generate an error message
3181af97f73ca03d16ffa069af65a494d0933665ce11Eric Christopher      return std::make_pair(0u, static_cast<const TargetRegisterClass*>(0));
318284f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes    }
318384f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes  }
318484f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
318584f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes}
318684f47c52fd3c13a781134a8df6cfb918dce0033aBruno Cardoso Lopes
318750ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
318850ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher/// vector.  If it is invalid, don't add anything to Ops.
318950ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christophervoid MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
319050ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher                                                     std::string &Constraint,
319150ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher                                                     std::vector<SDValue>&Ops,
319250ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher                                                     SelectionDAG &DAG) const {
319350ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  SDValue Result(0, 0);
319450ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher
319550ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  // Only support length 1 constraints for now.
319650ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  if (Constraint.length() > 1) return;
319750ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher
319850ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  char ConstraintLetter = Constraint[0];
319950ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  switch (ConstraintLetter) {
320050ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  default: break; // This will fall through to the generic implementation
320150ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  case 'I': // Signed 16 bit constant
320250ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher    // If this fails, the parent routine will give an error
320350ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
320450ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher      EVT Type = Op.getValueType();
320550ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher      int64_t Val = C->getSExtValue();
320650ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher      if (isInt<16>(Val)) {
320750ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher        Result = DAG.getTargetConstant(Val, Type);
320850ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher        break;
320950ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher      }
321050ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher    }
321150ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher    return;
3212e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher  case 'J': // integer zero
3213e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
3214e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher      EVT Type = Op.getValueType();
3215e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher      int64_t Val = C->getZExtValue();
3216e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher      if (Val == 0) {
3217e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher        Result = DAG.getTargetConstant(0, Type);
3218e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher        break;
3219e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher      }
3220e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher    }
3221e5076d484b2f530e2e2422fb06c268970b53b055Eric Christopher    return;
3222f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher  case 'K': // unsigned 16 bit immediate
3223f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
3224f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher      EVT Type = Op.getValueType();
3225f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher      uint64_t Val = (uint64_t)C->getZExtValue();
3226f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher      if (isUInt<16>(Val)) {
3227f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher        Result = DAG.getTargetConstant(Val, Type);
3228f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher        break;
3229f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher      }
3230f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher    }
3231f49f846eec471ca64a72c151dbaa62a9306d4e37Eric Christopher    return;
32325ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher  case 'L': // signed 32 bit immediate where lower 16 bits are 0
32335ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
32345ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher      EVT Type = Op.getValueType();
32355ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher      int64_t Val = C->getSExtValue();
32365ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher      if ((isInt<32>(Val)) && ((Val & 0xffff) == 0)){
32375ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher        Result = DAG.getTargetConstant(Val, Type);
32385ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher        break;
32395ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher      }
32405ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher    }
32415ac47bba83ac1a1b79addc8d5e36e8a468324153Eric Christopher    return;
324260cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher  case 'N': // immediate in the range of -65535 to -1 (inclusive)
324360cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
324460cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher      EVT Type = Op.getValueType();
324560cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher      int64_t Val = C->getSExtValue();
324660cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher      if ((Val >= -65535) && (Val <= -1)) {
324760cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher        Result = DAG.getTargetConstant(Val, Type);
324860cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher        break;
324960cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher      }
325060cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher    }
325160cfc7908ef6acdfab0ea4af5b2c50087a8f36d8Eric Christopher    return;
32521ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher  case 'O': // signed 15 bit immediate
32531ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
32541ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher      EVT Type = Op.getValueType();
32551ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher      int64_t Val = C->getSExtValue();
32561ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher      if ((isInt<15>(Val))) {
32571ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher        Result = DAG.getTargetConstant(Val, Type);
32581ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher        break;
32591ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher      }
32601ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher    }
32611ce2034e43b94abb9930fd86430c46c0bf309ed7Eric Christopher    return;
326254412a789a35386e11612739dd3b30ab382e5127Eric Christopher  case 'P': // immediate in the range of 1 to 65535 (inclusive)
326354412a789a35386e11612739dd3b30ab382e5127Eric Christopher    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
326454412a789a35386e11612739dd3b30ab382e5127Eric Christopher      EVT Type = Op.getValueType();
326554412a789a35386e11612739dd3b30ab382e5127Eric Christopher      int64_t Val = C->getSExtValue();
326654412a789a35386e11612739dd3b30ab382e5127Eric Christopher      if ((Val <= 65535) && (Val >= 1)) {
326754412a789a35386e11612739dd3b30ab382e5127Eric Christopher        Result = DAG.getTargetConstant(Val, Type);
326854412a789a35386e11612739dd3b30ab382e5127Eric Christopher        break;
326954412a789a35386e11612739dd3b30ab382e5127Eric Christopher      }
327054412a789a35386e11612739dd3b30ab382e5127Eric Christopher    }
327154412a789a35386e11612739dd3b30ab382e5127Eric Christopher    return;
327250ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  }
327350ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher
327450ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  if (Result.getNode()) {
327550ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher    Ops.push_back(Result);
327650ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher    return;
327750ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  }
327850ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher
327950ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher  TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
328050ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher}
328150ab03954ec0a43708ad0a5cf3d253ce41a30db3Eric Christopher
32826520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohmanbool
328394e472832f30320d273f5630044c6bbd626e9949Akira HatanakaMipsTargetLowering::isLegalAddressingMode(const AddrMode &AM, Type *Ty) const {
328494e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka  // No global is ever allowed as a base.
328594e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka  if (AM.BaseGV)
328694e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka    return false;
328794e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka
328894e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka  switch (AM.Scale) {
328994e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka  case 0: // "r+i" or just "i", depending on HasBaseReg.
329094e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka    break;
329194e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka  case 1:
329294e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka    if (!AM.HasBaseReg) // allow "r+i".
329394e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka      break;
329494e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka    return false; // disallow "r+r" or "r+r+i".
329594e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka  default:
329694e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka    return false;
329794e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka  }
329894e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka
329994e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka  return true;
330094e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka}
330194e472832f30320d273f5630044c6bbd626e9949Akira Hatanaka
330294e472832f30320d273f5630044c6bbd626e9949Akira Hatanakabool
33036520e20e4fb31f2e65e25c38b372b19d33a83df4Dan GohmanMipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
33046520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman  // The Mips target isn't yet aware of offsets.
33056520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman  return false;
33066520e20e4fb31f2e65e25c38b372b19d33a83df4Dan Gohman}
3307eb2f969a4ddfb0bc8fdcb5bce3b52e53abff321dEvan Cheng
3308e193b325837bee5f9a848a16077a6e156fe88fbaAkira HatanakaEVT MipsTargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
3309946a3a9f22c967d5432eaab5fa464b91343477cdEvan Cheng                                            unsigned SrcAlign,
3310946a3a9f22c967d5432eaab5fa464b91343477cdEvan Cheng                                            bool IsMemset, bool ZeroMemset,
3311e193b325837bee5f9a848a16077a6e156fe88fbaAkira Hatanaka                                            bool MemcpyStrSrc,
3312e193b325837bee5f9a848a16077a6e156fe88fbaAkira Hatanaka                                            MachineFunction &MF) const {
3313e193b325837bee5f9a848a16077a6e156fe88fbaAkira Hatanaka  if (Subtarget->hasMips64())
3314e193b325837bee5f9a848a16077a6e156fe88fbaAkira Hatanaka    return MVT::i64;
3315e193b325837bee5f9a848a16077a6e156fe88fbaAkira Hatanaka
3316e193b325837bee5f9a848a16077a6e156fe88fbaAkira Hatanaka  return MVT::i32;
3317e193b325837bee5f9a848a16077a6e156fe88fbaAkira Hatanaka}
3318e193b325837bee5f9a848a16077a6e156fe88fbaAkira Hatanaka
3319a1eaa3c52b75d4fe2bcd4f7c52e56c405ee91d3cEvan Chengbool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
3320a1eaa3c52b75d4fe2bcd4f7c52e56c405ee91d3cEvan Cheng  if (VT != MVT::f32 && VT != MVT::f64)
3321a1eaa3c52b75d4fe2bcd4f7c52e56c405ee91d3cEvan Cheng    return false;
33226b9028251cfc5ae93431838dfa6db4750e6b67f4Bruno Cardoso Lopes  if (Imm.isNegZero())
33236b9028251cfc5ae93431838dfa6db4750e6b67f4Bruno Cardoso Lopes    return false;
3324eb2f969a4ddfb0bc8fdcb5bce3b52e53abff321dEvan Cheng  return Imm.isZero();
3325eb2f969a4ddfb0bc8fdcb5bce3b52e53abff321dEvan Cheng}
33266c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka
33276c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanakaunsigned MipsTargetLowering::getJumpTableEncoding() const {
33286c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka  if (IsN64)
33296c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka    return MachineJumpTableInfo::EK_GPRel64BlockAddress;
3330bb481f882093fb738d2bb15610c79364bada5496Jia Liu
33316c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka  return TargetLowering::getJumpTableEncoding();
33326c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka}
33337887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
33341e3e869899468de2210f9777905340d907c814c6Akira Hatanaka/// This function returns true if CallSym is a long double emulation routine.
33351e3e869899468de2210f9777905340d907c814c6Akira Hatanakastatic bool isF128SoftLibCall(const char *CallSym) {
33361e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  const char *const LibCalls[] =
33371e3e869899468de2210f9777905340d907c814c6Akira Hatanaka    {"__addtf3", "__divtf3", "__eqtf2", "__extenddftf2", "__extendsftf2",
33381e3e869899468de2210f9777905340d907c814c6Akira Hatanaka     "__fixtfdi", "__fixtfsi", "__fixtfti", "__fixunstfdi", "__fixunstfsi",
33391e3e869899468de2210f9777905340d907c814c6Akira Hatanaka     "__fixunstfti", "__floatditf", "__floatsitf", "__floattitf",
33401e3e869899468de2210f9777905340d907c814c6Akira Hatanaka     "__floatunditf", "__floatunsitf", "__floatuntitf", "__getf2", "__gttf2",
33411e3e869899468de2210f9777905340d907c814c6Akira Hatanaka     "__letf2", "__lttf2", "__multf3", "__netf2", "__powitf2", "__subtf3",
33421e3e869899468de2210f9777905340d907c814c6Akira Hatanaka     "__trunctfdf2", "__trunctfsf2", "__unordtf2",
33431e3e869899468de2210f9777905340d907c814c6Akira Hatanaka     "ceill", "copysignl", "cosl", "exp2l", "expl", "floorl", "fmal", "fmodl",
33441e3e869899468de2210f9777905340d907c814c6Akira Hatanaka     "log10l", "log2l", "logl", "nearbyintl", "powl", "rintl", "sinl", "sqrtl",
33451e3e869899468de2210f9777905340d907c814c6Akira Hatanaka     "truncl"};
33461e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
33471e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  const char * const *End = LibCalls + array_lengthof(LibCalls);
33481e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
33491e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  // Check that LibCalls is sorted alphabetically.
33505ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MipsTargetLowering::LTStr Comp;
33511e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
33525ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka#ifndef NDEBUG
33531e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  for (const char * const *I = LibCalls; I < End - 1; ++I)
33541e3e869899468de2210f9777905340d907c814c6Akira Hatanaka    assert(Comp(*I, *(I + 1)));
33551e3e869899468de2210f9777905340d907c814c6Akira Hatanaka#endif
33561e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
33575ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  return std::binary_search(LibCalls, End, CallSym, Comp);
33581e3e869899468de2210f9777905340d907c814c6Akira Hatanaka}
33591e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
33601e3e869899468de2210f9777905340d907c814c6Akira Hatanaka/// This function returns true if Ty is fp128 or i128 which was originally a
33611e3e869899468de2210f9777905340d907c814c6Akira Hatanaka/// fp128.
33621e3e869899468de2210f9777905340d907c814c6Akira Hatanakastatic bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode) {
33631e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  if (Ty->isFP128Ty())
33641e3e869899468de2210f9777905340d907c814c6Akira Hatanaka    return true;
33651e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
33661e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  const ExternalSymbolSDNode *ES =
33671e3e869899468de2210f9777905340d907c814c6Akira Hatanaka    dyn_cast_or_null<const ExternalSymbolSDNode>(CallNode);
33681e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
33691e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  // If the Ty is i128 and the function being called is a long double emulation
33701e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  // routine, then the original type is f128.
33711e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  return (ES && Ty->isIntegerTy(128) && isF128SoftLibCall(ES->getSymbol()));
33721e3e869899468de2210f9777905340d907c814c6Akira Hatanaka}
33731e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
3374ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira HatanakaMipsTargetLowering::MipsCC::MipsCC(CallingConv::ID CC, bool IsO32_,
3375ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka                                   CCState &Info)
3376ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  : CCInfo(Info), CallConv(CC), IsO32(IsO32_) {
33777887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  // Pre-allocate reserved argument area.
3378ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  CCInfo.AllocateStack(reservedArgArea(), 1);
33797887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka}
33807887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
33817887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanakavoid MipsTargetLowering::MipsCC::
3382ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira HatanakaanalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Args,
3383cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka                    bool IsVarArg, bool IsSoftFloat, const SDNode *CallNode,
3384cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka                    std::vector<ArgListEntry> &FuncArgs) {
3385ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  assert((CallConv != CallingConv::Fast || !IsVarArg) &&
3386ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka         "CallingConv::Fast shouldn't be used for vararg functions.");
3387ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka
33887887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  unsigned NumOpnds = Args.size();
3389ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  llvm::CCAssignFn *FixedFn = fixedArgFn(), *VarFn = varArgFn();
33907887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
33917887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  for (unsigned I = 0; I != NumOpnds; ++I) {
33927887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    MVT ArgVT = Args[I].VT;
33937887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    ISD::ArgFlagsTy ArgFlags = Args[I].Flags;
33947887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    bool R;
33957887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
33967887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    if (ArgFlags.isByVal()) {
33977887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka      handleByValArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags);
33987887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka      continue;
33997887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    }
34007887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
3401ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka    if (IsVarArg && !Args[I].IsFixed)
34027887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka      R = VarFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo);
3403cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka    else {
3404cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka      MVT RegVT = getRegVT(ArgVT, FuncArgs[Args[I].OrigArgIndex].Ty, CallNode,
3405cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka                           IsSoftFloat);
3406cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka      R = FixedFn(I, ArgVT, RegVT, CCValAssign::Full, ArgFlags, CCInfo);
3407cb2eafdfa358ae8a1e1f9ae39d8c72cd4d446da1Akira Hatanaka    }
34087887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
34097887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    if (R) {
34107887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka#ifndef NDEBUG
34117887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka      dbgs() << "Call operand #" << I << " has unhandled type "
34127887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka             << EVT(ArgVT).getEVTString();
34137887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka#endif
34147887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka      llvm_unreachable(0);
34157887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    }
34167887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  }
34177887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka}
34187887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
34197887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanakavoid MipsTargetLowering::MipsCC::
34205fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira HatanakaanalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Args,
34215fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka                       bool IsSoftFloat, Function::const_arg_iterator FuncArg) {
34227887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  unsigned NumArgs = Args.size();
3423ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  llvm::CCAssignFn *FixedFn = fixedArgFn();
34245fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka  unsigned CurArgIdx = 0;
34257887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
34267887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  for (unsigned I = 0; I != NumArgs; ++I) {
34277887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    MVT ArgVT = Args[I].VT;
34287887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    ISD::ArgFlagsTy ArgFlags = Args[I].Flags;
34295fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka    std::advance(FuncArg, Args[I].OrigArgIndex - CurArgIdx);
34305fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka    CurArgIdx = Args[I].OrigArgIndex;
34317887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
34327887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    if (ArgFlags.isByVal()) {
34337887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka      handleByValArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags);
34347887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka      continue;
34357887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    }
34367887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
34375fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka    MVT RegVT = getRegVT(ArgVT, FuncArg->getType(), 0, IsSoftFloat);
34385fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka
34395fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka    if (!FixedFn(I, ArgVT, RegVT, CCValAssign::Full, ArgFlags, CCInfo))
34407887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka      continue;
34417887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
34427887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka#ifndef NDEBUG
34437887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    dbgs() << "Formal Arg #" << I << " has unhandled type "
34447887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka           << EVT(ArgVT).getEVTString();
34457887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka#endif
34467887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    llvm_unreachable(0);
34477887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  }
34487887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka}
34497887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
34507433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanakatemplate<typename Ty>
34517433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanakavoid MipsTargetLowering::MipsCC::
34527433b2e1142a46c1dbb491d91e0175cb9ce83167Akira HatanakaanalyzeReturn(const SmallVectorImpl<Ty> &RetVals, bool IsSoftFloat,
34537433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka              const SDNode *CallNode, const Type *RetTy) const {
34541e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  CCAssignFn *Fn;
34551e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
34561e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  if (IsSoftFloat && originalTypeIsF128(RetTy, CallNode))
34571e3e869899468de2210f9777905340d907c814c6Akira Hatanaka    Fn = RetCC_F128Soft;
34581e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  else
34591e3e869899468de2210f9777905340d907c814c6Akira Hatanaka    Fn = RetCC_Mips;
34601e3e869899468de2210f9777905340d907c814c6Akira Hatanaka
34617433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  for (unsigned I = 0, E = RetVals.size(); I < E; ++I) {
34627433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    MVT VT = RetVals[I].VT;
34637433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    ISD::ArgFlagsTy Flags = RetVals[I].Flags;
34647433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    MVT RegVT = this->getRegVT(VT, RetTy, CallNode, IsSoftFloat);
34657433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka
34661e3e869899468de2210f9777905340d907c814c6Akira Hatanaka    if (Fn(I, VT, RegVT, CCValAssign::Full, Flags, this->CCInfo)) {
34677433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka#ifndef NDEBUG
34687433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka      dbgs() << "Call result #" << I << " has unhandled type "
34697433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka             << EVT(VT).getEVTString() << '\n';
34707433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka#endif
34717433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka      llvm_unreachable(0);
34727433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka    }
34737433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  }
34747433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka}
34757433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka
34767433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanakavoid MipsTargetLowering::MipsCC::
34777433b2e1142a46c1dbb491d91e0175cb9ce83167Akira HatanakaanalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, bool IsSoftFloat,
34787433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka                  const SDNode *CallNode, const Type *RetTy) const {
34797433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  analyzeReturn(Ins, IsSoftFloat, CallNode, RetTy);
34807433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka}
34817433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka
34827433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanakavoid MipsTargetLowering::MipsCC::
34837433b2e1142a46c1dbb491d91e0175cb9ce83167Akira HatanakaanalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, bool IsSoftFloat,
34847433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka              const Type *RetTy) const {
34857433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka  analyzeReturn(Outs, IsSoftFloat, 0, RetTy);
34867433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka}
34877433b2e1142a46c1dbb491d91e0175cb9ce83167Akira Hatanaka
34887887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanakavoid
34897887c90a7b80b994a51a2a3b88eef3643473e67cAkira HatanakaMipsTargetLowering::MipsCC::handleByValArg(unsigned ValNo, MVT ValVT,
34907887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka                                           MVT LocVT,
34917887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka                                           CCValAssign::LocInfo LocInfo,
34927887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka                                           ISD::ArgFlagsTy ArgFlags) {
34937887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  assert(ArgFlags.getByValSize() && "Byval argument's size shouldn't be 0.");
34947887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
34957887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  struct ByValArgInfo ByVal;
3496ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  unsigned RegSize = regSize();
34977887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  unsigned ByValSize = RoundUpToAlignment(ArgFlags.getByValSize(), RegSize);
34987887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  unsigned Align = std::min(std::max(ArgFlags.getByValAlign(), RegSize),
34997887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka                            RegSize * 2);
35007887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
3501ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  if (useRegsForByval())
35027887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    allocateRegs(ByVal, ByValSize, Align);
35037887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
35047887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  // Allocate space on caller's stack.
35057887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  ByVal.Address = CCInfo.AllocateStack(ByValSize - RegSize * ByVal.NumRegs,
35067887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka                                       Align);
35077887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  CCInfo.addLoc(CCValAssign::getMem(ValNo, ValVT, ByVal.Address, LocVT,
35087887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka                                    LocInfo));
35097887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  ByValArgs.push_back(ByVal);
35107887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka}
35117887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
3512ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanakaunsigned MipsTargetLowering::MipsCC::numIntArgRegs() const {
3513ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  return IsO32 ? array_lengthof(O32IntRegs) : array_lengthof(Mips64IntRegs);
3514ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka}
3515ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka
3516ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanakaunsigned MipsTargetLowering::MipsCC::reservedArgArea() const {
3517ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  return (IsO32 && (CallConv != CallingConv::Fast)) ? 16 : 0;
3518ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka}
3519ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka
3520ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanakaconst uint16_t *MipsTargetLowering::MipsCC::intArgRegs() const {
3521ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  return IsO32 ? O32IntRegs : Mips64IntRegs;
3522ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka}
3523ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka
3524ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanakallvm::CCAssignFn *MipsTargetLowering::MipsCC::fixedArgFn() const {
3525ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  if (CallConv == CallingConv::Fast)
3526ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka    return CC_Mips_FastCC;
3527ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka
3528ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  return IsO32 ? CC_MipsO32 : CC_MipsN;
3529ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka}
3530ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka
3531ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanakallvm::CCAssignFn *MipsTargetLowering::MipsCC::varArgFn() const {
3532ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  return IsO32 ? CC_MipsO32 : CC_MipsN_VarArg;
3533ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka}
3534ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka
3535ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanakaconst uint16_t *MipsTargetLowering::MipsCC::shadowRegs() const {
3536ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  return IsO32 ? O32IntRegs : Mips64DPRegs;
3537ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka}
3538ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka
35397887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanakavoid MipsTargetLowering::MipsCC::allocateRegs(ByValArgInfo &ByVal,
35407887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka                                              unsigned ByValSize,
35417887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka                                              unsigned Align) {
3542ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  unsigned RegSize = regSize(), NumIntArgRegs = numIntArgRegs();
3543ffd28a44f04ab2de5a7092fbd5ff17af79f56e28Akira Hatanaka  const uint16_t *IntArgRegs = intArgRegs(), *ShadowRegs = shadowRegs();
35447887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  assert(!(ByValSize % RegSize) && !(Align % RegSize) &&
35457887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka         "Byval argument's size and alignment should be a multiple of"
35467887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka         "RegSize.");
35477887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
35487887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  ByVal.FirstIdx = CCInfo.getFirstUnallocated(IntArgRegs, NumIntArgRegs);
35497887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
35507887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  // If Align > RegSize, the first arg register must be even.
35517887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  if ((Align > RegSize) && (ByVal.FirstIdx % 2)) {
35527887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    CCInfo.AllocateReg(IntArgRegs[ByVal.FirstIdx], ShadowRegs[ByVal.FirstIdx]);
35537887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    ++ByVal.FirstIdx;
35547887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  }
35557887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka
35567887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  // Mark the registers allocated.
35577887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka  for (unsigned I = ByVal.FirstIdx; ByValSize && (I < NumIntArgRegs);
35587887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka       ByValSize -= RegSize, ++I, ++ByVal.NumRegs)
35597887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka    CCInfo.AllocateReg(IntArgRegs[I], ShadowRegs[I]);
35607887c90a7b80b994a51a2a3b88eef3643473e67cAkira Hatanaka}
3561eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka
35625fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira HatanakaMVT MipsTargetLowering::MipsCC::getRegVT(MVT VT, const Type *OrigTy,
35635fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka                                         const SDNode *CallNode,
35645fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka                                         bool IsSoftFloat) const {
35655fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka  if (IsSoftFloat || IsO32)
35665fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka    return VT;
35675fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka
35685fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka  // Check if the original type was fp128.
35691e3e869899468de2210f9777905340d907c814c6Akira Hatanaka  if (originalTypeIsF128(OrigTy, CallNode)) {
35705fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka    assert(VT == MVT::i64);
35715fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka    return MVT::f64;
35725fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka  }
35735fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka
35745fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka  return VT;
35755fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka}
35765fdee6d2b5a72a826bf6db47c319ddac08cd9f57Akira Hatanaka
3577eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanakavoid MipsTargetLowering::
3578eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira HatanakacopyByValRegs(SDValue Chain, DebugLoc DL, std::vector<SDValue> &OutChains,
3579eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka              SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags,
3580eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka              SmallVectorImpl<SDValue> &InVals, const Argument *FuncArg,
3581eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka              const MipsCC &CC, const ByValArgInfo &ByVal) const {
3582eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  MachineFunction &MF = DAG.getMachineFunction();
3583eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  MachineFrameInfo *MFI = MF.getFrameInfo();
3584eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  unsigned RegAreaSize = ByVal.NumRegs * CC.regSize();
3585eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  unsigned FrameObjSize = std::max(Flags.getByValSize(), RegAreaSize);
3586eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  int FrameObjOffset;
3587eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka
3588eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  if (RegAreaSize)
3589eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka    FrameObjOffset = (int)CC.reservedArgArea() -
3590eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka      (int)((CC.numIntArgRegs() - ByVal.FirstIdx) * CC.regSize());
3591eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  else
3592eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka    FrameObjOffset = ByVal.Address;
3593eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka
3594eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  // Create frame object.
3595eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  EVT PtrTy = getPointerTy();
3596eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  int FI = MFI->CreateFixedObject(FrameObjSize, FrameObjOffset, true);
3597eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  SDValue FIN = DAG.getFrameIndex(FI, PtrTy);
3598eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  InVals.push_back(FIN);
3599eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka
3600eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  if (!ByVal.NumRegs)
3601eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka    return;
3602eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka
3603eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  // Copy arg registers.
3604a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund  MVT RegTy = MVT::getIntegerVT(CC.regSize() * 8);
3605eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  const TargetRegisterClass *RC = getRegClassFor(RegTy);
3606eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka
3607eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  for (unsigned I = 0; I < ByVal.NumRegs; ++I) {
3608eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka    unsigned ArgReg = CC.intArgRegs()[ByVal.FirstIdx + I];
3609f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    unsigned VReg = addLiveIn(MF, ArgReg, RC);
3610eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka    unsigned Offset = I * CC.regSize();
3611eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka    SDValue StorePtr = DAG.getNode(ISD::ADD, DL, PtrTy, FIN,
3612eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka                                   DAG.getConstant(Offset, PtrTy));
3613eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka    SDValue Store = DAG.getStore(Chain, DL, DAG.getRegister(VReg, RegTy),
3614eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka                                 StorePtr, MachinePointerInfo(FuncArg, Offset),
3615eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka                                 false, false, 0);
3616eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka    OutChains.push_back(Store);
3617eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka  }
3618eb98ae46bca786f033f8f4ab5f89ac046bd9f28eAkira Hatanaka}
3619db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3620db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka// Copy byVal arg to registers and stack.
3621db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanakavoid MipsTargetLowering::
3622db40edeb11f4f97c8de5428a84346834deaa2a47Akira HatanakapassByValArg(SDValue Chain, DebugLoc DL,
3623bf6a77b98715012c0fa3bdbb3ba55fa7c24c1548Akira Hatanaka             std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
3624db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka             SmallVector<SDValue, 8> &MemOpChains, SDValue StackPtr,
3625db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka             MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg,
3626db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka             const MipsCC &CC, const ByValArgInfo &ByVal,
3627db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka             const ISD::ArgFlagsTy &Flags, bool isLittle) const {
3628db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  unsigned ByValSize = Flags.getByValSize();
3629db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  unsigned Offset = 0; // Offset in # of bytes from the beginning of struct.
3630db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  unsigned RegSize = CC.regSize();
3631db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  unsigned Alignment = std::min(Flags.getByValAlign(), RegSize);
3632db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  EVT PtrTy = getPointerTy(), RegTy = MVT::getIntegerVT(RegSize * 8);
3633db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3634db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  if (ByVal.NumRegs) {
3635db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    const uint16_t *ArgRegs = CC.intArgRegs();
3636db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    bool LeftoverBytes = (ByVal.NumRegs * RegSize > ByValSize);
3637db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    unsigned I = 0;
3638db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3639db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    // Copy words to registers.
3640db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    for (; I < ByVal.NumRegs - LeftoverBytes; ++I, Offset += RegSize) {
3641db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      SDValue LoadPtr = DAG.getNode(ISD::ADD, DL, PtrTy, Arg,
3642db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                                    DAG.getConstant(Offset, PtrTy));
3643db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      SDValue LoadVal = DAG.getLoad(RegTy, DL, Chain, LoadPtr,
3644db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                                    MachinePointerInfo(), false, false, false,
3645db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                                    Alignment);
3646db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      MemOpChains.push_back(LoadVal.getValue(1));
3647db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      unsigned ArgReg = ArgRegs[ByVal.FirstIdx + I];
3648db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      RegsToPass.push_back(std::make_pair(ArgReg, LoadVal));
3649db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    }
3650db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3651db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    // Return if the struct has been fully copied.
3652db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    if (ByValSize == Offset)
3653db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      return;
3654db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3655db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    // Copy the remainder of the byval argument with sub-word loads and shifts.
3656db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    if (LeftoverBytes) {
3657db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      assert((ByValSize > Offset) && (ByValSize < Offset + RegSize) &&
3658db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka             "Size of the remainder should be smaller than RegSize.");
3659db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      SDValue Val;
3660db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3661db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      for (unsigned LoadSize = RegSize / 2, TotalSizeLoaded = 0;
3662db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka           Offset < ByValSize; LoadSize /= 2) {
3663db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        unsigned RemSize = ByValSize - Offset;
3664db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3665db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        if (RemSize < LoadSize)
3666db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka          continue;
3667db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3668db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        // Load subword.
3669db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        SDValue LoadPtr = DAG.getNode(ISD::ADD, DL, PtrTy, Arg,
3670db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                                      DAG.getConstant(Offset, PtrTy));
3671db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        SDValue LoadVal =
3672db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka          DAG.getExtLoad(ISD::ZEXTLOAD, DL, RegTy, Chain, LoadPtr,
3673db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                         MachinePointerInfo(), MVT::getIntegerVT(LoadSize * 8),
3674db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                         false, false, Alignment);
3675db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        MemOpChains.push_back(LoadVal.getValue(1));
3676db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3677db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        // Shift the loaded value.
3678db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        unsigned Shamt;
3679db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3680db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        if (isLittle)
3681db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka          Shamt = TotalSizeLoaded;
3682db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        else
3683db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka          Shamt = (RegSize - (TotalSizeLoaded + LoadSize)) * 8;
3684db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3685db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        SDValue Shift = DAG.getNode(ISD::SHL, DL, RegTy, LoadVal,
3686db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                                    DAG.getConstant(Shamt, MVT::i32));
3687db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3688db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        if (Val.getNode())
3689db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka          Val = DAG.getNode(ISD::OR, DL, RegTy, Val, Shift);
3690db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        else
3691db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka          Val = Shift;
3692db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3693db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        Offset += LoadSize;
3694db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        TotalSizeLoaded += LoadSize;
3695db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka        Alignment = std::min(Alignment, LoadSize);
3696db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      }
3697db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3698db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      unsigned ArgReg = ArgRegs[ByVal.FirstIdx + I];
3699db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      RegsToPass.push_back(std::make_pair(ArgReg, Val));
3700db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka      return;
3701db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka    }
3702db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  }
3703db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka
3704db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  // Copy remainder of byval arg to it with memcpy.
3705db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  unsigned MemCpySize = ByValSize - Offset;
3706db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  SDValue Src = DAG.getNode(ISD::ADD, DL, PtrTy, Arg,
3707db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                            DAG.getConstant(Offset, PtrTy));
3708db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  SDValue Dst = DAG.getNode(ISD::ADD, DL, PtrTy, StackPtr,
3709db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                            DAG.getIntPtrConstant(ByVal.Address));
3710db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  Chain = DAG.getMemcpy(Chain, DL, Dst, Src,
3711db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                        DAG.getConstant(MemCpySize, PtrTy), Alignment,
3712db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                        /*isVolatile=*/false, /*AlwaysInline=*/false,
3713db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka                        MachinePointerInfo(0), MachinePointerInfo(0));
3714db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka  MemOpChains.push_back(Chain);
3715db40edeb11f4f97c8de5428a84346834deaa2a47Akira Hatanaka}
3716f084847373210540f345698295af333834493322Akira Hatanaka
3717f084847373210540f345698295af333834493322Akira Hatanakavoid
3718f084847373210540f345698295af333834493322Akira HatanakaMipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,
3719f084847373210540f345698295af333834493322Akira Hatanaka                                    const MipsCC &CC, SDValue Chain,
3720f084847373210540f345698295af333834493322Akira Hatanaka                                    DebugLoc DL, SelectionDAG &DAG) const {
3721f084847373210540f345698295af333834493322Akira Hatanaka  unsigned NumRegs = CC.numIntArgRegs();
3722f084847373210540f345698295af333834493322Akira Hatanaka  const uint16_t *ArgRegs = CC.intArgRegs();
3723f084847373210540f345698295af333834493322Akira Hatanaka  const CCState &CCInfo = CC.getCCInfo();
3724f084847373210540f345698295af333834493322Akira Hatanaka  unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs, NumRegs);
3725f084847373210540f345698295af333834493322Akira Hatanaka  unsigned RegSize = CC.regSize();
3726a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund  MVT RegTy = MVT::getIntegerVT(RegSize * 8);
3727f084847373210540f345698295af333834493322Akira Hatanaka  const TargetRegisterClass *RC = getRegClassFor(RegTy);
3728f084847373210540f345698295af333834493322Akira Hatanaka  MachineFunction &MF = DAG.getMachineFunction();
3729f084847373210540f345698295af333834493322Akira Hatanaka  MachineFrameInfo *MFI = MF.getFrameInfo();
3730f084847373210540f345698295af333834493322Akira Hatanaka  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
3731f084847373210540f345698295af333834493322Akira Hatanaka
3732f084847373210540f345698295af333834493322Akira Hatanaka  // Offset of the first variable argument from stack pointer.
3733f084847373210540f345698295af333834493322Akira Hatanaka  int VaArgOffset;
3734f084847373210540f345698295af333834493322Akira Hatanaka
3735f084847373210540f345698295af333834493322Akira Hatanaka  if (NumRegs == Idx)
3736f084847373210540f345698295af333834493322Akira Hatanaka    VaArgOffset = RoundUpToAlignment(CCInfo.getNextStackOffset(), RegSize);
3737f084847373210540f345698295af333834493322Akira Hatanaka  else
3738f084847373210540f345698295af333834493322Akira Hatanaka    VaArgOffset =
3739f084847373210540f345698295af333834493322Akira Hatanaka      (int)CC.reservedArgArea() - (int)(RegSize * (NumRegs - Idx));
3740f084847373210540f345698295af333834493322Akira Hatanaka
3741f084847373210540f345698295af333834493322Akira Hatanaka  // Record the frame index of the first variable argument
3742f084847373210540f345698295af333834493322Akira Hatanaka  // which is a value necessary to VASTART.
3743f084847373210540f345698295af333834493322Akira Hatanaka  int FI = MFI->CreateFixedObject(RegSize, VaArgOffset, true);
3744f084847373210540f345698295af333834493322Akira Hatanaka  MipsFI->setVarArgsFrameIndex(FI);
3745f084847373210540f345698295af333834493322Akira Hatanaka
3746f084847373210540f345698295af333834493322Akira Hatanaka  // Copy the integer registers that have not been used for argument passing
3747f084847373210540f345698295af333834493322Akira Hatanaka  // to the argument register save area. For O32, the save area is allocated
3748f084847373210540f345698295af333834493322Akira Hatanaka  // in the caller's stack frame, while for N32/64, it is allocated in the
3749f084847373210540f345698295af333834493322Akira Hatanaka  // callee's stack frame.
3750f084847373210540f345698295af333834493322Akira Hatanaka  for (unsigned I = Idx; I < NumRegs; ++I, VaArgOffset += RegSize) {
3751f635ef401786c84df32090251a8cf45981ecca33Akira Hatanaka    unsigned Reg = addLiveIn(MF, ArgRegs[I], RC);
3752f084847373210540f345698295af333834493322Akira Hatanaka    SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegTy);
3753f084847373210540f345698295af333834493322Akira Hatanaka    FI = MFI->CreateFixedObject(RegSize, VaArgOffset, true);
3754f084847373210540f345698295af333834493322Akira Hatanaka    SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy());
3755f084847373210540f345698295af333834493322Akira Hatanaka    SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
3756f084847373210540f345698295af333834493322Akira Hatanaka                                 MachinePointerInfo(), false, false, 0);
3757f084847373210540f345698295af333834493322Akira Hatanaka    cast<StoreSDNode>(Store.getNode())->getMemOperand()->setValue(0);
3758f084847373210540f345698295af333834493322Akira Hatanaka    OutChains.push_back(Store);
3759f084847373210540f345698295af333834493322Akira Hatanaka  }
3760f084847373210540f345698295af333834493322Akira Hatanaka}
3761