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 41*fef80a29SKazushi (Jam) Marukawa static bool IsIntegerCC(unsigned CC) { return (CC < VECC::CC_AF); } 42*fef80a29SKazushi (Jam) Marukawa 43*fef80a29SKazushi (Jam) Marukawa static VECC::CondCodes GetOppositeBranchCondition(VECC::CondCodes CC) { 44*fef80a29SKazushi (Jam) Marukawa switch(CC) { 45*fef80a29SKazushi (Jam) Marukawa case VECC::CC_IG: return VECC::CC_ILE; 46*fef80a29SKazushi (Jam) Marukawa case VECC::CC_IL: return VECC::CC_IGE; 47*fef80a29SKazushi (Jam) Marukawa case VECC::CC_INE: return VECC::CC_IEQ; 48*fef80a29SKazushi (Jam) Marukawa case VECC::CC_IEQ: return VECC::CC_INE; 49*fef80a29SKazushi (Jam) Marukawa case VECC::CC_IGE: return VECC::CC_IL; 50*fef80a29SKazushi (Jam) Marukawa case VECC::CC_ILE: return VECC::CC_IG; 51*fef80a29SKazushi (Jam) Marukawa case VECC::CC_AF: return VECC::CC_AT; 52*fef80a29SKazushi (Jam) Marukawa case VECC::CC_G: return VECC::CC_LENAN; 53*fef80a29SKazushi (Jam) Marukawa case VECC::CC_L: return VECC::CC_GENAN; 54*fef80a29SKazushi (Jam) Marukawa case VECC::CC_NE: return VECC::CC_EQNAN; 55*fef80a29SKazushi (Jam) Marukawa case VECC::CC_EQ: return VECC::CC_NENAN; 56*fef80a29SKazushi (Jam) Marukawa case VECC::CC_GE: return VECC::CC_LNAN; 57*fef80a29SKazushi (Jam) Marukawa case VECC::CC_LE: return VECC::CC_GNAN; 58*fef80a29SKazushi (Jam) Marukawa case VECC::CC_NUM: return VECC::CC_NAN; 59*fef80a29SKazushi (Jam) Marukawa case VECC::CC_NAN: return VECC::CC_NUM; 60*fef80a29SKazushi (Jam) Marukawa case VECC::CC_GNAN: return VECC::CC_LE; 61*fef80a29SKazushi (Jam) Marukawa case VECC::CC_LNAN: return VECC::CC_GE; 62*fef80a29SKazushi (Jam) Marukawa case VECC::CC_NENAN: return VECC::CC_EQ; 63*fef80a29SKazushi (Jam) Marukawa case VECC::CC_EQNAN: return VECC::CC_NE; 64*fef80a29SKazushi (Jam) Marukawa case VECC::CC_GENAN: return VECC::CC_L; 65*fef80a29SKazushi (Jam) Marukawa case VECC::CC_LENAN: return VECC::CC_G; 66*fef80a29SKazushi (Jam) Marukawa case VECC::CC_AT: return VECC::CC_AF; 67*fef80a29SKazushi (Jam) Marukawa } 68*fef80a29SKazushi (Jam) Marukawa llvm_unreachable("Invalid cond code"); 69*fef80a29SKazushi (Jam) Marukawa } 70*fef80a29SKazushi (Jam) Marukawa 71*fef80a29SKazushi (Jam) Marukawa // Treat br.l [BCR AT] as unconditional branch 72*fef80a29SKazushi (Jam) Marukawa static bool isUncondBranchOpcode(int Opc) { 73*fef80a29SKazushi (Jam) Marukawa return Opc == VE::BCRLa || Opc == VE::BCRWa || 74*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRDa || Opc == VE::BCRSa; 75*fef80a29SKazushi (Jam) Marukawa } 76*fef80a29SKazushi (Jam) Marukawa 77*fef80a29SKazushi (Jam) Marukawa static bool isCondBranchOpcode(int Opc) { 78*fef80a29SKazushi (Jam) Marukawa return Opc == VE::BCRLrr || Opc == VE::BCRLir || 79*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRLrm0 || Opc == VE::BCRLrm1 || 80*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRLim0 || Opc == VE::BCRLim1 || 81*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRWrr || Opc == VE::BCRWir || 82*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRWrm0 || Opc == VE::BCRWrm1 || 83*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRWim0 || Opc == VE::BCRWim1 || 84*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRDrr || Opc == VE::BCRDir || 85*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRDrm0 || Opc == VE::BCRDrm1 || 86*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRDim0 || Opc == VE::BCRDim1 || 87*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRSrr || Opc == VE::BCRSir || 88*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRSrm0 || Opc == VE::BCRSrm1 || 89*fef80a29SKazushi (Jam) Marukawa Opc == VE::BCRSim0 || Opc == VE::BCRSim1; 90*fef80a29SKazushi (Jam) Marukawa } 91*fef80a29SKazushi (Jam) Marukawa 92*fef80a29SKazushi (Jam) Marukawa static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, 93*fef80a29SKazushi (Jam) Marukawa SmallVectorImpl<MachineOperand> &Cond) { 94*fef80a29SKazushi (Jam) Marukawa Cond.push_back(MachineOperand::CreateImm(LastInst->getOperand(0).getImm())); 95*fef80a29SKazushi (Jam) Marukawa Cond.push_back(LastInst->getOperand(1)); 96*fef80a29SKazushi (Jam) Marukawa Cond.push_back(LastInst->getOperand(2)); 97*fef80a29SKazushi (Jam) Marukawa Target = LastInst->getOperand(3).getMBB(); 98*fef80a29SKazushi (Jam) Marukawa } 99*fef80a29SKazushi (Jam) Marukawa 100*fef80a29SKazushi (Jam) Marukawa bool VEInstrInfo::analyzeBranch(MachineBasicBlock &MBB, 101*fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *&TBB, 102*fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *&FBB, 103*fef80a29SKazushi (Jam) Marukawa SmallVectorImpl<MachineOperand> &Cond, 104*fef80a29SKazushi (Jam) Marukawa bool AllowModify) const { 105*fef80a29SKazushi (Jam) Marukawa MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 106*fef80a29SKazushi (Jam) Marukawa if (I == MBB.end()) 107*fef80a29SKazushi (Jam) Marukawa return false; 108*fef80a29SKazushi (Jam) Marukawa 109*fef80a29SKazushi (Jam) Marukawa if (!isUnpredicatedTerminator(*I)) 110*fef80a29SKazushi (Jam) Marukawa return false; 111*fef80a29SKazushi (Jam) Marukawa 112*fef80a29SKazushi (Jam) Marukawa // Get the last instruction in the block. 113*fef80a29SKazushi (Jam) Marukawa MachineInstr *LastInst = &*I; 114*fef80a29SKazushi (Jam) Marukawa unsigned LastOpc = LastInst->getOpcode(); 115*fef80a29SKazushi (Jam) Marukawa 116*fef80a29SKazushi (Jam) Marukawa // If there is only one terminator instruction, process it. 117*fef80a29SKazushi (Jam) Marukawa if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 118*fef80a29SKazushi (Jam) Marukawa if (isUncondBranchOpcode(LastOpc)) { 119*fef80a29SKazushi (Jam) Marukawa TBB = LastInst->getOperand(0).getMBB(); 120*fef80a29SKazushi (Jam) Marukawa return false; 121*fef80a29SKazushi (Jam) Marukawa } 122*fef80a29SKazushi (Jam) Marukawa if (isCondBranchOpcode(LastOpc)) { 123*fef80a29SKazushi (Jam) Marukawa // Block ends with fall-through condbranch. 124*fef80a29SKazushi (Jam) Marukawa parseCondBranch(LastInst, TBB, Cond); 125*fef80a29SKazushi (Jam) Marukawa return false; 126*fef80a29SKazushi (Jam) Marukawa } 127*fef80a29SKazushi (Jam) Marukawa return true; // Can't handle indirect branch. 128*fef80a29SKazushi (Jam) Marukawa } 129*fef80a29SKazushi (Jam) Marukawa 130*fef80a29SKazushi (Jam) Marukawa // Get the instruction before it if it is a terminator. 131*fef80a29SKazushi (Jam) Marukawa MachineInstr *SecondLastInst = &*I; 132*fef80a29SKazushi (Jam) Marukawa unsigned SecondLastOpc = SecondLastInst->getOpcode(); 133*fef80a29SKazushi (Jam) Marukawa 134*fef80a29SKazushi (Jam) Marukawa // If AllowModify is true and the block ends with two or more unconditional 135*fef80a29SKazushi (Jam) Marukawa // branches, delete all but the first unconditional branch. 136*fef80a29SKazushi (Jam) Marukawa if (AllowModify && isUncondBranchOpcode(LastOpc)) { 137*fef80a29SKazushi (Jam) Marukawa while (isUncondBranchOpcode(SecondLastOpc)) { 138*fef80a29SKazushi (Jam) Marukawa LastInst->eraseFromParent(); 139*fef80a29SKazushi (Jam) Marukawa LastInst = SecondLastInst; 140*fef80a29SKazushi (Jam) Marukawa LastOpc = LastInst->getOpcode(); 141*fef80a29SKazushi (Jam) Marukawa if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 142*fef80a29SKazushi (Jam) Marukawa // Return now the only terminator is an unconditional branch. 143*fef80a29SKazushi (Jam) Marukawa TBB = LastInst->getOperand(0).getMBB(); 144*fef80a29SKazushi (Jam) Marukawa return false; 145*fef80a29SKazushi (Jam) Marukawa } 146*fef80a29SKazushi (Jam) Marukawa SecondLastInst = &*I; 147*fef80a29SKazushi (Jam) Marukawa SecondLastOpc = SecondLastInst->getOpcode(); 148*fef80a29SKazushi (Jam) Marukawa } 149*fef80a29SKazushi (Jam) Marukawa } 150*fef80a29SKazushi (Jam) Marukawa 151*fef80a29SKazushi (Jam) Marukawa // If there are three terminators, we don't know what sort of block this is. 152*fef80a29SKazushi (Jam) Marukawa if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) 153*fef80a29SKazushi (Jam) Marukawa return true; 154*fef80a29SKazushi (Jam) Marukawa 155*fef80a29SKazushi (Jam) Marukawa // If the block ends with a B and a Bcc, handle it. 156*fef80a29SKazushi (Jam) Marukawa if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 157*fef80a29SKazushi (Jam) Marukawa parseCondBranch(SecondLastInst, TBB, Cond); 158*fef80a29SKazushi (Jam) Marukawa FBB = LastInst->getOperand(0).getMBB(); 159*fef80a29SKazushi (Jam) Marukawa return false; 160*fef80a29SKazushi (Jam) Marukawa } 161*fef80a29SKazushi (Jam) Marukawa 162*fef80a29SKazushi (Jam) Marukawa // If the block ends with two unconditional branches, handle it. The second 163*fef80a29SKazushi (Jam) Marukawa // one is not executed. 164*fef80a29SKazushi (Jam) Marukawa if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 165*fef80a29SKazushi (Jam) Marukawa TBB = SecondLastInst->getOperand(0).getMBB(); 166*fef80a29SKazushi (Jam) Marukawa return false; 167*fef80a29SKazushi (Jam) Marukawa } 168*fef80a29SKazushi (Jam) Marukawa 169*fef80a29SKazushi (Jam) Marukawa // TODO ...likewise if it ends with an indirect branch followed by an unconditional 170*fef80a29SKazushi (Jam) Marukawa // branch. 171*fef80a29SKazushi (Jam) Marukawa // if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 172*fef80a29SKazushi (Jam) Marukawa // I = LastInst; 173*fef80a29SKazushi (Jam) Marukawa // if (AllowModify) 174*fef80a29SKazushi (Jam) Marukawa // I->eraseFromParent(); 175*fef80a29SKazushi (Jam) Marukawa // return true; 176*fef80a29SKazushi (Jam) Marukawa // } 177*fef80a29SKazushi (Jam) Marukawa 178*fef80a29SKazushi (Jam) Marukawa // Otherwise, can't handle this. 179*fef80a29SKazushi (Jam) Marukawa return true; 180*fef80a29SKazushi (Jam) Marukawa } 181*fef80a29SKazushi (Jam) Marukawa 182*fef80a29SKazushi (Jam) Marukawa unsigned VEInstrInfo::insertBranch(MachineBasicBlock &MBB, 183*fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *TBB, 184*fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *FBB, 185*fef80a29SKazushi (Jam) Marukawa ArrayRef<MachineOperand> Cond, 186*fef80a29SKazushi (Jam) Marukawa const DebugLoc &DL, 187*fef80a29SKazushi (Jam) Marukawa int *BytesAdded) const { 188*fef80a29SKazushi (Jam) Marukawa assert(TBB && "insertBranch must not be told to insert a fallthrough"); 189*fef80a29SKazushi (Jam) Marukawa assert((Cond.size() == 3 || Cond.size() == 0) && 190*fef80a29SKazushi (Jam) Marukawa "VE branch conditions should have three component!"); 191*fef80a29SKazushi (Jam) Marukawa assert(!BytesAdded && "code size not handled"); 192*fef80a29SKazushi (Jam) Marukawa if (Cond.empty()) { 193*fef80a29SKazushi (Jam) Marukawa // Uncondition branch 194*fef80a29SKazushi (Jam) Marukawa assert(!FBB && "Unconditional branch with multiple successors!"); 195*fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(VE::BCRLa)) 196*fef80a29SKazushi (Jam) Marukawa .addMBB(TBB); 197*fef80a29SKazushi (Jam) Marukawa return 1; 198*fef80a29SKazushi (Jam) Marukawa } 199*fef80a29SKazushi (Jam) Marukawa 200*fef80a29SKazushi (Jam) Marukawa // Conditional branch 201*fef80a29SKazushi (Jam) Marukawa // (BCRir CC sy sz addr) 202*fef80a29SKazushi (Jam) Marukawa assert(Cond[0].isImm() && Cond[2].isReg() && "not implemented"); 203*fef80a29SKazushi (Jam) Marukawa 204*fef80a29SKazushi (Jam) Marukawa unsigned opc[2]; 205*fef80a29SKazushi (Jam) Marukawa const TargetRegisterInfo *TRI = &getRegisterInfo(); 206*fef80a29SKazushi (Jam) Marukawa MachineFunction *MF = MBB.getParent(); 207*fef80a29SKazushi (Jam) Marukawa const MachineRegisterInfo &MRI = MF->getRegInfo(); 208*fef80a29SKazushi (Jam) Marukawa unsigned Reg = Cond[2].getReg(); 209*fef80a29SKazushi (Jam) Marukawa if (IsIntegerCC(Cond[0].getImm())) { 210*fef80a29SKazushi (Jam) Marukawa if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 211*fef80a29SKazushi (Jam) Marukawa opc[0] = VE::BCRWir; 212*fef80a29SKazushi (Jam) Marukawa opc[1] = VE::BCRWrr; 213*fef80a29SKazushi (Jam) Marukawa } else { 214*fef80a29SKazushi (Jam) Marukawa opc[0] = VE::BCRLir; 215*fef80a29SKazushi (Jam) Marukawa opc[1] = VE::BCRLrr; 216*fef80a29SKazushi (Jam) Marukawa } 217*fef80a29SKazushi (Jam) Marukawa } else { 218*fef80a29SKazushi (Jam) Marukawa if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 219*fef80a29SKazushi (Jam) Marukawa opc[0] = VE::BCRSir; 220*fef80a29SKazushi (Jam) Marukawa opc[1] = VE::BCRSrr; 221*fef80a29SKazushi (Jam) Marukawa } else { 222*fef80a29SKazushi (Jam) Marukawa opc[0] = VE::BCRDir; 223*fef80a29SKazushi (Jam) Marukawa opc[1] = VE::BCRDrr; 224*fef80a29SKazushi (Jam) Marukawa } 225*fef80a29SKazushi (Jam) Marukawa } 226*fef80a29SKazushi (Jam) Marukawa if (Cond[1].isImm()) { 227*fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(opc[0])) 228*fef80a29SKazushi (Jam) Marukawa .add(Cond[0]) // condition code 229*fef80a29SKazushi (Jam) Marukawa .add(Cond[1]) // lhs 230*fef80a29SKazushi (Jam) Marukawa .add(Cond[2]) // rhs 231*fef80a29SKazushi (Jam) Marukawa .addMBB(TBB); 232*fef80a29SKazushi (Jam) Marukawa } else { 233*fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(opc[1])) 234*fef80a29SKazushi (Jam) Marukawa .add(Cond[0]) 235*fef80a29SKazushi (Jam) Marukawa .add(Cond[1]) 236*fef80a29SKazushi (Jam) Marukawa .add(Cond[2]) 237*fef80a29SKazushi (Jam) Marukawa .addMBB(TBB); 238*fef80a29SKazushi (Jam) Marukawa } 239*fef80a29SKazushi (Jam) Marukawa 240*fef80a29SKazushi (Jam) Marukawa if (!FBB) 241*fef80a29SKazushi (Jam) Marukawa return 1; 242*fef80a29SKazushi (Jam) Marukawa 243*fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(VE::BCRLa)) 244*fef80a29SKazushi (Jam) Marukawa .addMBB(FBB); 245*fef80a29SKazushi (Jam) Marukawa return 2; 246*fef80a29SKazushi (Jam) Marukawa } 247*fef80a29SKazushi (Jam) Marukawa 248*fef80a29SKazushi (Jam) Marukawa unsigned VEInstrInfo::removeBranch(MachineBasicBlock &MBB, 249*fef80a29SKazushi (Jam) Marukawa int *BytesRemoved) const { 250*fef80a29SKazushi (Jam) Marukawa assert(!BytesRemoved && "code size not handled"); 251*fef80a29SKazushi (Jam) Marukawa 252*fef80a29SKazushi (Jam) Marukawa MachineBasicBlock::iterator I = MBB.end(); 253*fef80a29SKazushi (Jam) Marukawa unsigned Count = 0; 254*fef80a29SKazushi (Jam) Marukawa while (I != MBB.begin()) { 255*fef80a29SKazushi (Jam) Marukawa --I; 256*fef80a29SKazushi (Jam) Marukawa 257*fef80a29SKazushi (Jam) Marukawa if (I->isDebugValue()) 258*fef80a29SKazushi (Jam) Marukawa continue; 259*fef80a29SKazushi (Jam) Marukawa 260*fef80a29SKazushi (Jam) Marukawa if (!isUncondBranchOpcode(I->getOpcode()) && 261*fef80a29SKazushi (Jam) Marukawa !isCondBranchOpcode(I->getOpcode())) 262*fef80a29SKazushi (Jam) Marukawa break; // Not a branch 263*fef80a29SKazushi (Jam) Marukawa 264*fef80a29SKazushi (Jam) Marukawa I->eraseFromParent(); 265*fef80a29SKazushi (Jam) Marukawa I = MBB.end(); 266*fef80a29SKazushi (Jam) Marukawa ++Count; 267*fef80a29SKazushi (Jam) Marukawa } 268*fef80a29SKazushi (Jam) Marukawa return Count; 269*fef80a29SKazushi (Jam) Marukawa } 270*fef80a29SKazushi (Jam) Marukawa 271*fef80a29SKazushi (Jam) Marukawa bool VEInstrInfo::reverseBranchCondition( 272*fef80a29SKazushi (Jam) Marukawa SmallVectorImpl<MachineOperand> &Cond) const { 273*fef80a29SKazushi (Jam) Marukawa VECC::CondCodes CC = static_cast<VECC::CondCodes>(Cond[0].getImm()); 274*fef80a29SKazushi (Jam) Marukawa Cond[0].setImm(GetOppositeBranchCondition(CC)); 275*fef80a29SKazushi (Jam) Marukawa return false; 276*fef80a29SKazushi (Jam) Marukawa } 277*fef80a29SKazushi (Jam) Marukawa 2783a906a9fSKazushi (Jam) Marukawa static bool IsAliasOfSX(Register Reg) { 2793a906a9fSKazushi (Jam) Marukawa return VE::I8RegClass.contains(Reg) || VE::I16RegClass.contains(Reg) || 2803a906a9fSKazushi (Jam) Marukawa VE::I32RegClass.contains(Reg) || VE::I64RegClass.contains(Reg) || 2813a906a9fSKazushi (Jam) Marukawa VE::F32RegClass.contains(Reg); 2823a906a9fSKazushi (Jam) Marukawa } 2833a906a9fSKazushi (Jam) Marukawa 284773ae62fSKazushi (Jam) Marukawa void VEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 285773ae62fSKazushi (Jam) Marukawa MachineBasicBlock::iterator I, const DebugLoc &DL, 286773ae62fSKazushi (Jam) Marukawa MCRegister DestReg, MCRegister SrcReg, 287773ae62fSKazushi (Jam) Marukawa bool KillSrc) const { 288773ae62fSKazushi (Jam) Marukawa 2893a906a9fSKazushi (Jam) Marukawa if (IsAliasOfSX(SrcReg) && IsAliasOfSX(DestReg)) { 290773ae62fSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::ORri), DestReg) 291773ae62fSKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(KillSrc)) 292773ae62fSKazushi (Jam) Marukawa .addImm(0); 293773ae62fSKazushi (Jam) Marukawa } else { 294773ae62fSKazushi (Jam) Marukawa const TargetRegisterInfo *TRI = &getRegisterInfo(); 295773ae62fSKazushi (Jam) Marukawa dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg, TRI) 296773ae62fSKazushi (Jam) Marukawa << " to " << printReg(DestReg, TRI) << "\n"; 297773ae62fSKazushi (Jam) Marukawa llvm_unreachable("Impossible reg-to-reg copy"); 298773ae62fSKazushi (Jam) Marukawa } 299773ae62fSKazushi (Jam) Marukawa } 300773ae62fSKazushi (Jam) Marukawa 301064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 302064859bdSKazushi (Jam) Marukawa switch (MI.getOpcode()) { 303064859bdSKazushi (Jam) Marukawa case VE::EXTEND_STACK: { 304064859bdSKazushi (Jam) Marukawa return expandExtendStackPseudo(MI); 305064859bdSKazushi (Jam) Marukawa } 306064859bdSKazushi (Jam) Marukawa case VE::EXTEND_STACK_GUARD: { 307064859bdSKazushi (Jam) Marukawa MI.eraseFromParent(); // The pseudo instruction is gone now. 308064859bdSKazushi (Jam) Marukawa return true; 309064859bdSKazushi (Jam) Marukawa } 310064859bdSKazushi (Jam) Marukawa } 311064859bdSKazushi (Jam) Marukawa return false; 312064859bdSKazushi (Jam) Marukawa } 313064859bdSKazushi (Jam) Marukawa 314064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { 315064859bdSKazushi (Jam) Marukawa MachineBasicBlock &MBB = *MI.getParent(); 316064859bdSKazushi (Jam) Marukawa MachineFunction &MF = *MBB.getParent(); 317064859bdSKazushi (Jam) Marukawa const VEInstrInfo &TII = 318064859bdSKazushi (Jam) Marukawa *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 319064859bdSKazushi (Jam) Marukawa DebugLoc dl = MBB.findDebugLoc(MI); 320064859bdSKazushi (Jam) Marukawa 321064859bdSKazushi (Jam) Marukawa // Create following instructions and multiple basic blocks. 322064859bdSKazushi (Jam) Marukawa // 323064859bdSKazushi (Jam) Marukawa // thisBB: 324064859bdSKazushi (Jam) Marukawa // brge.l.t %sp, %sl, sinkBB 325064859bdSKazushi (Jam) Marukawa // syscallBB: 326064859bdSKazushi (Jam) Marukawa // ld %s61, 0x18(, %tp) // load param area 327064859bdSKazushi (Jam) Marukawa // or %s62, 0, %s0 // spill the value of %s0 328064859bdSKazushi (Jam) Marukawa // lea %s63, 0x13b // syscall # of grow 329064859bdSKazushi (Jam) Marukawa // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 330064859bdSKazushi (Jam) Marukawa // shm.l %sl, 0x8(%s61) // store old limit at addr:8 331064859bdSKazushi (Jam) Marukawa // shm.l %sp, 0x10(%s61) // store new limit at addr:16 332064859bdSKazushi (Jam) Marukawa // monc // call monitor 333064859bdSKazushi (Jam) Marukawa // or %s0, 0, %s62 // restore the value of %s0 334064859bdSKazushi (Jam) Marukawa // sinkBB: 335064859bdSKazushi (Jam) Marukawa 336064859bdSKazushi (Jam) Marukawa // Create new MBB 337064859bdSKazushi (Jam) Marukawa MachineBasicBlock *BB = &MBB; 338064859bdSKazushi (Jam) Marukawa const BasicBlock *LLVM_BB = BB->getBasicBlock(); 339064859bdSKazushi (Jam) Marukawa MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); 340064859bdSKazushi (Jam) Marukawa MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); 341064859bdSKazushi (Jam) Marukawa MachineFunction::iterator It = ++(BB->getIterator()); 342064859bdSKazushi (Jam) Marukawa MF.insert(It, syscallMBB); 343064859bdSKazushi (Jam) Marukawa MF.insert(It, sinkMBB); 344064859bdSKazushi (Jam) Marukawa 345064859bdSKazushi (Jam) Marukawa // Transfer the remainder of BB and its successor edges to sinkMBB. 346064859bdSKazushi (Jam) Marukawa sinkMBB->splice(sinkMBB->begin(), BB, 347064859bdSKazushi (Jam) Marukawa std::next(std::next(MachineBasicBlock::iterator(MI))), 348064859bdSKazushi (Jam) Marukawa BB->end()); 349064859bdSKazushi (Jam) Marukawa sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 350064859bdSKazushi (Jam) Marukawa 351064859bdSKazushi (Jam) Marukawa // Next, add the true and fallthrough blocks as its successors. 352064859bdSKazushi (Jam) Marukawa BB->addSuccessor(syscallMBB); 353064859bdSKazushi (Jam) Marukawa BB->addSuccessor(sinkMBB); 354064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::BCRLrr)) 355064859bdSKazushi (Jam) Marukawa .addImm(VECC::CC_IGE) 356064859bdSKazushi (Jam) Marukawa .addReg(VE::SX11) // %sp 357064859bdSKazushi (Jam) Marukawa .addReg(VE::SX8) // %sl 358064859bdSKazushi (Jam) Marukawa .addMBB(sinkMBB); 359064859bdSKazushi (Jam) Marukawa 360064859bdSKazushi (Jam) Marukawa BB = syscallMBB; 361064859bdSKazushi (Jam) Marukawa 362064859bdSKazushi (Jam) Marukawa // Update machine-CFG edges 363064859bdSKazushi (Jam) Marukawa BB->addSuccessor(sinkMBB); 364064859bdSKazushi (Jam) Marukawa 365064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61) 366064859bdSKazushi (Jam) Marukawa .addReg(VE::SX14) 367064859bdSKazushi (Jam) Marukawa .addImm(0x18); 368064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) 369064859bdSKazushi (Jam) Marukawa .addReg(VE::SX0) 370064859bdSKazushi (Jam) Marukawa .addImm(0); 371064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63) 372064859bdSKazushi (Jam) Marukawa .addImm(0x13b); 373064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMri)) 374064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 375064859bdSKazushi (Jam) Marukawa .addImm(0) 376064859bdSKazushi (Jam) Marukawa .addReg(VE::SX63); 377064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMri)) 378064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 379064859bdSKazushi (Jam) Marukawa .addImm(8) 380064859bdSKazushi (Jam) Marukawa .addReg(VE::SX8); 381064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMri)) 382064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 383064859bdSKazushi (Jam) Marukawa .addImm(16) 384064859bdSKazushi (Jam) Marukawa .addReg(VE::SX11); 385064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::MONC)); 386064859bdSKazushi (Jam) Marukawa 387064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) 388064859bdSKazushi (Jam) Marukawa .addReg(VE::SX62) 389064859bdSKazushi (Jam) Marukawa .addImm(0); 390064859bdSKazushi (Jam) Marukawa 391064859bdSKazushi (Jam) Marukawa MI.eraseFromParent(); // The pseudo instruction is gone now. 392064859bdSKazushi (Jam) Marukawa return true; 393064859bdSKazushi (Jam) Marukawa } 394