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