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