1064859bdSKazushi (Jam) Marukawa //===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===// 2064859bdSKazushi (Jam) Marukawa // 3064859bdSKazushi (Jam) Marukawa // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4064859bdSKazushi (Jam) Marukawa // See https://llvm.org/LICENSE.txt for license information. 5064859bdSKazushi (Jam) Marukawa // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6064859bdSKazushi (Jam) Marukawa // 7064859bdSKazushi (Jam) Marukawa //===----------------------------------------------------------------------===// 8064859bdSKazushi (Jam) Marukawa // 9064859bdSKazushi (Jam) Marukawa // This file contains the VE implementation of the TargetInstrInfo class. 10064859bdSKazushi (Jam) Marukawa // 11064859bdSKazushi (Jam) Marukawa //===----------------------------------------------------------------------===// 12064859bdSKazushi (Jam) Marukawa 13064859bdSKazushi (Jam) Marukawa #include "VEInstrInfo.h" 14064859bdSKazushi (Jam) Marukawa #include "VE.h" 15*60431bd7SKazushi (Jam) Marukawa #include "VEMachineFunctionInfo.h" 16064859bdSKazushi (Jam) Marukawa #include "VESubtarget.h" 17064859bdSKazushi (Jam) Marukawa #include "llvm/ADT/STLExtras.h" 18064859bdSKazushi (Jam) Marukawa #include "llvm/ADT/SmallVector.h" 19064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineFrameInfo.h" 20064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineInstrBuilder.h" 21064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineMemOperand.h" 22064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineRegisterInfo.h" 23064859bdSKazushi (Jam) Marukawa #include "llvm/Support/CommandLine.h" 24064859bdSKazushi (Jam) Marukawa #include "llvm/Support/Debug.h" 25064859bdSKazushi (Jam) Marukawa #include "llvm/Support/ErrorHandling.h" 26064859bdSKazushi (Jam) Marukawa #include "llvm/Support/TargetRegistry.h" 27064859bdSKazushi (Jam) Marukawa 28064859bdSKazushi (Jam) Marukawa #define DEBUG_TYPE "ve" 29064859bdSKazushi (Jam) Marukawa 30064859bdSKazushi (Jam) Marukawa using namespace llvm; 31064859bdSKazushi (Jam) Marukawa 32064859bdSKazushi (Jam) Marukawa #define GET_INSTRINFO_CTOR_DTOR 33064859bdSKazushi (Jam) Marukawa #include "VEGenInstrInfo.inc" 34064859bdSKazushi (Jam) Marukawa 35064859bdSKazushi (Jam) Marukawa // Pin the vtable to this file. 36064859bdSKazushi (Jam) Marukawa void VEInstrInfo::anchor() {} 37064859bdSKazushi (Jam) Marukawa 38064859bdSKazushi (Jam) Marukawa VEInstrInfo::VEInstrInfo(VESubtarget &ST) 39064859bdSKazushi (Jam) Marukawa : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(), 40064859bdSKazushi (Jam) Marukawa Subtarget(ST) {} 41064859bdSKazushi (Jam) Marukawa 42fef80a29SKazushi (Jam) Marukawa static bool IsIntegerCC(unsigned CC) { return (CC < VECC::CC_AF); } 43fef80a29SKazushi (Jam) Marukawa 44fef80a29SKazushi (Jam) Marukawa static VECC::CondCodes GetOppositeBranchCondition(VECC::CondCodes CC) { 45fef80a29SKazushi (Jam) Marukawa switch(CC) { 46fef80a29SKazushi (Jam) Marukawa case VECC::CC_IG: return VECC::CC_ILE; 47fef80a29SKazushi (Jam) Marukawa case VECC::CC_IL: return VECC::CC_IGE; 48fef80a29SKazushi (Jam) Marukawa case VECC::CC_INE: return VECC::CC_IEQ; 49fef80a29SKazushi (Jam) Marukawa case VECC::CC_IEQ: return VECC::CC_INE; 50fef80a29SKazushi (Jam) Marukawa case VECC::CC_IGE: return VECC::CC_IL; 51fef80a29SKazushi (Jam) Marukawa case VECC::CC_ILE: return VECC::CC_IG; 52fef80a29SKazushi (Jam) Marukawa case VECC::CC_AF: return VECC::CC_AT; 53fef80a29SKazushi (Jam) Marukawa case VECC::CC_G: return VECC::CC_LENAN; 54fef80a29SKazushi (Jam) Marukawa case VECC::CC_L: return VECC::CC_GENAN; 55fef80a29SKazushi (Jam) Marukawa case VECC::CC_NE: return VECC::CC_EQNAN; 56fef80a29SKazushi (Jam) Marukawa case VECC::CC_EQ: return VECC::CC_NENAN; 57fef80a29SKazushi (Jam) Marukawa case VECC::CC_GE: return VECC::CC_LNAN; 58fef80a29SKazushi (Jam) Marukawa case VECC::CC_LE: return VECC::CC_GNAN; 59fef80a29SKazushi (Jam) Marukawa case VECC::CC_NUM: return VECC::CC_NAN; 60fef80a29SKazushi (Jam) Marukawa case VECC::CC_NAN: return VECC::CC_NUM; 61fef80a29SKazushi (Jam) Marukawa case VECC::CC_GNAN: return VECC::CC_LE; 62fef80a29SKazushi (Jam) Marukawa case VECC::CC_LNAN: return VECC::CC_GE; 63fef80a29SKazushi (Jam) Marukawa case VECC::CC_NENAN: return VECC::CC_EQ; 64fef80a29SKazushi (Jam) Marukawa case VECC::CC_EQNAN: return VECC::CC_NE; 65fef80a29SKazushi (Jam) Marukawa case VECC::CC_GENAN: return VECC::CC_L; 66fef80a29SKazushi (Jam) Marukawa case VECC::CC_LENAN: return VECC::CC_G; 67fef80a29SKazushi (Jam) Marukawa case VECC::CC_AT: return VECC::CC_AF; 68fef80a29SKazushi (Jam) Marukawa } 69fef80a29SKazushi (Jam) Marukawa llvm_unreachable("Invalid cond code"); 70fef80a29SKazushi (Jam) Marukawa } 71fef80a29SKazushi (Jam) Marukawa 72fef80a29SKazushi (Jam) Marukawa // Treat br.l [BCR AT] as unconditional branch 73fef80a29SKazushi (Jam) Marukawa static bool isUncondBranchOpcode(int Opc) { 74fef80a29SKazushi (Jam) Marukawa return Opc == VE::BCRLa || Opc == VE::BCRWa || 75fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRDa || Opc == VE::BCRSa; 76fef80a29SKazushi (Jam) Marukawa } 77fef80a29SKazushi (Jam) Marukawa 78fef80a29SKazushi (Jam) Marukawa static bool isCondBranchOpcode(int Opc) { 79fef80a29SKazushi (Jam) Marukawa return Opc == VE::BCRLrr || Opc == VE::BCRLir || 80fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRLrm0 || Opc == VE::BCRLrm1 || 81fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRLim0 || Opc == VE::BCRLim1 || 82fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRWrr || Opc == VE::BCRWir || 83fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRWrm0 || Opc == VE::BCRWrm1 || 84fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRWim0 || Opc == VE::BCRWim1 || 85fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRDrr || Opc == VE::BCRDir || 86fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRDrm0 || Opc == VE::BCRDrm1 || 87fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRDim0 || Opc == VE::BCRDim1 || 88fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRSrr || Opc == VE::BCRSir || 89fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRSrm0 || Opc == VE::BCRSrm1 || 90fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRSim0 || Opc == VE::BCRSim1; 91fef80a29SKazushi (Jam) Marukawa } 92fef80a29SKazushi (Jam) Marukawa 93fef80a29SKazushi (Jam) Marukawa static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, 94fef80a29SKazushi (Jam) Marukawa SmallVectorImpl<MachineOperand> &Cond) { 95fef80a29SKazushi (Jam) Marukawa Cond.push_back(MachineOperand::CreateImm(LastInst->getOperand(0).getImm())); 96fef80a29SKazushi (Jam) Marukawa Cond.push_back(LastInst->getOperand(1)); 97fef80a29SKazushi (Jam) Marukawa Cond.push_back(LastInst->getOperand(2)); 98fef80a29SKazushi (Jam) Marukawa Target = LastInst->getOperand(3).getMBB(); 99fef80a29SKazushi (Jam) Marukawa } 100fef80a29SKazushi (Jam) Marukawa 10124215fecSSimon Moll bool VEInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 102fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *&FBB, 103fef80a29SKazushi (Jam) Marukawa SmallVectorImpl<MachineOperand> &Cond, 104fef80a29SKazushi (Jam) Marukawa bool AllowModify) const { 105fef80a29SKazushi (Jam) Marukawa MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 106fef80a29SKazushi (Jam) Marukawa if (I == MBB.end()) 107fef80a29SKazushi (Jam) Marukawa return false; 108fef80a29SKazushi (Jam) Marukawa 109fef80a29SKazushi (Jam) Marukawa if (!isUnpredicatedTerminator(*I)) 110fef80a29SKazushi (Jam) Marukawa return false; 111fef80a29SKazushi (Jam) Marukawa 112fef80a29SKazushi (Jam) Marukawa // Get the last instruction in the block. 113fef80a29SKazushi (Jam) Marukawa MachineInstr *LastInst = &*I; 114fef80a29SKazushi (Jam) Marukawa unsigned LastOpc = LastInst->getOpcode(); 115fef80a29SKazushi (Jam) Marukawa 116fef80a29SKazushi (Jam) Marukawa // If there is only one terminator instruction, process it. 117fef80a29SKazushi (Jam) Marukawa if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 118fef80a29SKazushi (Jam) Marukawa if (isUncondBranchOpcode(LastOpc)) { 119fef80a29SKazushi (Jam) Marukawa TBB = LastInst->getOperand(0).getMBB(); 120fef80a29SKazushi (Jam) Marukawa return false; 121fef80a29SKazushi (Jam) Marukawa } 122fef80a29SKazushi (Jam) Marukawa if (isCondBranchOpcode(LastOpc)) { 123fef80a29SKazushi (Jam) Marukawa // Block ends with fall-through condbranch. 124fef80a29SKazushi (Jam) Marukawa parseCondBranch(LastInst, TBB, Cond); 125fef80a29SKazushi (Jam) Marukawa return false; 126fef80a29SKazushi (Jam) Marukawa } 127fef80a29SKazushi (Jam) Marukawa return true; // Can't handle indirect branch. 128fef80a29SKazushi (Jam) Marukawa } 129fef80a29SKazushi (Jam) Marukawa 130fef80a29SKazushi (Jam) Marukawa // Get the instruction before it if it is a terminator. 131fef80a29SKazushi (Jam) Marukawa MachineInstr *SecondLastInst = &*I; 132fef80a29SKazushi (Jam) Marukawa unsigned SecondLastOpc = SecondLastInst->getOpcode(); 133fef80a29SKazushi (Jam) Marukawa 134fef80a29SKazushi (Jam) Marukawa // If AllowModify is true and the block ends with two or more unconditional 135fef80a29SKazushi (Jam) Marukawa // branches, delete all but the first unconditional branch. 136fef80a29SKazushi (Jam) Marukawa if (AllowModify && isUncondBranchOpcode(LastOpc)) { 137fef80a29SKazushi (Jam) Marukawa while (isUncondBranchOpcode(SecondLastOpc)) { 138fef80a29SKazushi (Jam) Marukawa LastInst->eraseFromParent(); 139fef80a29SKazushi (Jam) Marukawa LastInst = SecondLastInst; 140fef80a29SKazushi (Jam) Marukawa LastOpc = LastInst->getOpcode(); 141fef80a29SKazushi (Jam) Marukawa if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 142fef80a29SKazushi (Jam) Marukawa // Return now the only terminator is an unconditional branch. 143fef80a29SKazushi (Jam) Marukawa TBB = LastInst->getOperand(0).getMBB(); 144fef80a29SKazushi (Jam) Marukawa return false; 145fef80a29SKazushi (Jam) Marukawa } 146fef80a29SKazushi (Jam) Marukawa SecondLastInst = &*I; 147fef80a29SKazushi (Jam) Marukawa SecondLastOpc = SecondLastInst->getOpcode(); 148fef80a29SKazushi (Jam) Marukawa } 149fef80a29SKazushi (Jam) Marukawa } 150fef80a29SKazushi (Jam) Marukawa 151fef80a29SKazushi (Jam) Marukawa // If there are three terminators, we don't know what sort of block this is. 152fef80a29SKazushi (Jam) Marukawa if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) 153fef80a29SKazushi (Jam) Marukawa return true; 154fef80a29SKazushi (Jam) Marukawa 155fef80a29SKazushi (Jam) Marukawa // If the block ends with a B and a Bcc, handle it. 156fef80a29SKazushi (Jam) Marukawa if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 157fef80a29SKazushi (Jam) Marukawa parseCondBranch(SecondLastInst, TBB, Cond); 158fef80a29SKazushi (Jam) Marukawa FBB = LastInst->getOperand(0).getMBB(); 159fef80a29SKazushi (Jam) Marukawa return false; 160fef80a29SKazushi (Jam) Marukawa } 161fef80a29SKazushi (Jam) Marukawa 162fef80a29SKazushi (Jam) Marukawa // If the block ends with two unconditional branches, handle it. The second 163fef80a29SKazushi (Jam) Marukawa // one is not executed. 164fef80a29SKazushi (Jam) Marukawa if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 165fef80a29SKazushi (Jam) Marukawa TBB = SecondLastInst->getOperand(0).getMBB(); 166fef80a29SKazushi (Jam) Marukawa return false; 167fef80a29SKazushi (Jam) Marukawa } 168fef80a29SKazushi (Jam) Marukawa 169fef80a29SKazushi (Jam) Marukawa // TODO ...likewise if it ends with an indirect branch followed by an unconditional 170fef80a29SKazushi (Jam) Marukawa // branch. 171fef80a29SKazushi (Jam) Marukawa // if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 172fef80a29SKazushi (Jam) Marukawa // I = LastInst; 173fef80a29SKazushi (Jam) Marukawa // if (AllowModify) 174fef80a29SKazushi (Jam) Marukawa // I->eraseFromParent(); 175fef80a29SKazushi (Jam) Marukawa // return true; 176fef80a29SKazushi (Jam) Marukawa // } 177fef80a29SKazushi (Jam) Marukawa 178fef80a29SKazushi (Jam) Marukawa // Otherwise, can't handle this. 179fef80a29SKazushi (Jam) Marukawa return true; 180fef80a29SKazushi (Jam) Marukawa } 181fef80a29SKazushi (Jam) Marukawa 182fef80a29SKazushi (Jam) Marukawa unsigned VEInstrInfo::insertBranch(MachineBasicBlock &MBB, 183fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *TBB, 184fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *FBB, 185fef80a29SKazushi (Jam) Marukawa ArrayRef<MachineOperand> Cond, 18624215fecSSimon Moll const DebugLoc &DL, int *BytesAdded) const { 187fef80a29SKazushi (Jam) Marukawa assert(TBB && "insertBranch must not be told to insert a fallthrough"); 188fef80a29SKazushi (Jam) Marukawa assert((Cond.size() == 3 || Cond.size() == 0) && 189fef80a29SKazushi (Jam) Marukawa "VE branch conditions should have three component!"); 190fef80a29SKazushi (Jam) Marukawa assert(!BytesAdded && "code size not handled"); 191fef80a29SKazushi (Jam) Marukawa if (Cond.empty()) { 192fef80a29SKazushi (Jam) Marukawa // Uncondition branch 193fef80a29SKazushi (Jam) Marukawa assert(!FBB && "Unconditional branch with multiple successors!"); 194fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(VE::BCRLa)) 195fef80a29SKazushi (Jam) Marukawa .addMBB(TBB); 196fef80a29SKazushi (Jam) Marukawa return 1; 197fef80a29SKazushi (Jam) Marukawa } 198fef80a29SKazushi (Jam) Marukawa 199fef80a29SKazushi (Jam) Marukawa // Conditional branch 200fef80a29SKazushi (Jam) Marukawa // (BCRir CC sy sz addr) 201fef80a29SKazushi (Jam) Marukawa assert(Cond[0].isImm() && Cond[2].isReg() && "not implemented"); 202fef80a29SKazushi (Jam) Marukawa 203fef80a29SKazushi (Jam) Marukawa unsigned opc[2]; 204fef80a29SKazushi (Jam) Marukawa const TargetRegisterInfo *TRI = &getRegisterInfo(); 205fef80a29SKazushi (Jam) Marukawa MachineFunction *MF = MBB.getParent(); 206fef80a29SKazushi (Jam) Marukawa const MachineRegisterInfo &MRI = MF->getRegInfo(); 207fef80a29SKazushi (Jam) Marukawa unsigned Reg = Cond[2].getReg(); 208fef80a29SKazushi (Jam) Marukawa if (IsIntegerCC(Cond[0].getImm())) { 209fef80a29SKazushi (Jam) Marukawa if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 210fef80a29SKazushi (Jam) Marukawa opc[0] = VE::BCRWir; 211fef80a29SKazushi (Jam) Marukawa opc[1] = VE::BCRWrr; 212fef80a29SKazushi (Jam) Marukawa } else { 213fef80a29SKazushi (Jam) Marukawa opc[0] = VE::BCRLir; 214fef80a29SKazushi (Jam) Marukawa opc[1] = VE::BCRLrr; 215fef80a29SKazushi (Jam) Marukawa } 216fef80a29SKazushi (Jam) Marukawa } else { 217fef80a29SKazushi (Jam) Marukawa if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 218fef80a29SKazushi (Jam) Marukawa opc[0] = VE::BCRSir; 219fef80a29SKazushi (Jam) Marukawa opc[1] = VE::BCRSrr; 220fef80a29SKazushi (Jam) Marukawa } else { 221fef80a29SKazushi (Jam) Marukawa opc[0] = VE::BCRDir; 222fef80a29SKazushi (Jam) Marukawa opc[1] = VE::BCRDrr; 223fef80a29SKazushi (Jam) Marukawa } 224fef80a29SKazushi (Jam) Marukawa } 225fef80a29SKazushi (Jam) Marukawa if (Cond[1].isImm()) { 226fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(opc[0])) 227fef80a29SKazushi (Jam) Marukawa .add(Cond[0]) // condition code 228fef80a29SKazushi (Jam) Marukawa .add(Cond[1]) // lhs 229fef80a29SKazushi (Jam) Marukawa .add(Cond[2]) // rhs 230fef80a29SKazushi (Jam) Marukawa .addMBB(TBB); 231fef80a29SKazushi (Jam) Marukawa } else { 232fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(opc[1])) 233fef80a29SKazushi (Jam) Marukawa .add(Cond[0]) 234fef80a29SKazushi (Jam) Marukawa .add(Cond[1]) 235fef80a29SKazushi (Jam) Marukawa .add(Cond[2]) 236fef80a29SKazushi (Jam) Marukawa .addMBB(TBB); 237fef80a29SKazushi (Jam) Marukawa } 238fef80a29SKazushi (Jam) Marukawa 239fef80a29SKazushi (Jam) Marukawa if (!FBB) 240fef80a29SKazushi (Jam) Marukawa return 1; 241fef80a29SKazushi (Jam) Marukawa 242fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(VE::BCRLa)) 243fef80a29SKazushi (Jam) Marukawa .addMBB(FBB); 244fef80a29SKazushi (Jam) Marukawa return 2; 245fef80a29SKazushi (Jam) Marukawa } 246fef80a29SKazushi (Jam) Marukawa 247fef80a29SKazushi (Jam) Marukawa unsigned VEInstrInfo::removeBranch(MachineBasicBlock &MBB, 248fef80a29SKazushi (Jam) Marukawa int *BytesRemoved) const { 249fef80a29SKazushi (Jam) Marukawa assert(!BytesRemoved && "code size not handled"); 250fef80a29SKazushi (Jam) Marukawa 251fef80a29SKazushi (Jam) Marukawa MachineBasicBlock::iterator I = MBB.end(); 252fef80a29SKazushi (Jam) Marukawa unsigned Count = 0; 253fef80a29SKazushi (Jam) Marukawa while (I != MBB.begin()) { 254fef80a29SKazushi (Jam) Marukawa --I; 255fef80a29SKazushi (Jam) Marukawa 256fef80a29SKazushi (Jam) Marukawa if (I->isDebugValue()) 257fef80a29SKazushi (Jam) Marukawa continue; 258fef80a29SKazushi (Jam) Marukawa 259fef80a29SKazushi (Jam) Marukawa if (!isUncondBranchOpcode(I->getOpcode()) && 260fef80a29SKazushi (Jam) Marukawa !isCondBranchOpcode(I->getOpcode())) 261fef80a29SKazushi (Jam) Marukawa break; // Not a branch 262fef80a29SKazushi (Jam) Marukawa 263fef80a29SKazushi (Jam) Marukawa I->eraseFromParent(); 264fef80a29SKazushi (Jam) Marukawa I = MBB.end(); 265fef80a29SKazushi (Jam) Marukawa ++Count; 266fef80a29SKazushi (Jam) Marukawa } 267fef80a29SKazushi (Jam) Marukawa return Count; 268fef80a29SKazushi (Jam) Marukawa } 269fef80a29SKazushi (Jam) Marukawa 270fef80a29SKazushi (Jam) Marukawa bool VEInstrInfo::reverseBranchCondition( 271fef80a29SKazushi (Jam) Marukawa SmallVectorImpl<MachineOperand> &Cond) const { 272fef80a29SKazushi (Jam) Marukawa VECC::CondCodes CC = static_cast<VECC::CondCodes>(Cond[0].getImm()); 273fef80a29SKazushi (Jam) Marukawa Cond[0].setImm(GetOppositeBranchCondition(CC)); 274fef80a29SKazushi (Jam) Marukawa return false; 275fef80a29SKazushi (Jam) Marukawa } 276fef80a29SKazushi (Jam) Marukawa 2773a906a9fSKazushi (Jam) Marukawa static bool IsAliasOfSX(Register Reg) { 2783a906a9fSKazushi (Jam) Marukawa return VE::I8RegClass.contains(Reg) || VE::I16RegClass.contains(Reg) || 2793a906a9fSKazushi (Jam) Marukawa VE::I32RegClass.contains(Reg) || VE::I64RegClass.contains(Reg) || 2803a906a9fSKazushi (Jam) Marukawa VE::F32RegClass.contains(Reg); 2813a906a9fSKazushi (Jam) Marukawa } 2823a906a9fSKazushi (Jam) Marukawa 283773ae62fSKazushi (Jam) Marukawa void VEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 284773ae62fSKazushi (Jam) Marukawa MachineBasicBlock::iterator I, const DebugLoc &DL, 285773ae62fSKazushi (Jam) Marukawa MCRegister DestReg, MCRegister SrcReg, 286773ae62fSKazushi (Jam) Marukawa bool KillSrc) const { 287773ae62fSKazushi (Jam) Marukawa 2883a906a9fSKazushi (Jam) Marukawa if (IsAliasOfSX(SrcReg) && IsAliasOfSX(DestReg)) { 289773ae62fSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::ORri), DestReg) 290773ae62fSKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(KillSrc)) 291773ae62fSKazushi (Jam) Marukawa .addImm(0); 292773ae62fSKazushi (Jam) Marukawa } else { 293773ae62fSKazushi (Jam) Marukawa const TargetRegisterInfo *TRI = &getRegisterInfo(); 294773ae62fSKazushi (Jam) Marukawa dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg, TRI) 295773ae62fSKazushi (Jam) Marukawa << " to " << printReg(DestReg, TRI) << "\n"; 296773ae62fSKazushi (Jam) Marukawa llvm_unreachable("Impossible reg-to-reg copy"); 297773ae62fSKazushi (Jam) Marukawa } 298773ae62fSKazushi (Jam) Marukawa } 299773ae62fSKazushi (Jam) Marukawa 30007c9f757SKazushi (Jam) Marukawa /// isLoadFromStackSlot - If the specified machine instruction is a direct 30107c9f757SKazushi (Jam) Marukawa /// load from a stack slot, return the virtual or physical register number of 30207c9f757SKazushi (Jam) Marukawa /// the destination along with the FrameIndex of the loaded stack slot. If 30307c9f757SKazushi (Jam) Marukawa /// not, return 0. This predicate must return 0 if the instruction has 30407c9f757SKazushi (Jam) Marukawa /// any side effects other than loading from the stack slot. 30507c9f757SKazushi (Jam) Marukawa unsigned VEInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 30607c9f757SKazushi (Jam) Marukawa int &FrameIndex) const { 30707c9f757SKazushi (Jam) Marukawa if (MI.getOpcode() == VE::LDSri || MI.getOpcode() == VE::LDLri || 30807c9f757SKazushi (Jam) Marukawa MI.getOpcode() == VE::LDUri) { 30907c9f757SKazushi (Jam) Marukawa if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 31007c9f757SKazushi (Jam) Marukawa MI.getOperand(2).getImm() == 0) { 31107c9f757SKazushi (Jam) Marukawa FrameIndex = MI.getOperand(1).getIndex(); 31207c9f757SKazushi (Jam) Marukawa return MI.getOperand(0).getReg(); 31307c9f757SKazushi (Jam) Marukawa } 31407c9f757SKazushi (Jam) Marukawa } 31507c9f757SKazushi (Jam) Marukawa return 0; 31607c9f757SKazushi (Jam) Marukawa } 31707c9f757SKazushi (Jam) Marukawa 31807c9f757SKazushi (Jam) Marukawa /// isStoreToStackSlot - If the specified machine instruction is a direct 31907c9f757SKazushi (Jam) Marukawa /// store to a stack slot, return the virtual or physical register number of 32007c9f757SKazushi (Jam) Marukawa /// the source reg along with the FrameIndex of the loaded stack slot. If 32107c9f757SKazushi (Jam) Marukawa /// not, return 0. This predicate must return 0 if the instruction has 32207c9f757SKazushi (Jam) Marukawa /// any side effects other than storing to the stack slot. 32307c9f757SKazushi (Jam) Marukawa unsigned VEInstrInfo::isStoreToStackSlot(const MachineInstr &MI, 32407c9f757SKazushi (Jam) Marukawa int &FrameIndex) const { 32507c9f757SKazushi (Jam) Marukawa if (MI.getOpcode() == VE::STSri || MI.getOpcode() == VE::STLri || 32607c9f757SKazushi (Jam) Marukawa MI.getOpcode() == VE::STUri) { 32707c9f757SKazushi (Jam) Marukawa if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() && 32807c9f757SKazushi (Jam) Marukawa MI.getOperand(1).getImm() == 0) { 32907c9f757SKazushi (Jam) Marukawa FrameIndex = MI.getOperand(0).getIndex(); 33007c9f757SKazushi (Jam) Marukawa return MI.getOperand(2).getReg(); 33107c9f757SKazushi (Jam) Marukawa } 33207c9f757SKazushi (Jam) Marukawa } 33307c9f757SKazushi (Jam) Marukawa return 0; 33407c9f757SKazushi (Jam) Marukawa } 33507c9f757SKazushi (Jam) Marukawa 33607c9f757SKazushi (Jam) Marukawa void VEInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 33707c9f757SKazushi (Jam) Marukawa MachineBasicBlock::iterator I, 33807c9f757SKazushi (Jam) Marukawa Register SrcReg, bool isKill, int FI, 33907c9f757SKazushi (Jam) Marukawa const TargetRegisterClass *RC, 34007c9f757SKazushi (Jam) Marukawa const TargetRegisterInfo *TRI) const { 34107c9f757SKazushi (Jam) Marukawa DebugLoc DL; 34207c9f757SKazushi (Jam) Marukawa if (I != MBB.end()) 34307c9f757SKazushi (Jam) Marukawa DL = I->getDebugLoc(); 34407c9f757SKazushi (Jam) Marukawa 34507c9f757SKazushi (Jam) Marukawa MachineFunction *MF = MBB.getParent(); 34607c9f757SKazushi (Jam) Marukawa const MachineFrameInfo &MFI = MF->getFrameInfo(); 34707c9f757SKazushi (Jam) Marukawa MachineMemOperand *MMO = MF->getMachineMemOperand( 34807c9f757SKazushi (Jam) Marukawa MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, 34907c9f757SKazushi (Jam) Marukawa MFI.getObjectSize(FI), MFI.getObjectAlignment(FI)); 35007c9f757SKazushi (Jam) Marukawa 35107c9f757SKazushi (Jam) Marukawa // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 35207c9f757SKazushi (Jam) Marukawa if (RC == &VE::I64RegClass) { 35307c9f757SKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::STSri)) 35407c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 35507c9f757SKazushi (Jam) Marukawa .addImm(0) 35607c9f757SKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(isKill)) 35707c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 35807c9f757SKazushi (Jam) Marukawa } else if (RC == &VE::I32RegClass) { 35907c9f757SKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::STLri)) 36007c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 36107c9f757SKazushi (Jam) Marukawa .addImm(0) 36207c9f757SKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(isKill)) 36307c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 36407c9f757SKazushi (Jam) Marukawa } else if (RC == &VE::F32RegClass) { 36507c9f757SKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::STUri)) 36607c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 36707c9f757SKazushi (Jam) Marukawa .addImm(0) 36807c9f757SKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(isKill)) 36907c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 37007c9f757SKazushi (Jam) Marukawa } else 37107c9f757SKazushi (Jam) Marukawa report_fatal_error("Can't store this register to stack slot"); 37207c9f757SKazushi (Jam) Marukawa } 37307c9f757SKazushi (Jam) Marukawa 37407c9f757SKazushi (Jam) Marukawa void VEInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 37507c9f757SKazushi (Jam) Marukawa MachineBasicBlock::iterator I, 37607c9f757SKazushi (Jam) Marukawa Register DestReg, int FI, 37707c9f757SKazushi (Jam) Marukawa const TargetRegisterClass *RC, 37807c9f757SKazushi (Jam) Marukawa const TargetRegisterInfo *TRI) const { 37907c9f757SKazushi (Jam) Marukawa DebugLoc DL; 38007c9f757SKazushi (Jam) Marukawa if (I != MBB.end()) 38107c9f757SKazushi (Jam) Marukawa DL = I->getDebugLoc(); 38207c9f757SKazushi (Jam) Marukawa 38307c9f757SKazushi (Jam) Marukawa MachineFunction *MF = MBB.getParent(); 38407c9f757SKazushi (Jam) Marukawa const MachineFrameInfo &MFI = MF->getFrameInfo(); 38507c9f757SKazushi (Jam) Marukawa MachineMemOperand *MMO = MF->getMachineMemOperand( 38607c9f757SKazushi (Jam) Marukawa MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, 38707c9f757SKazushi (Jam) Marukawa MFI.getObjectSize(FI), MFI.getObjectAlignment(FI)); 38807c9f757SKazushi (Jam) Marukawa 38907c9f757SKazushi (Jam) Marukawa if (RC == &VE::I64RegClass) { 39007c9f757SKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::LDSri), DestReg) 39107c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 39207c9f757SKazushi (Jam) Marukawa .addImm(0) 39307c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 39407c9f757SKazushi (Jam) Marukawa } else if (RC == &VE::I32RegClass) { 39507c9f757SKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::LDLri), DestReg) 39607c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 39707c9f757SKazushi (Jam) Marukawa .addImm(0) 39807c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 39907c9f757SKazushi (Jam) Marukawa } else if (RC == &VE::F32RegClass) { 40007c9f757SKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::LDUri), DestReg) 40107c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 40207c9f757SKazushi (Jam) Marukawa .addImm(0) 40307c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 40407c9f757SKazushi (Jam) Marukawa } else 40507c9f757SKazushi (Jam) Marukawa report_fatal_error("Can't load this register from stack slot"); 40607c9f757SKazushi (Jam) Marukawa } 40707c9f757SKazushi (Jam) Marukawa 408*60431bd7SKazushi (Jam) Marukawa Register VEInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 409*60431bd7SKazushi (Jam) Marukawa VEMachineFunctionInfo *VEFI = MF->getInfo<VEMachineFunctionInfo>(); 410*60431bd7SKazushi (Jam) Marukawa Register GlobalBaseReg = VEFI->getGlobalBaseReg(); 411*60431bd7SKazushi (Jam) Marukawa if (GlobalBaseReg != 0) 412*60431bd7SKazushi (Jam) Marukawa return GlobalBaseReg; 413*60431bd7SKazushi (Jam) Marukawa 414*60431bd7SKazushi (Jam) Marukawa // We use %s15 (%got) as a global base register 415*60431bd7SKazushi (Jam) Marukawa GlobalBaseReg = VE::SX15; 416*60431bd7SKazushi (Jam) Marukawa 417*60431bd7SKazushi (Jam) Marukawa // Insert a pseudo instruction to set the GlobalBaseReg into the first 418*60431bd7SKazushi (Jam) Marukawa // MBB of the function 419*60431bd7SKazushi (Jam) Marukawa MachineBasicBlock &FirstMBB = MF->front(); 420*60431bd7SKazushi (Jam) Marukawa MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 421*60431bd7SKazushi (Jam) Marukawa DebugLoc dl; 422*60431bd7SKazushi (Jam) Marukawa BuildMI(FirstMBB, MBBI, dl, get(VE::GETGOT), GlobalBaseReg); 423*60431bd7SKazushi (Jam) Marukawa VEFI->setGlobalBaseReg(GlobalBaseReg); 424*60431bd7SKazushi (Jam) Marukawa return GlobalBaseReg; 425*60431bd7SKazushi (Jam) Marukawa } 426*60431bd7SKazushi (Jam) Marukawa 427064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 428064859bdSKazushi (Jam) Marukawa switch (MI.getOpcode()) { 429064859bdSKazushi (Jam) Marukawa case VE::EXTEND_STACK: { 430064859bdSKazushi (Jam) Marukawa return expandExtendStackPseudo(MI); 431064859bdSKazushi (Jam) Marukawa } 432064859bdSKazushi (Jam) Marukawa case VE::EXTEND_STACK_GUARD: { 433064859bdSKazushi (Jam) Marukawa MI.eraseFromParent(); // The pseudo instruction is gone now. 434064859bdSKazushi (Jam) Marukawa return true; 435064859bdSKazushi (Jam) Marukawa } 436064859bdSKazushi (Jam) Marukawa } 437064859bdSKazushi (Jam) Marukawa return false; 438064859bdSKazushi (Jam) Marukawa } 439064859bdSKazushi (Jam) Marukawa 440064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { 441064859bdSKazushi (Jam) Marukawa MachineBasicBlock &MBB = *MI.getParent(); 442064859bdSKazushi (Jam) Marukawa MachineFunction &MF = *MBB.getParent(); 443064859bdSKazushi (Jam) Marukawa const VEInstrInfo &TII = 444064859bdSKazushi (Jam) Marukawa *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 445064859bdSKazushi (Jam) Marukawa DebugLoc dl = MBB.findDebugLoc(MI); 446064859bdSKazushi (Jam) Marukawa 447064859bdSKazushi (Jam) Marukawa // Create following instructions and multiple basic blocks. 448064859bdSKazushi (Jam) Marukawa // 449064859bdSKazushi (Jam) Marukawa // thisBB: 450064859bdSKazushi (Jam) Marukawa // brge.l.t %sp, %sl, sinkBB 451064859bdSKazushi (Jam) Marukawa // syscallBB: 452064859bdSKazushi (Jam) Marukawa // ld %s61, 0x18(, %tp) // load param area 453064859bdSKazushi (Jam) Marukawa // or %s62, 0, %s0 // spill the value of %s0 454064859bdSKazushi (Jam) Marukawa // lea %s63, 0x13b // syscall # of grow 455064859bdSKazushi (Jam) Marukawa // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 456064859bdSKazushi (Jam) Marukawa // shm.l %sl, 0x8(%s61) // store old limit at addr:8 457064859bdSKazushi (Jam) Marukawa // shm.l %sp, 0x10(%s61) // store new limit at addr:16 458064859bdSKazushi (Jam) Marukawa // monc // call monitor 459064859bdSKazushi (Jam) Marukawa // or %s0, 0, %s62 // restore the value of %s0 460064859bdSKazushi (Jam) Marukawa // sinkBB: 461064859bdSKazushi (Jam) Marukawa 462064859bdSKazushi (Jam) Marukawa // Create new MBB 463064859bdSKazushi (Jam) Marukawa MachineBasicBlock *BB = &MBB; 464064859bdSKazushi (Jam) Marukawa const BasicBlock *LLVM_BB = BB->getBasicBlock(); 465064859bdSKazushi (Jam) Marukawa MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); 466064859bdSKazushi (Jam) Marukawa MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); 467064859bdSKazushi (Jam) Marukawa MachineFunction::iterator It = ++(BB->getIterator()); 468064859bdSKazushi (Jam) Marukawa MF.insert(It, syscallMBB); 469064859bdSKazushi (Jam) Marukawa MF.insert(It, sinkMBB); 470064859bdSKazushi (Jam) Marukawa 471064859bdSKazushi (Jam) Marukawa // Transfer the remainder of BB and its successor edges to sinkMBB. 472064859bdSKazushi (Jam) Marukawa sinkMBB->splice(sinkMBB->begin(), BB, 473064859bdSKazushi (Jam) Marukawa std::next(std::next(MachineBasicBlock::iterator(MI))), 474064859bdSKazushi (Jam) Marukawa BB->end()); 475064859bdSKazushi (Jam) Marukawa sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 476064859bdSKazushi (Jam) Marukawa 477064859bdSKazushi (Jam) Marukawa // Next, add the true and fallthrough blocks as its successors. 478064859bdSKazushi (Jam) Marukawa BB->addSuccessor(syscallMBB); 479064859bdSKazushi (Jam) Marukawa BB->addSuccessor(sinkMBB); 480064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::BCRLrr)) 481064859bdSKazushi (Jam) Marukawa .addImm(VECC::CC_IGE) 482064859bdSKazushi (Jam) Marukawa .addReg(VE::SX11) // %sp 483064859bdSKazushi (Jam) Marukawa .addReg(VE::SX8) // %sl 484064859bdSKazushi (Jam) Marukawa .addMBB(sinkMBB); 485064859bdSKazushi (Jam) Marukawa 486064859bdSKazushi (Jam) Marukawa BB = syscallMBB; 487064859bdSKazushi (Jam) Marukawa 488064859bdSKazushi (Jam) Marukawa // Update machine-CFG edges 489064859bdSKazushi (Jam) Marukawa BB->addSuccessor(sinkMBB); 490064859bdSKazushi (Jam) Marukawa 491064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61) 492064859bdSKazushi (Jam) Marukawa .addReg(VE::SX14) 493064859bdSKazushi (Jam) Marukawa .addImm(0x18); 494064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) 495064859bdSKazushi (Jam) Marukawa .addReg(VE::SX0) 496064859bdSKazushi (Jam) Marukawa .addImm(0); 497064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63) 498064859bdSKazushi (Jam) Marukawa .addImm(0x13b); 499064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMri)) 500064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 501064859bdSKazushi (Jam) Marukawa .addImm(0) 502064859bdSKazushi (Jam) Marukawa .addReg(VE::SX63); 503064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMri)) 504064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 505064859bdSKazushi (Jam) Marukawa .addImm(8) 506064859bdSKazushi (Jam) Marukawa .addReg(VE::SX8); 507064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMri)) 508064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 509064859bdSKazushi (Jam) Marukawa .addImm(16) 510064859bdSKazushi (Jam) Marukawa .addReg(VE::SX11); 511064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::MONC)); 512064859bdSKazushi (Jam) Marukawa 513064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) 514064859bdSKazushi (Jam) Marukawa .addReg(VE::SX62) 515064859bdSKazushi (Jam) Marukawa .addImm(0); 516064859bdSKazushi (Jam) Marukawa 517064859bdSKazushi (Jam) Marukawa MI.eraseFromParent(); // The pseudo instruction is gone now. 518064859bdSKazushi (Jam) Marukawa return true; 519064859bdSKazushi (Jam) Marukawa } 520