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" 15064859bdSKazushi (Jam) Marukawa #include "VESubtarget.h" 16064859bdSKazushi (Jam) Marukawa #include "llvm/ADT/STLExtras.h" 17064859bdSKazushi (Jam) Marukawa #include "llvm/ADT/SmallVector.h" 18064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineFrameInfo.h" 19064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineInstrBuilder.h" 20064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineMemOperand.h" 21064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineRegisterInfo.h" 22064859bdSKazushi (Jam) Marukawa #include "llvm/Support/CommandLine.h" 23064859bdSKazushi (Jam) Marukawa #include "llvm/Support/Debug.h" 24064859bdSKazushi (Jam) Marukawa #include "llvm/Support/ErrorHandling.h" 25064859bdSKazushi (Jam) Marukawa #include "llvm/Support/TargetRegistry.h" 26064859bdSKazushi (Jam) Marukawa 27064859bdSKazushi (Jam) Marukawa #define DEBUG_TYPE "ve" 28064859bdSKazushi (Jam) Marukawa 29064859bdSKazushi (Jam) Marukawa using namespace llvm; 30064859bdSKazushi (Jam) Marukawa 31064859bdSKazushi (Jam) Marukawa #define GET_INSTRINFO_CTOR_DTOR 32064859bdSKazushi (Jam) Marukawa #include "VEGenInstrInfo.inc" 33064859bdSKazushi (Jam) Marukawa 34064859bdSKazushi (Jam) Marukawa // Pin the vtable to this file. 35064859bdSKazushi (Jam) Marukawa void VEInstrInfo::anchor() {} 36064859bdSKazushi (Jam) Marukawa 37064859bdSKazushi (Jam) Marukawa VEInstrInfo::VEInstrInfo(VESubtarget &ST) 38064859bdSKazushi (Jam) Marukawa : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(), 39064859bdSKazushi (Jam) Marukawa Subtarget(ST) {} 40064859bdSKazushi (Jam) Marukawa 41fef80a29SKazushi (Jam) Marukawa static bool IsIntegerCC(unsigned CC) { return (CC < VECC::CC_AF); } 42fef80a29SKazushi (Jam) Marukawa 43fef80a29SKazushi (Jam) Marukawa static VECC::CondCodes GetOppositeBranchCondition(VECC::CondCodes 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 100*24215fecSSimon 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, 185*24215fecSSimon 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 { 271fef80a29SKazushi (Jam) Marukawa VECC::CondCodes CC = static_cast<VECC::CondCodes>(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 299064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 300064859bdSKazushi (Jam) Marukawa switch (MI.getOpcode()) { 301064859bdSKazushi (Jam) Marukawa case VE::EXTEND_STACK: { 302064859bdSKazushi (Jam) Marukawa return expandExtendStackPseudo(MI); 303064859bdSKazushi (Jam) Marukawa } 304064859bdSKazushi (Jam) Marukawa case VE::EXTEND_STACK_GUARD: { 305064859bdSKazushi (Jam) Marukawa MI.eraseFromParent(); // The pseudo instruction is gone now. 306064859bdSKazushi (Jam) Marukawa return true; 307064859bdSKazushi (Jam) Marukawa } 308064859bdSKazushi (Jam) Marukawa } 309064859bdSKazushi (Jam) Marukawa return false; 310064859bdSKazushi (Jam) Marukawa } 311064859bdSKazushi (Jam) Marukawa 312064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { 313064859bdSKazushi (Jam) Marukawa MachineBasicBlock &MBB = *MI.getParent(); 314064859bdSKazushi (Jam) Marukawa MachineFunction &MF = *MBB.getParent(); 315064859bdSKazushi (Jam) Marukawa const VEInstrInfo &TII = 316064859bdSKazushi (Jam) Marukawa *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 317064859bdSKazushi (Jam) Marukawa DebugLoc dl = MBB.findDebugLoc(MI); 318064859bdSKazushi (Jam) Marukawa 319064859bdSKazushi (Jam) Marukawa // Create following instructions and multiple basic blocks. 320064859bdSKazushi (Jam) Marukawa // 321064859bdSKazushi (Jam) Marukawa // thisBB: 322064859bdSKazushi (Jam) Marukawa // brge.l.t %sp, %sl, sinkBB 323064859bdSKazushi (Jam) Marukawa // syscallBB: 324064859bdSKazushi (Jam) Marukawa // ld %s61, 0x18(, %tp) // load param area 325064859bdSKazushi (Jam) Marukawa // or %s62, 0, %s0 // spill the value of %s0 326064859bdSKazushi (Jam) Marukawa // lea %s63, 0x13b // syscall # of grow 327064859bdSKazushi (Jam) Marukawa // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 328064859bdSKazushi (Jam) Marukawa // shm.l %sl, 0x8(%s61) // store old limit at addr:8 329064859bdSKazushi (Jam) Marukawa // shm.l %sp, 0x10(%s61) // store new limit at addr:16 330064859bdSKazushi (Jam) Marukawa // monc // call monitor 331064859bdSKazushi (Jam) Marukawa // or %s0, 0, %s62 // restore the value of %s0 332064859bdSKazushi (Jam) Marukawa // sinkBB: 333064859bdSKazushi (Jam) Marukawa 334064859bdSKazushi (Jam) Marukawa // Create new MBB 335064859bdSKazushi (Jam) Marukawa MachineBasicBlock *BB = &MBB; 336064859bdSKazushi (Jam) Marukawa const BasicBlock *LLVM_BB = BB->getBasicBlock(); 337064859bdSKazushi (Jam) Marukawa MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); 338064859bdSKazushi (Jam) Marukawa MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); 339064859bdSKazushi (Jam) Marukawa MachineFunction::iterator It = ++(BB->getIterator()); 340064859bdSKazushi (Jam) Marukawa MF.insert(It, syscallMBB); 341064859bdSKazushi (Jam) Marukawa MF.insert(It, sinkMBB); 342064859bdSKazushi (Jam) Marukawa 343064859bdSKazushi (Jam) Marukawa // Transfer the remainder of BB and its successor edges to sinkMBB. 344064859bdSKazushi (Jam) Marukawa sinkMBB->splice(sinkMBB->begin(), BB, 345064859bdSKazushi (Jam) Marukawa std::next(std::next(MachineBasicBlock::iterator(MI))), 346064859bdSKazushi (Jam) Marukawa BB->end()); 347064859bdSKazushi (Jam) Marukawa sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 348064859bdSKazushi (Jam) Marukawa 349064859bdSKazushi (Jam) Marukawa // Next, add the true and fallthrough blocks as its successors. 350064859bdSKazushi (Jam) Marukawa BB->addSuccessor(syscallMBB); 351064859bdSKazushi (Jam) Marukawa BB->addSuccessor(sinkMBB); 352064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::BCRLrr)) 353064859bdSKazushi (Jam) Marukawa .addImm(VECC::CC_IGE) 354064859bdSKazushi (Jam) Marukawa .addReg(VE::SX11) // %sp 355064859bdSKazushi (Jam) Marukawa .addReg(VE::SX8) // %sl 356064859bdSKazushi (Jam) Marukawa .addMBB(sinkMBB); 357064859bdSKazushi (Jam) Marukawa 358064859bdSKazushi (Jam) Marukawa BB = syscallMBB; 359064859bdSKazushi (Jam) Marukawa 360064859bdSKazushi (Jam) Marukawa // Update machine-CFG edges 361064859bdSKazushi (Jam) Marukawa BB->addSuccessor(sinkMBB); 362064859bdSKazushi (Jam) Marukawa 363064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61) 364064859bdSKazushi (Jam) Marukawa .addReg(VE::SX14) 365064859bdSKazushi (Jam) Marukawa .addImm(0x18); 366064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) 367064859bdSKazushi (Jam) Marukawa .addReg(VE::SX0) 368064859bdSKazushi (Jam) Marukawa .addImm(0); 369064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63) 370064859bdSKazushi (Jam) Marukawa .addImm(0x13b); 371064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMri)) 372064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 373064859bdSKazushi (Jam) Marukawa .addImm(0) 374064859bdSKazushi (Jam) Marukawa .addReg(VE::SX63); 375064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMri)) 376064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 377064859bdSKazushi (Jam) Marukawa .addImm(8) 378064859bdSKazushi (Jam) Marukawa .addReg(VE::SX8); 379064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMri)) 380064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 381064859bdSKazushi (Jam) Marukawa .addImm(16) 382064859bdSKazushi (Jam) Marukawa .addReg(VE::SX11); 383064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::MONC)); 384064859bdSKazushi (Jam) Marukawa 385064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) 386064859bdSKazushi (Jam) Marukawa .addReg(VE::SX62) 387064859bdSKazushi (Jam) Marukawa .addImm(0); 388064859bdSKazushi (Jam) Marukawa 389064859bdSKazushi (Jam) Marukawa MI.eraseFromParent(); // The pseudo instruction is gone now. 390064859bdSKazushi (Jam) Marukawa return true; 391064859bdSKazushi (Jam) Marukawa } 392