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" 2389b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h" 24064859bdSKazushi (Jam) Marukawa #include "llvm/Support/CommandLine.h" 25064859bdSKazushi (Jam) Marukawa #include "llvm/Support/Debug.h" 26064859bdSKazushi (Jam) Marukawa #include "llvm/Support/ErrorHandling.h" 27064859bdSKazushi (Jam) Marukawa 28dedaf3a2SKazushi (Jam) Marukawa #define DEBUG_TYPE "ve-instr-info" 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 4328a42dd1SKazushi (Jam) Marukawa static VECC::CondCode GetOppositeBranchCondition(VECC::CondCode CC) { 44fef80a29SKazushi (Jam) Marukawa switch (CC) { 45117c0d7cSKazushi (Jam) Marukawa case VECC::CC_IG: 46117c0d7cSKazushi (Jam) Marukawa return VECC::CC_ILE; 47117c0d7cSKazushi (Jam) Marukawa case VECC::CC_IL: 48117c0d7cSKazushi (Jam) Marukawa return VECC::CC_IGE; 49117c0d7cSKazushi (Jam) Marukawa case VECC::CC_INE: 50117c0d7cSKazushi (Jam) Marukawa return VECC::CC_IEQ; 51117c0d7cSKazushi (Jam) Marukawa case VECC::CC_IEQ: 52117c0d7cSKazushi (Jam) Marukawa return VECC::CC_INE; 53117c0d7cSKazushi (Jam) Marukawa case VECC::CC_IGE: 54117c0d7cSKazushi (Jam) Marukawa return VECC::CC_IL; 55117c0d7cSKazushi (Jam) Marukawa case VECC::CC_ILE: 56117c0d7cSKazushi (Jam) Marukawa return VECC::CC_IG; 57117c0d7cSKazushi (Jam) Marukawa case VECC::CC_AF: 58117c0d7cSKazushi (Jam) Marukawa return VECC::CC_AT; 59117c0d7cSKazushi (Jam) Marukawa case VECC::CC_G: 60117c0d7cSKazushi (Jam) Marukawa return VECC::CC_LENAN; 61117c0d7cSKazushi (Jam) Marukawa case VECC::CC_L: 62117c0d7cSKazushi (Jam) Marukawa return VECC::CC_GENAN; 63117c0d7cSKazushi (Jam) Marukawa case VECC::CC_NE: 64117c0d7cSKazushi (Jam) Marukawa return VECC::CC_EQNAN; 65117c0d7cSKazushi (Jam) Marukawa case VECC::CC_EQ: 66117c0d7cSKazushi (Jam) Marukawa return VECC::CC_NENAN; 67117c0d7cSKazushi (Jam) Marukawa case VECC::CC_GE: 68117c0d7cSKazushi (Jam) Marukawa return VECC::CC_LNAN; 69117c0d7cSKazushi (Jam) Marukawa case VECC::CC_LE: 70117c0d7cSKazushi (Jam) Marukawa return VECC::CC_GNAN; 71117c0d7cSKazushi (Jam) Marukawa case VECC::CC_NUM: 72117c0d7cSKazushi (Jam) Marukawa return VECC::CC_NAN; 73117c0d7cSKazushi (Jam) Marukawa case VECC::CC_NAN: 74117c0d7cSKazushi (Jam) Marukawa return VECC::CC_NUM; 75117c0d7cSKazushi (Jam) Marukawa case VECC::CC_GNAN: 76117c0d7cSKazushi (Jam) Marukawa return VECC::CC_LE; 77117c0d7cSKazushi (Jam) Marukawa case VECC::CC_LNAN: 78117c0d7cSKazushi (Jam) Marukawa return VECC::CC_GE; 79117c0d7cSKazushi (Jam) Marukawa case VECC::CC_NENAN: 80117c0d7cSKazushi (Jam) Marukawa return VECC::CC_EQ; 81117c0d7cSKazushi (Jam) Marukawa case VECC::CC_EQNAN: 82117c0d7cSKazushi (Jam) Marukawa return VECC::CC_NE; 83117c0d7cSKazushi (Jam) Marukawa case VECC::CC_GENAN: 84117c0d7cSKazushi (Jam) Marukawa return VECC::CC_L; 85117c0d7cSKazushi (Jam) Marukawa case VECC::CC_LENAN: 86117c0d7cSKazushi (Jam) Marukawa return VECC::CC_G; 87117c0d7cSKazushi (Jam) Marukawa case VECC::CC_AT: 88117c0d7cSKazushi (Jam) Marukawa return VECC::CC_AF; 89117c0d7cSKazushi (Jam) Marukawa case VECC::UNKNOWN: 90117c0d7cSKazushi (Jam) Marukawa return VECC::UNKNOWN; 91fef80a29SKazushi (Jam) Marukawa } 92fef80a29SKazushi (Jam) Marukawa llvm_unreachable("Invalid cond code"); 93fef80a29SKazushi (Jam) Marukawa } 94fef80a29SKazushi (Jam) Marukawa 956fe61053SKazushi (Jam) Marukawa // Treat a branch relative long always instruction as unconditional branch. 966fe61053SKazushi (Jam) Marukawa // For example, br.l.t and br.l. 97fef80a29SKazushi (Jam) Marukawa static bool isUncondBranchOpcode(int Opc) { 986fe61053SKazushi (Jam) Marukawa using namespace llvm::VE; 996fe61053SKazushi (Jam) Marukawa 1006fe61053SKazushi (Jam) Marukawa #define BRKIND(NAME) (Opc == NAME##a || Opc == NAME##a_nt || Opc == NAME##a_t) 1016fe61053SKazushi (Jam) Marukawa // VE has other branch relative always instructions for word/double/float, 1025b8bbbecSZarko Todorovski // but we use only long branches in our lower. So, check it here. 1036fe61053SKazushi (Jam) Marukawa assert(!BRKIND(BRCFW) && !BRKIND(BRCFD) && !BRKIND(BRCFS) && 1046fe61053SKazushi (Jam) Marukawa "Branch relative word/double/float always instructions should not be " 1056fe61053SKazushi (Jam) Marukawa "used!"); 1066fe61053SKazushi (Jam) Marukawa return BRKIND(BRCFL); 1076fe61053SKazushi (Jam) Marukawa #undef BRKIND 108fef80a29SKazushi (Jam) Marukawa } 109fef80a29SKazushi (Jam) Marukawa 1106fe61053SKazushi (Jam) Marukawa // Treat branch relative conditional as conditional branch instructions. 1116fe61053SKazushi (Jam) Marukawa // For example, brgt.l.t and brle.s.nt. 112fef80a29SKazushi (Jam) Marukawa static bool isCondBranchOpcode(int Opc) { 1136fe61053SKazushi (Jam) Marukawa using namespace llvm::VE; 1146fe61053SKazushi (Jam) Marukawa 1156fe61053SKazushi (Jam) Marukawa #define BRKIND(NAME) \ 1166fe61053SKazushi (Jam) Marukawa (Opc == NAME##rr || Opc == NAME##rr_nt || Opc == NAME##rr_t || \ 1176fe61053SKazushi (Jam) Marukawa Opc == NAME##ir || Opc == NAME##ir_nt || Opc == NAME##ir_t) 1186fe61053SKazushi (Jam) Marukawa return BRKIND(BRCFL) || BRKIND(BRCFW) || BRKIND(BRCFD) || BRKIND(BRCFS); 1196fe61053SKazushi (Jam) Marukawa #undef BRKIND 1203c80478dSKazushi (Jam) Marukawa } 1213c80478dSKazushi (Jam) Marukawa 1226fe61053SKazushi (Jam) Marukawa // Treat branch long always instructions as indirect branch. 1236fe61053SKazushi (Jam) Marukawa // For example, b.l.t and b.l. 1243c80478dSKazushi (Jam) Marukawa static bool isIndirectBranchOpcode(int Opc) { 1256fe61053SKazushi (Jam) Marukawa using namespace llvm::VE; 1266fe61053SKazushi (Jam) Marukawa 1276fe61053SKazushi (Jam) Marukawa #define BRKIND(NAME) \ 1286fe61053SKazushi (Jam) Marukawa (Opc == NAME##ari || Opc == NAME##ari_nt || Opc == NAME##ari_t) 1296fe61053SKazushi (Jam) Marukawa // VE has other branch always instructions for word/double/float, but 1305b8bbbecSZarko Todorovski // we use only long branches in our lower. So, check it here. 1316fe61053SKazushi (Jam) Marukawa assert(!BRKIND(BCFW) && !BRKIND(BCFD) && !BRKIND(BCFS) && 1326fe61053SKazushi (Jam) Marukawa "Branch word/double/float always instructions should not be used!"); 1336fe61053SKazushi (Jam) Marukawa return BRKIND(BCFL); 1346fe61053SKazushi (Jam) Marukawa #undef BRKIND 135fef80a29SKazushi (Jam) Marukawa } 136fef80a29SKazushi (Jam) Marukawa 137fef80a29SKazushi (Jam) Marukawa static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, 138fef80a29SKazushi (Jam) Marukawa SmallVectorImpl<MachineOperand> &Cond) { 139fef80a29SKazushi (Jam) Marukawa Cond.push_back(MachineOperand::CreateImm(LastInst->getOperand(0).getImm())); 140fef80a29SKazushi (Jam) Marukawa Cond.push_back(LastInst->getOperand(1)); 141fef80a29SKazushi (Jam) Marukawa Cond.push_back(LastInst->getOperand(2)); 142fef80a29SKazushi (Jam) Marukawa Target = LastInst->getOperand(3).getMBB(); 143fef80a29SKazushi (Jam) Marukawa } 144fef80a29SKazushi (Jam) Marukawa 14524215fecSSimon Moll bool VEInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 146fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *&FBB, 147fef80a29SKazushi (Jam) Marukawa SmallVectorImpl<MachineOperand> &Cond, 148fef80a29SKazushi (Jam) Marukawa bool AllowModify) const { 149fef80a29SKazushi (Jam) Marukawa MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 150fef80a29SKazushi (Jam) Marukawa if (I == MBB.end()) 151fef80a29SKazushi (Jam) Marukawa return false; 152fef80a29SKazushi (Jam) Marukawa 153fef80a29SKazushi (Jam) Marukawa if (!isUnpredicatedTerminator(*I)) 154fef80a29SKazushi (Jam) Marukawa return false; 155fef80a29SKazushi (Jam) Marukawa 156fef80a29SKazushi (Jam) Marukawa // Get the last instruction in the block. 157fef80a29SKazushi (Jam) Marukawa MachineInstr *LastInst = &*I; 158fef80a29SKazushi (Jam) Marukawa unsigned LastOpc = LastInst->getOpcode(); 159fef80a29SKazushi (Jam) Marukawa 160fef80a29SKazushi (Jam) Marukawa // If there is only one terminator instruction, process it. 161fef80a29SKazushi (Jam) Marukawa if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 162fef80a29SKazushi (Jam) Marukawa if (isUncondBranchOpcode(LastOpc)) { 163fef80a29SKazushi (Jam) Marukawa TBB = LastInst->getOperand(0).getMBB(); 164fef80a29SKazushi (Jam) Marukawa return false; 165fef80a29SKazushi (Jam) Marukawa } 166fef80a29SKazushi (Jam) Marukawa if (isCondBranchOpcode(LastOpc)) { 167fef80a29SKazushi (Jam) Marukawa // Block ends with fall-through condbranch. 168fef80a29SKazushi (Jam) Marukawa parseCondBranch(LastInst, TBB, Cond); 169fef80a29SKazushi (Jam) Marukawa return false; 170fef80a29SKazushi (Jam) Marukawa } 171fef80a29SKazushi (Jam) Marukawa return true; // Can't handle indirect branch. 172fef80a29SKazushi (Jam) Marukawa } 173fef80a29SKazushi (Jam) Marukawa 174fef80a29SKazushi (Jam) Marukawa // Get the instruction before it if it is a terminator. 175fef80a29SKazushi (Jam) Marukawa MachineInstr *SecondLastInst = &*I; 176fef80a29SKazushi (Jam) Marukawa unsigned SecondLastOpc = SecondLastInst->getOpcode(); 177fef80a29SKazushi (Jam) Marukawa 178fef80a29SKazushi (Jam) Marukawa // If AllowModify is true and the block ends with two or more unconditional 179fef80a29SKazushi (Jam) Marukawa // branches, delete all but the first unconditional branch. 180fef80a29SKazushi (Jam) Marukawa if (AllowModify && isUncondBranchOpcode(LastOpc)) { 181fef80a29SKazushi (Jam) Marukawa while (isUncondBranchOpcode(SecondLastOpc)) { 182fef80a29SKazushi (Jam) Marukawa LastInst->eraseFromParent(); 183fef80a29SKazushi (Jam) Marukawa LastInst = SecondLastInst; 184fef80a29SKazushi (Jam) Marukawa LastOpc = LastInst->getOpcode(); 185fef80a29SKazushi (Jam) Marukawa if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 186fef80a29SKazushi (Jam) Marukawa // Return now the only terminator is an unconditional branch. 187fef80a29SKazushi (Jam) Marukawa TBB = LastInst->getOperand(0).getMBB(); 188fef80a29SKazushi (Jam) Marukawa return false; 189fef80a29SKazushi (Jam) Marukawa } 190fef80a29SKazushi (Jam) Marukawa SecondLastInst = &*I; 191fef80a29SKazushi (Jam) Marukawa SecondLastOpc = SecondLastInst->getOpcode(); 192fef80a29SKazushi (Jam) Marukawa } 193fef80a29SKazushi (Jam) Marukawa } 194fef80a29SKazushi (Jam) Marukawa 195fef80a29SKazushi (Jam) Marukawa // If there are three terminators, we don't know what sort of block this is. 196fef80a29SKazushi (Jam) Marukawa if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) 197fef80a29SKazushi (Jam) Marukawa return true; 198fef80a29SKazushi (Jam) Marukawa 199fef80a29SKazushi (Jam) Marukawa // If the block ends with a B and a Bcc, handle it. 200fef80a29SKazushi (Jam) Marukawa if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 201fef80a29SKazushi (Jam) Marukawa parseCondBranch(SecondLastInst, TBB, Cond); 202fef80a29SKazushi (Jam) Marukawa FBB = LastInst->getOperand(0).getMBB(); 203fef80a29SKazushi (Jam) Marukawa return false; 204fef80a29SKazushi (Jam) Marukawa } 205fef80a29SKazushi (Jam) Marukawa 206fef80a29SKazushi (Jam) Marukawa // If the block ends with two unconditional branches, handle it. The second 207fef80a29SKazushi (Jam) Marukawa // one is not executed. 208fef80a29SKazushi (Jam) Marukawa if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 209fef80a29SKazushi (Jam) Marukawa TBB = SecondLastInst->getOperand(0).getMBB(); 210fef80a29SKazushi (Jam) Marukawa return false; 211fef80a29SKazushi (Jam) Marukawa } 212fef80a29SKazushi (Jam) Marukawa 2133c80478dSKazushi (Jam) Marukawa // ...likewise if it ends with an indirect branch followed by an unconditional 214fef80a29SKazushi (Jam) Marukawa // branch. 2153c80478dSKazushi (Jam) Marukawa if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 2163c80478dSKazushi (Jam) Marukawa I = LastInst; 2173c80478dSKazushi (Jam) Marukawa if (AllowModify) 2183c80478dSKazushi (Jam) Marukawa I->eraseFromParent(); 2193c80478dSKazushi (Jam) Marukawa return true; 2203c80478dSKazushi (Jam) Marukawa } 221fef80a29SKazushi (Jam) Marukawa 222fef80a29SKazushi (Jam) Marukawa // Otherwise, can't handle this. 223fef80a29SKazushi (Jam) Marukawa return true; 224fef80a29SKazushi (Jam) Marukawa } 225fef80a29SKazushi (Jam) Marukawa 226fef80a29SKazushi (Jam) Marukawa unsigned VEInstrInfo::insertBranch(MachineBasicBlock &MBB, 227fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *TBB, 228fef80a29SKazushi (Jam) Marukawa MachineBasicBlock *FBB, 229fef80a29SKazushi (Jam) Marukawa ArrayRef<MachineOperand> Cond, 23024215fecSSimon Moll const DebugLoc &DL, int *BytesAdded) const { 231fef80a29SKazushi (Jam) Marukawa assert(TBB && "insertBranch must not be told to insert a fallthrough"); 232fef80a29SKazushi (Jam) Marukawa assert((Cond.size() == 3 || Cond.size() == 0) && 233fef80a29SKazushi (Jam) Marukawa "VE branch conditions should have three component!"); 234fef80a29SKazushi (Jam) Marukawa assert(!BytesAdded && "code size not handled"); 235fef80a29SKazushi (Jam) Marukawa if (Cond.empty()) { 236fef80a29SKazushi (Jam) Marukawa // Uncondition branch 237fef80a29SKazushi (Jam) Marukawa assert(!FBB && "Unconditional branch with multiple successors!"); 2383c80478dSKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(VE::BRCFLa_t)) 239fef80a29SKazushi (Jam) Marukawa .addMBB(TBB); 240fef80a29SKazushi (Jam) Marukawa return 1; 241fef80a29SKazushi (Jam) Marukawa } 242fef80a29SKazushi (Jam) Marukawa 243fef80a29SKazushi (Jam) Marukawa // Conditional branch 2443c80478dSKazushi (Jam) Marukawa // (BRCFir CC sy sz addr) 245fef80a29SKazushi (Jam) Marukawa assert(Cond[0].isImm() && Cond[2].isReg() && "not implemented"); 246fef80a29SKazushi (Jam) Marukawa 247fef80a29SKazushi (Jam) Marukawa unsigned opc[2]; 248fef80a29SKazushi (Jam) Marukawa const TargetRegisterInfo *TRI = &getRegisterInfo(); 249fef80a29SKazushi (Jam) Marukawa MachineFunction *MF = MBB.getParent(); 250fef80a29SKazushi (Jam) Marukawa const MachineRegisterInfo &MRI = MF->getRegInfo(); 251d6b07348SJim Lin Register Reg = Cond[2].getReg(); 252fef80a29SKazushi (Jam) Marukawa if (IsIntegerCC(Cond[0].getImm())) { 253fef80a29SKazushi (Jam) Marukawa if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 2543c80478dSKazushi (Jam) Marukawa opc[0] = VE::BRCFWir; 2553c80478dSKazushi (Jam) Marukawa opc[1] = VE::BRCFWrr; 256fef80a29SKazushi (Jam) Marukawa } else { 2573c80478dSKazushi (Jam) Marukawa opc[0] = VE::BRCFLir; 2583c80478dSKazushi (Jam) Marukawa opc[1] = VE::BRCFLrr; 259fef80a29SKazushi (Jam) Marukawa } 260fef80a29SKazushi (Jam) Marukawa } else { 261fef80a29SKazushi (Jam) Marukawa if (TRI->getRegSizeInBits(Reg, MRI) == 32) { 2623c80478dSKazushi (Jam) Marukawa opc[0] = VE::BRCFSir; 2633c80478dSKazushi (Jam) Marukawa opc[1] = VE::BRCFSrr; 264fef80a29SKazushi (Jam) Marukawa } else { 2653c80478dSKazushi (Jam) Marukawa opc[0] = VE::BRCFDir; 2663c80478dSKazushi (Jam) Marukawa opc[1] = VE::BRCFDrr; 267fef80a29SKazushi (Jam) Marukawa } 268fef80a29SKazushi (Jam) Marukawa } 269fef80a29SKazushi (Jam) Marukawa if (Cond[1].isImm()) { 270fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(opc[0])) 271fef80a29SKazushi (Jam) Marukawa .add(Cond[0]) // condition code 272fef80a29SKazushi (Jam) Marukawa .add(Cond[1]) // lhs 273fef80a29SKazushi (Jam) Marukawa .add(Cond[2]) // rhs 274fef80a29SKazushi (Jam) Marukawa .addMBB(TBB); 275fef80a29SKazushi (Jam) Marukawa } else { 276fef80a29SKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(opc[1])) 277fef80a29SKazushi (Jam) Marukawa .add(Cond[0]) 278fef80a29SKazushi (Jam) Marukawa .add(Cond[1]) 279fef80a29SKazushi (Jam) Marukawa .add(Cond[2]) 280fef80a29SKazushi (Jam) Marukawa .addMBB(TBB); 281fef80a29SKazushi (Jam) Marukawa } 282fef80a29SKazushi (Jam) Marukawa 283fef80a29SKazushi (Jam) Marukawa if (!FBB) 284fef80a29SKazushi (Jam) Marukawa return 1; 285fef80a29SKazushi (Jam) Marukawa 2863c80478dSKazushi (Jam) Marukawa BuildMI(&MBB, DL, get(VE::BRCFLa_t)) 287fef80a29SKazushi (Jam) Marukawa .addMBB(FBB); 288fef80a29SKazushi (Jam) Marukawa return 2; 289fef80a29SKazushi (Jam) Marukawa } 290fef80a29SKazushi (Jam) Marukawa 291fef80a29SKazushi (Jam) Marukawa unsigned VEInstrInfo::removeBranch(MachineBasicBlock &MBB, 292fef80a29SKazushi (Jam) Marukawa int *BytesRemoved) const { 293fef80a29SKazushi (Jam) Marukawa assert(!BytesRemoved && "code size not handled"); 294fef80a29SKazushi (Jam) Marukawa 295fef80a29SKazushi (Jam) Marukawa MachineBasicBlock::iterator I = MBB.end(); 296fef80a29SKazushi (Jam) Marukawa unsigned Count = 0; 297fef80a29SKazushi (Jam) Marukawa while (I != MBB.begin()) { 298fef80a29SKazushi (Jam) Marukawa --I; 299fef80a29SKazushi (Jam) Marukawa 300fef80a29SKazushi (Jam) Marukawa if (I->isDebugValue()) 301fef80a29SKazushi (Jam) Marukawa continue; 302fef80a29SKazushi (Jam) Marukawa 303fef80a29SKazushi (Jam) Marukawa if (!isUncondBranchOpcode(I->getOpcode()) && 304fef80a29SKazushi (Jam) Marukawa !isCondBranchOpcode(I->getOpcode())) 305fef80a29SKazushi (Jam) Marukawa break; // Not a branch 306fef80a29SKazushi (Jam) Marukawa 307fef80a29SKazushi (Jam) Marukawa I->eraseFromParent(); 308fef80a29SKazushi (Jam) Marukawa I = MBB.end(); 309fef80a29SKazushi (Jam) Marukawa ++Count; 310fef80a29SKazushi (Jam) Marukawa } 311fef80a29SKazushi (Jam) Marukawa return Count; 312fef80a29SKazushi (Jam) Marukawa } 313fef80a29SKazushi (Jam) Marukawa 314fef80a29SKazushi (Jam) Marukawa bool VEInstrInfo::reverseBranchCondition( 315fef80a29SKazushi (Jam) Marukawa SmallVectorImpl<MachineOperand> &Cond) const { 31628a42dd1SKazushi (Jam) Marukawa VECC::CondCode CC = static_cast<VECC::CondCode>(Cond[0].getImm()); 317fef80a29SKazushi (Jam) Marukawa Cond[0].setImm(GetOppositeBranchCondition(CC)); 318fef80a29SKazushi (Jam) Marukawa return false; 319fef80a29SKazushi (Jam) Marukawa } 320fef80a29SKazushi (Jam) Marukawa 3213a906a9fSKazushi (Jam) Marukawa static bool IsAliasOfSX(Register Reg) { 3222f01af76SKazushi (Jam) Marukawa return VE::I32RegClass.contains(Reg) || VE::I64RegClass.contains(Reg) || 3233a906a9fSKazushi (Jam) Marukawa VE::F32RegClass.contains(Reg); 3243a906a9fSKazushi (Jam) Marukawa } 3253a906a9fSKazushi (Jam) Marukawa 32640f1e7e8SKazushi (Jam) Marukawa static void copyPhysSubRegs(MachineBasicBlock &MBB, 32740f1e7e8SKazushi (Jam) Marukawa MachineBasicBlock::iterator I, const DebugLoc &DL, 32840f1e7e8SKazushi (Jam) Marukawa MCRegister DestReg, MCRegister SrcReg, bool KillSrc, 32940f1e7e8SKazushi (Jam) Marukawa const MCInstrDesc &MCID, unsigned int NumSubRegs, 33040f1e7e8SKazushi (Jam) Marukawa const unsigned *SubRegIdx, 33140f1e7e8SKazushi (Jam) Marukawa const TargetRegisterInfo *TRI) { 33240f1e7e8SKazushi (Jam) Marukawa MachineInstr *MovMI = nullptr; 33340f1e7e8SKazushi (Jam) Marukawa 33440f1e7e8SKazushi (Jam) Marukawa for (unsigned Idx = 0; Idx != NumSubRegs; ++Idx) { 33540f1e7e8SKazushi (Jam) Marukawa Register SubDest = TRI->getSubReg(DestReg, SubRegIdx[Idx]); 33640f1e7e8SKazushi (Jam) Marukawa Register SubSrc = TRI->getSubReg(SrcReg, SubRegIdx[Idx]); 33740f1e7e8SKazushi (Jam) Marukawa assert(SubDest && SubSrc && "Bad sub-register"); 33840f1e7e8SKazushi (Jam) Marukawa 33940f1e7e8SKazushi (Jam) Marukawa if (MCID.getOpcode() == VE::ORri) { 34040f1e7e8SKazushi (Jam) Marukawa // generate "ORri, dest, src, 0" instruction. 34140f1e7e8SKazushi (Jam) Marukawa MachineInstrBuilder MIB = 34240f1e7e8SKazushi (Jam) Marukawa BuildMI(MBB, I, DL, MCID, SubDest).addReg(SubSrc).addImm(0); 34340f1e7e8SKazushi (Jam) Marukawa MovMI = MIB.getInstr(); 344af83b74dSKazushi (Jam) Marukawa } else if (MCID.getOpcode() == VE::ANDMmm) { 345af83b74dSKazushi (Jam) Marukawa // generate "ANDM, dest, vm0, src" instruction. 346af83b74dSKazushi (Jam) Marukawa MachineInstrBuilder MIB = 347af83b74dSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, MCID, SubDest).addReg(VE::VM0).addReg(SubSrc); 348af83b74dSKazushi (Jam) Marukawa MovMI = MIB.getInstr(); 34940f1e7e8SKazushi (Jam) Marukawa } else { 35040f1e7e8SKazushi (Jam) Marukawa llvm_unreachable("Unexpected reg-to-reg copy instruction"); 35140f1e7e8SKazushi (Jam) Marukawa } 35240f1e7e8SKazushi (Jam) Marukawa } 35340f1e7e8SKazushi (Jam) Marukawa // Add implicit super-register defs and kills to the last MovMI. 35440f1e7e8SKazushi (Jam) Marukawa MovMI->addRegisterDefined(DestReg, TRI); 35540f1e7e8SKazushi (Jam) Marukawa if (KillSrc) 35640f1e7e8SKazushi (Jam) Marukawa MovMI->addRegisterKilled(SrcReg, TRI, true); 35740f1e7e8SKazushi (Jam) Marukawa } 35840f1e7e8SKazushi (Jam) Marukawa 359773ae62fSKazushi (Jam) Marukawa void VEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 360773ae62fSKazushi (Jam) Marukawa MachineBasicBlock::iterator I, const DebugLoc &DL, 361773ae62fSKazushi (Jam) Marukawa MCRegister DestReg, MCRegister SrcReg, 362773ae62fSKazushi (Jam) Marukawa bool KillSrc) const { 363773ae62fSKazushi (Jam) Marukawa 3643a906a9fSKazushi (Jam) Marukawa if (IsAliasOfSX(SrcReg) && IsAliasOfSX(DestReg)) { 365773ae62fSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::ORri), DestReg) 366773ae62fSKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(KillSrc)) 367773ae62fSKazushi (Jam) Marukawa .addImm(0); 368a598c08aSSimon Moll } else if (VE::V64RegClass.contains(DestReg, SrcReg)) { 369a598c08aSSimon Moll // Generate following instructions 370a598c08aSSimon Moll // %sw16 = LEA32zii 256 371a598c08aSSimon Moll // VORmvl %dest, (0)1, %src, %sw16 372a598c08aSSimon Moll // TODO: reuse a register if vl is already assigned to a register 373a598c08aSSimon Moll // FIXME: it would be better to scavenge a register here instead of 374a598c08aSSimon Moll // reserving SX16 all of the time. 375a598c08aSSimon Moll const TargetRegisterInfo *TRI = &getRegisterInfo(); 376a598c08aSSimon Moll Register TmpReg = VE::SX16; 377a598c08aSSimon Moll Register SubTmp = TRI->getSubReg(TmpReg, VE::sub_i32); 378a598c08aSSimon Moll BuildMI(MBB, I, DL, get(VE::LEAzii), TmpReg) 379a598c08aSSimon Moll .addImm(0) 380a598c08aSSimon Moll .addImm(0) 381a598c08aSSimon Moll .addImm(256); 382a598c08aSSimon Moll MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(VE::VORmvl), DestReg) 383a598c08aSSimon Moll .addImm(M1(0)) // Represent (0)1. 384a598c08aSSimon Moll .addReg(SrcReg, getKillRegState(KillSrc)) 385a598c08aSSimon Moll .addReg(SubTmp, getKillRegState(true)); 386a598c08aSSimon Moll MIB.getInstr()->addRegisterKilled(TmpReg, TRI, true); 387af83b74dSKazushi (Jam) Marukawa } else if (VE::VMRegClass.contains(DestReg, SrcReg)) { 388af83b74dSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::ANDMmm), DestReg) 389af83b74dSKazushi (Jam) Marukawa .addReg(VE::VM0) 390af83b74dSKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(KillSrc)); 391af83b74dSKazushi (Jam) Marukawa } else if (VE::VM512RegClass.contains(DestReg, SrcReg)) { 392af83b74dSKazushi (Jam) Marukawa // Use two instructions. 393af83b74dSKazushi (Jam) Marukawa const unsigned SubRegIdx[] = {VE::sub_vm_even, VE::sub_vm_odd}; 394af83b74dSKazushi (Jam) Marukawa unsigned int NumSubRegs = 2; 395af83b74dSKazushi (Jam) Marukawa copyPhysSubRegs(MBB, I, DL, DestReg, SrcReg, KillSrc, get(VE::ANDMmm), 396af83b74dSKazushi (Jam) Marukawa NumSubRegs, SubRegIdx, &getRegisterInfo()); 39740f1e7e8SKazushi (Jam) Marukawa } else if (VE::F128RegClass.contains(DestReg, SrcReg)) { 39840f1e7e8SKazushi (Jam) Marukawa // Use two instructions. 39940f1e7e8SKazushi (Jam) Marukawa const unsigned SubRegIdx[] = {VE::sub_even, VE::sub_odd}; 40040f1e7e8SKazushi (Jam) Marukawa unsigned int NumSubRegs = 2; 40140f1e7e8SKazushi (Jam) Marukawa copyPhysSubRegs(MBB, I, DL, DestReg, SrcReg, KillSrc, get(VE::ORri), 40240f1e7e8SKazushi (Jam) Marukawa NumSubRegs, SubRegIdx, &getRegisterInfo()); 403773ae62fSKazushi (Jam) Marukawa } else { 404773ae62fSKazushi (Jam) Marukawa const TargetRegisterInfo *TRI = &getRegisterInfo(); 405773ae62fSKazushi (Jam) Marukawa dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg, TRI) 406773ae62fSKazushi (Jam) Marukawa << " to " << printReg(DestReg, TRI) << "\n"; 407773ae62fSKazushi (Jam) Marukawa llvm_unreachable("Impossible reg-to-reg copy"); 408773ae62fSKazushi (Jam) Marukawa } 409773ae62fSKazushi (Jam) Marukawa } 410773ae62fSKazushi (Jam) Marukawa 41107c9f757SKazushi (Jam) Marukawa /// isLoadFromStackSlot - If the specified machine instruction is a direct 41207c9f757SKazushi (Jam) Marukawa /// load from a stack slot, return the virtual or physical register number of 41307c9f757SKazushi (Jam) Marukawa /// the destination along with the FrameIndex of the loaded stack slot. If 41407c9f757SKazushi (Jam) Marukawa /// not, return 0. This predicate must return 0 if the instruction has 41507c9f757SKazushi (Jam) Marukawa /// any side effects other than loading from the stack slot. 41607c9f757SKazushi (Jam) Marukawa unsigned VEInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 41707c9f757SKazushi (Jam) Marukawa int &FrameIndex) const { 418e981a46aSKazushi (Jam) Marukawa if (MI.getOpcode() == VE::LDrii || // I64 419e981a46aSKazushi (Jam) Marukawa MI.getOpcode() == VE::LDLSXrii || // I32 42040f1e7e8SKazushi (Jam) Marukawa MI.getOpcode() == VE::LDUrii || // F32 42140f1e7e8SKazushi (Jam) Marukawa MI.getOpcode() == VE::LDQrii // F128 (pseudo) 422e981a46aSKazushi (Jam) Marukawa ) { 42307c9f757SKazushi (Jam) Marukawa if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 424e981a46aSKazushi (Jam) Marukawa MI.getOperand(2).getImm() == 0 && MI.getOperand(3).isImm() && 425e981a46aSKazushi (Jam) Marukawa MI.getOperand(3).getImm() == 0) { 42607c9f757SKazushi (Jam) Marukawa FrameIndex = MI.getOperand(1).getIndex(); 42707c9f757SKazushi (Jam) Marukawa return MI.getOperand(0).getReg(); 42807c9f757SKazushi (Jam) Marukawa } 42907c9f757SKazushi (Jam) Marukawa } 43007c9f757SKazushi (Jam) Marukawa return 0; 43107c9f757SKazushi (Jam) Marukawa } 43207c9f757SKazushi (Jam) Marukawa 43307c9f757SKazushi (Jam) Marukawa /// isStoreToStackSlot - If the specified machine instruction is a direct 43407c9f757SKazushi (Jam) Marukawa /// store to a stack slot, return the virtual or physical register number of 43507c9f757SKazushi (Jam) Marukawa /// the source reg along with the FrameIndex of the loaded stack slot. If 43607c9f757SKazushi (Jam) Marukawa /// not, return 0. This predicate must return 0 if the instruction has 43707c9f757SKazushi (Jam) Marukawa /// any side effects other than storing to the stack slot. 43807c9f757SKazushi (Jam) Marukawa unsigned VEInstrInfo::isStoreToStackSlot(const MachineInstr &MI, 43907c9f757SKazushi (Jam) Marukawa int &FrameIndex) const { 440e981a46aSKazushi (Jam) Marukawa if (MI.getOpcode() == VE::STrii || // I64 441e981a46aSKazushi (Jam) Marukawa MI.getOpcode() == VE::STLrii || // I32 44240f1e7e8SKazushi (Jam) Marukawa MI.getOpcode() == VE::STUrii || // F32 44340f1e7e8SKazushi (Jam) Marukawa MI.getOpcode() == VE::STQrii // F128 (pseudo) 444e981a46aSKazushi (Jam) Marukawa ) { 44507c9f757SKazushi (Jam) Marukawa if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() && 446e981a46aSKazushi (Jam) Marukawa MI.getOperand(1).getImm() == 0 && MI.getOperand(2).isImm() && 447e981a46aSKazushi (Jam) Marukawa MI.getOperand(2).getImm() == 0) { 44807c9f757SKazushi (Jam) Marukawa FrameIndex = MI.getOperand(0).getIndex(); 449e981a46aSKazushi (Jam) Marukawa return MI.getOperand(3).getReg(); 45007c9f757SKazushi (Jam) Marukawa } 45107c9f757SKazushi (Jam) Marukawa } 45207c9f757SKazushi (Jam) Marukawa return 0; 45307c9f757SKazushi (Jam) Marukawa } 45407c9f757SKazushi (Jam) Marukawa 45507c9f757SKazushi (Jam) Marukawa void VEInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 45607c9f757SKazushi (Jam) Marukawa MachineBasicBlock::iterator I, 45707c9f757SKazushi (Jam) Marukawa Register SrcReg, bool isKill, int FI, 45807c9f757SKazushi (Jam) Marukawa const TargetRegisterClass *RC, 45907c9f757SKazushi (Jam) Marukawa const TargetRegisterInfo *TRI) const { 46007c9f757SKazushi (Jam) Marukawa DebugLoc DL; 46107c9f757SKazushi (Jam) Marukawa if (I != MBB.end()) 46207c9f757SKazushi (Jam) Marukawa DL = I->getDebugLoc(); 46307c9f757SKazushi (Jam) Marukawa 46407c9f757SKazushi (Jam) Marukawa MachineFunction *MF = MBB.getParent(); 46507c9f757SKazushi (Jam) Marukawa const MachineFrameInfo &MFI = MF->getFrameInfo(); 46607c9f757SKazushi (Jam) Marukawa MachineMemOperand *MMO = MF->getMachineMemOperand( 46707c9f757SKazushi (Jam) Marukawa MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, 468624654fdSFangrui Song MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 46907c9f757SKazushi (Jam) Marukawa 47007c9f757SKazushi (Jam) Marukawa // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 47107c9f757SKazushi (Jam) Marukawa if (RC == &VE::I64RegClass) { 472e981a46aSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::STrii)) 47307c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 47407c9f757SKazushi (Jam) Marukawa .addImm(0) 475e981a46aSKazushi (Jam) Marukawa .addImm(0) 47607c9f757SKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(isKill)) 47707c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 47807c9f757SKazushi (Jam) Marukawa } else if (RC == &VE::I32RegClass) { 479e981a46aSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::STLrii)) 48007c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 48107c9f757SKazushi (Jam) Marukawa .addImm(0) 482e981a46aSKazushi (Jam) Marukawa .addImm(0) 48307c9f757SKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(isKill)) 48407c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 48507c9f757SKazushi (Jam) Marukawa } else if (RC == &VE::F32RegClass) { 486e981a46aSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::STUrii)) 48707c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 48807c9f757SKazushi (Jam) Marukawa .addImm(0) 489e981a46aSKazushi (Jam) Marukawa .addImm(0) 49007c9f757SKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(isKill)) 49107c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 49240f1e7e8SKazushi (Jam) Marukawa } else if (VE::F128RegClass.hasSubClassEq(RC)) { 49340f1e7e8SKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::STQrii)) 49440f1e7e8SKazushi (Jam) Marukawa .addFrameIndex(FI) 49540f1e7e8SKazushi (Jam) Marukawa .addImm(0) 49640f1e7e8SKazushi (Jam) Marukawa .addImm(0) 49740f1e7e8SKazushi (Jam) Marukawa .addReg(SrcReg, getKillRegState(isKill)) 49840f1e7e8SKazushi (Jam) Marukawa .addMemOperand(MMO); 49907c9f757SKazushi (Jam) Marukawa } else 50007c9f757SKazushi (Jam) Marukawa report_fatal_error("Can't store this register to stack slot"); 50107c9f757SKazushi (Jam) Marukawa } 50207c9f757SKazushi (Jam) Marukawa 50307c9f757SKazushi (Jam) Marukawa void VEInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 50407c9f757SKazushi (Jam) Marukawa MachineBasicBlock::iterator I, 50507c9f757SKazushi (Jam) Marukawa Register DestReg, int FI, 50607c9f757SKazushi (Jam) Marukawa const TargetRegisterClass *RC, 50707c9f757SKazushi (Jam) Marukawa const TargetRegisterInfo *TRI) const { 50807c9f757SKazushi (Jam) Marukawa DebugLoc DL; 50907c9f757SKazushi (Jam) Marukawa if (I != MBB.end()) 51007c9f757SKazushi (Jam) Marukawa DL = I->getDebugLoc(); 51107c9f757SKazushi (Jam) Marukawa 51207c9f757SKazushi (Jam) Marukawa MachineFunction *MF = MBB.getParent(); 51307c9f757SKazushi (Jam) Marukawa const MachineFrameInfo &MFI = MF->getFrameInfo(); 51407c9f757SKazushi (Jam) Marukawa MachineMemOperand *MMO = MF->getMachineMemOperand( 51507c9f757SKazushi (Jam) Marukawa MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, 516624654fdSFangrui Song MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 51707c9f757SKazushi (Jam) Marukawa 51807c9f757SKazushi (Jam) Marukawa if (RC == &VE::I64RegClass) { 519e981a46aSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::LDrii), DestReg) 52007c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 52107c9f757SKazushi (Jam) Marukawa .addImm(0) 522e981a46aSKazushi (Jam) Marukawa .addImm(0) 52307c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 52407c9f757SKazushi (Jam) Marukawa } else if (RC == &VE::I32RegClass) { 525e981a46aSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::LDLSXrii), DestReg) 52607c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 52707c9f757SKazushi (Jam) Marukawa .addImm(0) 528e981a46aSKazushi (Jam) Marukawa .addImm(0) 52907c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 53007c9f757SKazushi (Jam) Marukawa } else if (RC == &VE::F32RegClass) { 531e981a46aSKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::LDUrii), DestReg) 53207c9f757SKazushi (Jam) Marukawa .addFrameIndex(FI) 53307c9f757SKazushi (Jam) Marukawa .addImm(0) 534e981a46aSKazushi (Jam) Marukawa .addImm(0) 53507c9f757SKazushi (Jam) Marukawa .addMemOperand(MMO); 53640f1e7e8SKazushi (Jam) Marukawa } else if (VE::F128RegClass.hasSubClassEq(RC)) { 53740f1e7e8SKazushi (Jam) Marukawa BuildMI(MBB, I, DL, get(VE::LDQrii), DestReg) 53840f1e7e8SKazushi (Jam) Marukawa .addFrameIndex(FI) 53940f1e7e8SKazushi (Jam) Marukawa .addImm(0) 54040f1e7e8SKazushi (Jam) Marukawa .addImm(0) 54140f1e7e8SKazushi (Jam) Marukawa .addMemOperand(MMO); 54207c9f757SKazushi (Jam) Marukawa } else 54307c9f757SKazushi (Jam) Marukawa report_fatal_error("Can't load this register from stack slot"); 54407c9f757SKazushi (Jam) Marukawa } 54507c9f757SKazushi (Jam) Marukawa 546dd6f607eSKazushi (Jam) Marukawa bool VEInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, 547dd6f607eSKazushi (Jam) Marukawa Register Reg, MachineRegisterInfo *MRI) const { 548dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(dbgs() << "FoldImmediate\n"); 549dd6f607eSKazushi (Jam) Marukawa 550dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(dbgs() << "checking DefMI\n"); 551dd6f607eSKazushi (Jam) Marukawa int64_t ImmVal; 552dd6f607eSKazushi (Jam) Marukawa switch (DefMI.getOpcode()) { 553dd6f607eSKazushi (Jam) Marukawa default: 554dd6f607eSKazushi (Jam) Marukawa return false; 555dd6f607eSKazushi (Jam) Marukawa case VE::ORim: 556dd6f607eSKazushi (Jam) Marukawa // General move small immediate instruction on VE. 557dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(dbgs() << "checking ORim\n"); 558dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(DefMI.dump()); 559dd6f607eSKazushi (Jam) Marukawa // FIXME: We may need to support FPImm too. 560dd6f607eSKazushi (Jam) Marukawa assert(DefMI.getOperand(1).isImm()); 561dd6f607eSKazushi (Jam) Marukawa assert(DefMI.getOperand(2).isImm()); 562dd6f607eSKazushi (Jam) Marukawa ImmVal = 563dd6f607eSKazushi (Jam) Marukawa DefMI.getOperand(1).getImm() + mimm2Val(DefMI.getOperand(2).getImm()); 564dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(dbgs() << "ImmVal is " << ImmVal << "\n"); 565dd6f607eSKazushi (Jam) Marukawa break; 566dd6f607eSKazushi (Jam) Marukawa case VE::LEAzii: 567dd6f607eSKazushi (Jam) Marukawa // General move immediate instruction on VE. 568dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(dbgs() << "checking LEAzii\n"); 569dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(DefMI.dump()); 570dd6f607eSKazushi (Jam) Marukawa // FIXME: We may need to support FPImm too. 571dd6f607eSKazushi (Jam) Marukawa assert(DefMI.getOperand(2).isImm()); 572dd6f607eSKazushi (Jam) Marukawa if (!DefMI.getOperand(3).isImm()) 573dd6f607eSKazushi (Jam) Marukawa // LEAzii may refer label 574dd6f607eSKazushi (Jam) Marukawa return false; 575dd6f607eSKazushi (Jam) Marukawa ImmVal = DefMI.getOperand(2).getImm() + DefMI.getOperand(3).getImm(); 576dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(dbgs() << "ImmVal is " << ImmVal << "\n"); 577dd6f607eSKazushi (Jam) Marukawa break; 578dd6f607eSKazushi (Jam) Marukawa } 579dd6f607eSKazushi (Jam) Marukawa 580dd6f607eSKazushi (Jam) Marukawa // Try to fold like below: 581dd6f607eSKazushi (Jam) Marukawa // %1:i64 = ORim 0, 0(1) 582dd6f607eSKazushi (Jam) Marukawa // %2:i64 = CMPSLrr %0, %1 583dd6f607eSKazushi (Jam) Marukawa // To 584dd6f607eSKazushi (Jam) Marukawa // %2:i64 = CMPSLrm %0, 0(1) 585dd6f607eSKazushi (Jam) Marukawa // 586dd6f607eSKazushi (Jam) Marukawa // Another example: 587dd6f607eSKazushi (Jam) Marukawa // %1:i64 = ORim 6, 0(1) 588dd6f607eSKazushi (Jam) Marukawa // %2:i64 = CMPSLrr %1, %0 589dd6f607eSKazushi (Jam) Marukawa // To 590dd6f607eSKazushi (Jam) Marukawa // %2:i64 = CMPSLir 6, %0 591dd6f607eSKazushi (Jam) Marukawa // 592dd6f607eSKazushi (Jam) Marukawa // Support commutable instructions like below: 593dd6f607eSKazushi (Jam) Marukawa // %1:i64 = ORim 6, 0(1) 594dd6f607eSKazushi (Jam) Marukawa // %2:i64 = ADDSLrr %1, %0 595dd6f607eSKazushi (Jam) Marukawa // To 596dd6f607eSKazushi (Jam) Marukawa // %2:i64 = ADDSLri %0, 6 597dd6f607eSKazushi (Jam) Marukawa // 598dd6f607eSKazushi (Jam) Marukawa // FIXME: Need to support i32. Current implementtation requires 599dd6f607eSKazushi (Jam) Marukawa // EXTRACT_SUBREG, so input has following COPY and it avoids folding: 600dd6f607eSKazushi (Jam) Marukawa // %1:i64 = ORim 6, 0(1) 601dd6f607eSKazushi (Jam) Marukawa // %2:i32 = COPY %1.sub_i32 602dd6f607eSKazushi (Jam) Marukawa // %3:i32 = ADDSWSXrr %0, %2 603dd6f607eSKazushi (Jam) Marukawa // FIXME: Need to support shift, cmov, and more instructions. 604dd6f607eSKazushi (Jam) Marukawa // FIXME: Need to support lvl too, but LVLGen runs after peephole-opt. 605dd6f607eSKazushi (Jam) Marukawa 606dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(dbgs() << "checking UseMI\n"); 607dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(UseMI.dump()); 608dd6f607eSKazushi (Jam) Marukawa unsigned NewUseOpcSImm7; 609dd6f607eSKazushi (Jam) Marukawa unsigned NewUseOpcMImm; 610dd6f607eSKazushi (Jam) Marukawa enum InstType { 611dd6f607eSKazushi (Jam) Marukawa rr2ri_rm, // rr -> ri or rm, commutable 612dd6f607eSKazushi (Jam) Marukawa rr2ir_rm, // rr -> ir or rm 613dd6f607eSKazushi (Jam) Marukawa } InstType; 614dd6f607eSKazushi (Jam) Marukawa 615dd6f607eSKazushi (Jam) Marukawa using namespace llvm::VE; 616dd6f607eSKazushi (Jam) Marukawa #define INSTRKIND(NAME) \ 617dd6f607eSKazushi (Jam) Marukawa case NAME##rr: \ 618dd6f607eSKazushi (Jam) Marukawa NewUseOpcSImm7 = NAME##ri; \ 619dd6f607eSKazushi (Jam) Marukawa NewUseOpcMImm = NAME##rm; \ 620dd6f607eSKazushi (Jam) Marukawa InstType = rr2ri_rm; \ 621dd6f607eSKazushi (Jam) Marukawa break 622dd6f607eSKazushi (Jam) Marukawa #define NCINSTRKIND(NAME) \ 623dd6f607eSKazushi (Jam) Marukawa case NAME##rr: \ 624dd6f607eSKazushi (Jam) Marukawa NewUseOpcSImm7 = NAME##ir; \ 625dd6f607eSKazushi (Jam) Marukawa NewUseOpcMImm = NAME##rm; \ 626dd6f607eSKazushi (Jam) Marukawa InstType = rr2ir_rm; \ 627dd6f607eSKazushi (Jam) Marukawa break 628dd6f607eSKazushi (Jam) Marukawa 629dd6f607eSKazushi (Jam) Marukawa switch (UseMI.getOpcode()) { 630dd6f607eSKazushi (Jam) Marukawa default: 631dd6f607eSKazushi (Jam) Marukawa return false; 632dd6f607eSKazushi (Jam) Marukawa 633dd6f607eSKazushi (Jam) Marukawa INSTRKIND(ADDUL); 634dd6f607eSKazushi (Jam) Marukawa INSTRKIND(ADDSWSX); 635dd6f607eSKazushi (Jam) Marukawa INSTRKIND(ADDSWZX); 636dd6f607eSKazushi (Jam) Marukawa INSTRKIND(ADDSL); 637dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(SUBUL); 638dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(SUBSWSX); 639dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(SUBSWZX); 640dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(SUBSL); 641dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MULUL); 642dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MULSWSX); 643dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MULSWZX); 644dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MULSL); 645dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(DIVUL); 646dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(DIVSWSX); 647dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(DIVSWZX); 648dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(DIVSL); 649dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(CMPUL); 650dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(CMPSWSX); 651dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(CMPSWZX); 652dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(CMPSL); 653dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MAXSWSX); 654dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MAXSWZX); 655dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MAXSL); 656dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MINSWSX); 657dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MINSWZX); 658dd6f607eSKazushi (Jam) Marukawa INSTRKIND(MINSL); 659dd6f607eSKazushi (Jam) Marukawa INSTRKIND(AND); 660dd6f607eSKazushi (Jam) Marukawa INSTRKIND(OR); 661dd6f607eSKazushi (Jam) Marukawa INSTRKIND(XOR); 662dd6f607eSKazushi (Jam) Marukawa INSTRKIND(EQV); 663dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(NND); 664dd6f607eSKazushi (Jam) Marukawa NCINSTRKIND(MRG); 665dd6f607eSKazushi (Jam) Marukawa } 666dd6f607eSKazushi (Jam) Marukawa 667dd6f607eSKazushi (Jam) Marukawa #undef INSTRKIND 668dd6f607eSKazushi (Jam) Marukawa 669dd6f607eSKazushi (Jam) Marukawa unsigned NewUseOpc; 670dd6f607eSKazushi (Jam) Marukawa unsigned UseIdx; 671dd6f607eSKazushi (Jam) Marukawa bool Commute = false; 672dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(dbgs() << "checking UseMI operands\n"); 673dd6f607eSKazushi (Jam) Marukawa switch (InstType) { 674dd6f607eSKazushi (Jam) Marukawa case rr2ri_rm: 675dd6f607eSKazushi (Jam) Marukawa UseIdx = 2; 676dd6f607eSKazushi (Jam) Marukawa if (UseMI.getOperand(1).getReg() == Reg) { 677dd6f607eSKazushi (Jam) Marukawa Commute = true; 678dd6f607eSKazushi (Jam) Marukawa } else { 679dd6f607eSKazushi (Jam) Marukawa assert(UseMI.getOperand(2).getReg() == Reg); 680dd6f607eSKazushi (Jam) Marukawa } 681dd6f607eSKazushi (Jam) Marukawa if (isInt<7>(ImmVal)) { 682dd6f607eSKazushi (Jam) Marukawa // This ImmVal matches to SImm7 slot, so change UseOpc to an instruction 683dd6f607eSKazushi (Jam) Marukawa // holds a simm7 slot. 684dd6f607eSKazushi (Jam) Marukawa NewUseOpc = NewUseOpcSImm7; 685dd6f607eSKazushi (Jam) Marukawa } else if (isMImmVal(ImmVal)) { 686dd6f607eSKazushi (Jam) Marukawa // Similarly, change UseOpc to an instruction holds a mimm slot. 687dd6f607eSKazushi (Jam) Marukawa NewUseOpc = NewUseOpcMImm; 688dd6f607eSKazushi (Jam) Marukawa ImmVal = val2MImm(ImmVal); 689dd6f607eSKazushi (Jam) Marukawa } else 690dd6f607eSKazushi (Jam) Marukawa return false; 691dd6f607eSKazushi (Jam) Marukawa break; 692dd6f607eSKazushi (Jam) Marukawa case rr2ir_rm: 693dd6f607eSKazushi (Jam) Marukawa if (UseMI.getOperand(1).getReg() == Reg) { 694dd6f607eSKazushi (Jam) Marukawa // Check immediate value whether it matchs to the UseMI instruction. 695dd6f607eSKazushi (Jam) Marukawa if (!isInt<7>(ImmVal)) 696dd6f607eSKazushi (Jam) Marukawa return false; 697dd6f607eSKazushi (Jam) Marukawa NewUseOpc = NewUseOpcSImm7; 698dd6f607eSKazushi (Jam) Marukawa UseIdx = 1; 699dd6f607eSKazushi (Jam) Marukawa } else { 700dd6f607eSKazushi (Jam) Marukawa assert(UseMI.getOperand(2).getReg() == Reg); 701dd6f607eSKazushi (Jam) Marukawa // Check immediate value whether it matchs to the UseMI instruction. 702dd6f607eSKazushi (Jam) Marukawa if (!isMImmVal(ImmVal)) 703dd6f607eSKazushi (Jam) Marukawa return false; 704dd6f607eSKazushi (Jam) Marukawa NewUseOpc = NewUseOpcMImm; 705dd6f607eSKazushi (Jam) Marukawa ImmVal = val2MImm(ImmVal); 706dd6f607eSKazushi (Jam) Marukawa UseIdx = 2; 707dd6f607eSKazushi (Jam) Marukawa } 708dd6f607eSKazushi (Jam) Marukawa break; 709dd6f607eSKazushi (Jam) Marukawa } 710dd6f607eSKazushi (Jam) Marukawa 711dd6f607eSKazushi (Jam) Marukawa LLVM_DEBUG(dbgs() << "modifying UseMI\n"); 712dd6f607eSKazushi (Jam) Marukawa bool DeleteDef = MRI->hasOneNonDBGUse(Reg); 713dd6f607eSKazushi (Jam) Marukawa UseMI.setDesc(get(NewUseOpc)); 714dd6f607eSKazushi (Jam) Marukawa if (Commute) { 715dd6f607eSKazushi (Jam) Marukawa UseMI.getOperand(1).setReg(UseMI.getOperand(UseIdx).getReg()); 716dd6f607eSKazushi (Jam) Marukawa } 717dd6f607eSKazushi (Jam) Marukawa UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal); 718dd6f607eSKazushi (Jam) Marukawa if (DeleteDef) 719dd6f607eSKazushi (Jam) Marukawa DefMI.eraseFromParent(); 720dd6f607eSKazushi (Jam) Marukawa 721dd6f607eSKazushi (Jam) Marukawa return true; 722dd6f607eSKazushi (Jam) Marukawa } 723dd6f607eSKazushi (Jam) Marukawa 72460431bd7SKazushi (Jam) Marukawa Register VEInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 72560431bd7SKazushi (Jam) Marukawa VEMachineFunctionInfo *VEFI = MF->getInfo<VEMachineFunctionInfo>(); 72660431bd7SKazushi (Jam) Marukawa Register GlobalBaseReg = VEFI->getGlobalBaseReg(); 72760431bd7SKazushi (Jam) Marukawa if (GlobalBaseReg != 0) 72860431bd7SKazushi (Jam) Marukawa return GlobalBaseReg; 72960431bd7SKazushi (Jam) Marukawa 73060431bd7SKazushi (Jam) Marukawa // We use %s15 (%got) as a global base register 73160431bd7SKazushi (Jam) Marukawa GlobalBaseReg = VE::SX15; 73260431bd7SKazushi (Jam) Marukawa 73360431bd7SKazushi (Jam) Marukawa // Insert a pseudo instruction to set the GlobalBaseReg into the first 73460431bd7SKazushi (Jam) Marukawa // MBB of the function 73560431bd7SKazushi (Jam) Marukawa MachineBasicBlock &FirstMBB = MF->front(); 73660431bd7SKazushi (Jam) Marukawa MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 73760431bd7SKazushi (Jam) Marukawa DebugLoc dl; 73860431bd7SKazushi (Jam) Marukawa BuildMI(FirstMBB, MBBI, dl, get(VE::GETGOT), GlobalBaseReg); 73960431bd7SKazushi (Jam) Marukawa VEFI->setGlobalBaseReg(GlobalBaseReg); 74060431bd7SKazushi (Jam) Marukawa return GlobalBaseReg; 74160431bd7SKazushi (Jam) Marukawa } 74260431bd7SKazushi (Jam) Marukawa 74338621c45SKazushi (Jam) Marukawa static Register getVM512Upper(Register reg) { 74438621c45SKazushi (Jam) Marukawa return (reg - VE::VMP0) * 2 + VE::VM0; 74538621c45SKazushi (Jam) Marukawa } 74638621c45SKazushi (Jam) Marukawa 74738621c45SKazushi (Jam) Marukawa static Register getVM512Lower(Register reg) { return getVM512Upper(reg) + 1; } 74838621c45SKazushi (Jam) Marukawa 749aefedb17SKazushi (Jam) Marukawa // Expand pseudo logical vector instructions for VM512 registers. 750aefedb17SKazushi (Jam) Marukawa static void expandPseudoLogM(MachineInstr &MI, const MCInstrDesc &MCID) { 751aefedb17SKazushi (Jam) Marukawa MachineBasicBlock *MBB = MI.getParent(); 752aefedb17SKazushi (Jam) Marukawa DebugLoc DL = MI.getDebugLoc(); 753aefedb17SKazushi (Jam) Marukawa 754aefedb17SKazushi (Jam) Marukawa Register VMXu = getVM512Upper(MI.getOperand(0).getReg()); 755aefedb17SKazushi (Jam) Marukawa Register VMXl = getVM512Lower(MI.getOperand(0).getReg()); 756aefedb17SKazushi (Jam) Marukawa Register VMYu = getVM512Upper(MI.getOperand(1).getReg()); 757aefedb17SKazushi (Jam) Marukawa Register VMYl = getVM512Lower(MI.getOperand(1).getReg()); 758aefedb17SKazushi (Jam) Marukawa 759aefedb17SKazushi (Jam) Marukawa switch (MI.getOpcode()) { 760aefedb17SKazushi (Jam) Marukawa default: { 761aefedb17SKazushi (Jam) Marukawa Register VMZu = getVM512Upper(MI.getOperand(2).getReg()); 762aefedb17SKazushi (Jam) Marukawa Register VMZl = getVM512Lower(MI.getOperand(2).getReg()); 763aefedb17SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, MCID).addDef(VMXu).addUse(VMYu).addUse(VMZu); 764aefedb17SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, MCID).addDef(VMXl).addUse(VMYl).addUse(VMZl); 765aefedb17SKazushi (Jam) Marukawa break; 766aefedb17SKazushi (Jam) Marukawa } 767aefedb17SKazushi (Jam) Marukawa case VE::NEGMy: 768aefedb17SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, MCID).addDef(VMXu).addUse(VMYu); 769aefedb17SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, MCID).addDef(VMXl).addUse(VMYl); 770aefedb17SKazushi (Jam) Marukawa break; 771aefedb17SKazushi (Jam) Marukawa } 772aefedb17SKazushi (Jam) Marukawa MI.eraseFromParent(); 773aefedb17SKazushi (Jam) Marukawa } 774aefedb17SKazushi (Jam) Marukawa 775398f29fbSKazushi (Jam) Marukawa static void addOperandsForVFMK(MachineInstrBuilder &MIB, MachineInstr &MI, 776398f29fbSKazushi (Jam) Marukawa bool Upper) { 777398f29fbSKazushi (Jam) Marukawa // VM512 778398f29fbSKazushi (Jam) Marukawa MIB.addReg(Upper ? getVM512Upper(MI.getOperand(0).getReg()) 779398f29fbSKazushi (Jam) Marukawa : getVM512Lower(MI.getOperand(0).getReg())); 780398f29fbSKazushi (Jam) Marukawa 781398f29fbSKazushi (Jam) Marukawa switch (MI.getNumExplicitOperands()) { 782398f29fbSKazushi (Jam) Marukawa default: 783398f29fbSKazushi (Jam) Marukawa report_fatal_error("unexpected number of operands for pvfmk"); 784398f29fbSKazushi (Jam) Marukawa case 2: // _Ml: VM512, VL 785398f29fbSKazushi (Jam) Marukawa // VL 786398f29fbSKazushi (Jam) Marukawa MIB.addReg(MI.getOperand(1).getReg()); 787398f29fbSKazushi (Jam) Marukawa break; 788398f29fbSKazushi (Jam) Marukawa case 4: // _Mvl: VM512, CC, VR, VL 789398f29fbSKazushi (Jam) Marukawa // CC 790398f29fbSKazushi (Jam) Marukawa MIB.addImm(MI.getOperand(1).getImm()); 791398f29fbSKazushi (Jam) Marukawa // VR 792398f29fbSKazushi (Jam) Marukawa MIB.addReg(MI.getOperand(2).getReg()); 793398f29fbSKazushi (Jam) Marukawa // VL 794398f29fbSKazushi (Jam) Marukawa MIB.addReg(MI.getOperand(3).getReg()); 795398f29fbSKazushi (Jam) Marukawa break; 796398f29fbSKazushi (Jam) Marukawa case 5: // _MvMl: VM512, CC, VR, VM512, VL 797398f29fbSKazushi (Jam) Marukawa // CC 798398f29fbSKazushi (Jam) Marukawa MIB.addImm(MI.getOperand(1).getImm()); 799398f29fbSKazushi (Jam) Marukawa // VR 800398f29fbSKazushi (Jam) Marukawa MIB.addReg(MI.getOperand(2).getReg()); 801398f29fbSKazushi (Jam) Marukawa // VM512 802398f29fbSKazushi (Jam) Marukawa MIB.addReg(Upper ? getVM512Upper(MI.getOperand(3).getReg()) 803398f29fbSKazushi (Jam) Marukawa : getVM512Lower(MI.getOperand(3).getReg())); 804398f29fbSKazushi (Jam) Marukawa // VL 805398f29fbSKazushi (Jam) Marukawa MIB.addReg(MI.getOperand(4).getReg()); 806398f29fbSKazushi (Jam) Marukawa break; 807398f29fbSKazushi (Jam) Marukawa } 808398f29fbSKazushi (Jam) Marukawa } 809398f29fbSKazushi (Jam) Marukawa 810398f29fbSKazushi (Jam) Marukawa static void expandPseudoVFMK(const TargetInstrInfo &TI, MachineInstr &MI) { 811398f29fbSKazushi (Jam) Marukawa // replace to pvfmk.w.up and pvfmk.w.lo 812398f29fbSKazushi (Jam) Marukawa // replace to pvfmk.s.up and pvfmk.s.lo 813398f29fbSKazushi (Jam) Marukawa 814*fbce4a78SBenjamin Kramer static const std::pair<unsigned, std::pair<unsigned, unsigned>> VFMKMap[] = { 815398f29fbSKazushi (Jam) Marukawa {VE::VFMKyal, {VE::VFMKLal, VE::VFMKLal}}, 816398f29fbSKazushi (Jam) Marukawa {VE::VFMKynal, {VE::VFMKLnal, VE::VFMKLnal}}, 817398f29fbSKazushi (Jam) Marukawa {VE::VFMKWyvl, {VE::PVFMKWUPvl, VE::PVFMKWLOvl}}, 818398f29fbSKazushi (Jam) Marukawa {VE::VFMKWyvyl, {VE::PVFMKWUPvml, VE::PVFMKWLOvml}}, 819398f29fbSKazushi (Jam) Marukawa {VE::VFMKSyvl, {VE::PVFMKSUPvl, VE::PVFMKSLOvl}}, 820398f29fbSKazushi (Jam) Marukawa {VE::VFMKSyvyl, {VE::PVFMKSUPvml, VE::PVFMKSLOvml}}, 821398f29fbSKazushi (Jam) Marukawa }; 822398f29fbSKazushi (Jam) Marukawa 823398f29fbSKazushi (Jam) Marukawa unsigned Opcode = MI.getOpcode(); 824398f29fbSKazushi (Jam) Marukawa 825*fbce4a78SBenjamin Kramer const auto *Found = 826*fbce4a78SBenjamin Kramer llvm::find_if(VFMKMap, [&](auto P) { return P.first == Opcode; }); 827*fbce4a78SBenjamin Kramer if (Found == std::end(VFMKMap)) 828398f29fbSKazushi (Jam) Marukawa report_fatal_error("unexpected opcode for pseudo vfmk"); 829398f29fbSKazushi (Jam) Marukawa 830398f29fbSKazushi (Jam) Marukawa unsigned OpcodeUpper = (*Found).second.first; 831398f29fbSKazushi (Jam) Marukawa unsigned OpcodeLower = (*Found).second.second; 832398f29fbSKazushi (Jam) Marukawa 833398f29fbSKazushi (Jam) Marukawa MachineBasicBlock *MBB = MI.getParent(); 834398f29fbSKazushi (Jam) Marukawa DebugLoc DL = MI.getDebugLoc(); 835398f29fbSKazushi (Jam) Marukawa 836398f29fbSKazushi (Jam) Marukawa MachineInstrBuilder Bu = BuildMI(*MBB, MI, DL, TI.get(OpcodeUpper)); 837398f29fbSKazushi (Jam) Marukawa addOperandsForVFMK(Bu, MI, /* Upper */ true); 838398f29fbSKazushi (Jam) Marukawa MachineInstrBuilder Bl = BuildMI(*MBB, MI, DL, TI.get(OpcodeLower)); 839398f29fbSKazushi (Jam) Marukawa addOperandsForVFMK(Bl, MI, /* Upper */ false); 840398f29fbSKazushi (Jam) Marukawa 841398f29fbSKazushi (Jam) Marukawa MI.eraseFromParent(); 842398f29fbSKazushi (Jam) Marukawa } 843398f29fbSKazushi (Jam) Marukawa 844064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 845064859bdSKazushi (Jam) Marukawa switch (MI.getOpcode()) { 846064859bdSKazushi (Jam) Marukawa case VE::EXTEND_STACK: { 847064859bdSKazushi (Jam) Marukawa return expandExtendStackPseudo(MI); 848064859bdSKazushi (Jam) Marukawa } 849064859bdSKazushi (Jam) Marukawa case VE::EXTEND_STACK_GUARD: { 850064859bdSKazushi (Jam) Marukawa MI.eraseFromParent(); // The pseudo instruction is gone now. 851064859bdSKazushi (Jam) Marukawa return true; 852064859bdSKazushi (Jam) Marukawa } 853dedaf3a2SKazushi (Jam) Marukawa case VE::GETSTACKTOP: { 854dedaf3a2SKazushi (Jam) Marukawa return expandGetStackTopPseudo(MI); 855dedaf3a2SKazushi (Jam) Marukawa } 85638621c45SKazushi (Jam) Marukawa 857aefedb17SKazushi (Jam) Marukawa case VE::ANDMyy: 858aefedb17SKazushi (Jam) Marukawa expandPseudoLogM(MI, get(VE::ANDMmm)); 859aefedb17SKazushi (Jam) Marukawa return true; 860aefedb17SKazushi (Jam) Marukawa case VE::ORMyy: 861aefedb17SKazushi (Jam) Marukawa expandPseudoLogM(MI, get(VE::ORMmm)); 862aefedb17SKazushi (Jam) Marukawa return true; 863aefedb17SKazushi (Jam) Marukawa case VE::XORMyy: 864aefedb17SKazushi (Jam) Marukawa expandPseudoLogM(MI, get(VE::XORMmm)); 865aefedb17SKazushi (Jam) Marukawa return true; 866aefedb17SKazushi (Jam) Marukawa case VE::EQVMyy: 867aefedb17SKazushi (Jam) Marukawa expandPseudoLogM(MI, get(VE::EQVMmm)); 868aefedb17SKazushi (Jam) Marukawa return true; 869aefedb17SKazushi (Jam) Marukawa case VE::NNDMyy: 870aefedb17SKazushi (Jam) Marukawa expandPseudoLogM(MI, get(VE::NNDMmm)); 871aefedb17SKazushi (Jam) Marukawa return true; 872aefedb17SKazushi (Jam) Marukawa case VE::NEGMy: 873aefedb17SKazushi (Jam) Marukawa expandPseudoLogM(MI, get(VE::NEGMm)); 874aefedb17SKazushi (Jam) Marukawa return true; 875aefedb17SKazushi (Jam) Marukawa 87638621c45SKazushi (Jam) Marukawa case VE::LVMyir: 87738621c45SKazushi (Jam) Marukawa case VE::LVMyim: 87838621c45SKazushi (Jam) Marukawa case VE::LVMyir_y: 87938621c45SKazushi (Jam) Marukawa case VE::LVMyim_y: { 88038621c45SKazushi (Jam) Marukawa Register VMXu = getVM512Upper(MI.getOperand(0).getReg()); 88138621c45SKazushi (Jam) Marukawa Register VMXl = getVM512Lower(MI.getOperand(0).getReg()); 88238621c45SKazushi (Jam) Marukawa int64_t Imm = MI.getOperand(1).getImm(); 88338621c45SKazushi (Jam) Marukawa bool IsSrcReg = 88438621c45SKazushi (Jam) Marukawa MI.getOpcode() == VE::LVMyir || MI.getOpcode() == VE::LVMyir_y; 88538621c45SKazushi (Jam) Marukawa Register Src = IsSrcReg ? MI.getOperand(2).getReg() : VE::NoRegister; 88638621c45SKazushi (Jam) Marukawa int64_t MImm = IsSrcReg ? 0 : MI.getOperand(2).getImm(); 88738621c45SKazushi (Jam) Marukawa bool KillSrc = IsSrcReg ? MI.getOperand(2).isKill() : false; 88838621c45SKazushi (Jam) Marukawa Register VMX = VMXl; 88938621c45SKazushi (Jam) Marukawa if (Imm >= 4) { 89038621c45SKazushi (Jam) Marukawa VMX = VMXu; 89138621c45SKazushi (Jam) Marukawa Imm -= 4; 89238621c45SKazushi (Jam) Marukawa } 89338621c45SKazushi (Jam) Marukawa MachineBasicBlock *MBB = MI.getParent(); 89438621c45SKazushi (Jam) Marukawa DebugLoc DL = MI.getDebugLoc(); 89538621c45SKazushi (Jam) Marukawa switch (MI.getOpcode()) { 89638621c45SKazushi (Jam) Marukawa case VE::LVMyir: 89738621c45SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, get(VE::LVMir)) 89838621c45SKazushi (Jam) Marukawa .addDef(VMX) 89938621c45SKazushi (Jam) Marukawa .addImm(Imm) 90038621c45SKazushi (Jam) Marukawa .addReg(Src, getKillRegState(KillSrc)); 90138621c45SKazushi (Jam) Marukawa break; 90238621c45SKazushi (Jam) Marukawa case VE::LVMyim: 90338621c45SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, get(VE::LVMim)) 90438621c45SKazushi (Jam) Marukawa .addDef(VMX) 90538621c45SKazushi (Jam) Marukawa .addImm(Imm) 90638621c45SKazushi (Jam) Marukawa .addImm(MImm); 90738621c45SKazushi (Jam) Marukawa break; 90838621c45SKazushi (Jam) Marukawa case VE::LVMyir_y: 90938621c45SKazushi (Jam) Marukawa assert(MI.getOperand(0).getReg() == MI.getOperand(3).getReg() && 91038621c45SKazushi (Jam) Marukawa "LVMyir_y has different register in 3rd operand"); 91138621c45SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, get(VE::LVMir_m)) 91238621c45SKazushi (Jam) Marukawa .addDef(VMX) 91338621c45SKazushi (Jam) Marukawa .addImm(Imm) 91438621c45SKazushi (Jam) Marukawa .addReg(Src, getKillRegState(KillSrc)) 91538621c45SKazushi (Jam) Marukawa .addReg(VMX); 91638621c45SKazushi (Jam) Marukawa break; 91738621c45SKazushi (Jam) Marukawa case VE::LVMyim_y: 91838621c45SKazushi (Jam) Marukawa assert(MI.getOperand(0).getReg() == MI.getOperand(3).getReg() && 91938621c45SKazushi (Jam) Marukawa "LVMyim_y has different register in 3rd operand"); 92038621c45SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, get(VE::LVMim_m)) 92138621c45SKazushi (Jam) Marukawa .addDef(VMX) 92238621c45SKazushi (Jam) Marukawa .addImm(Imm) 92338621c45SKazushi (Jam) Marukawa .addImm(MImm) 92438621c45SKazushi (Jam) Marukawa .addReg(VMX); 92538621c45SKazushi (Jam) Marukawa break; 92638621c45SKazushi (Jam) Marukawa } 92738621c45SKazushi (Jam) Marukawa MI.eraseFromParent(); 92838621c45SKazushi (Jam) Marukawa return true; 92938621c45SKazushi (Jam) Marukawa } 93038621c45SKazushi (Jam) Marukawa case VE::SVMyi: { 93138621c45SKazushi (Jam) Marukawa Register Dest = MI.getOperand(0).getReg(); 93238621c45SKazushi (Jam) Marukawa Register VMZu = getVM512Upper(MI.getOperand(1).getReg()); 93338621c45SKazushi (Jam) Marukawa Register VMZl = getVM512Lower(MI.getOperand(1).getReg()); 93438621c45SKazushi (Jam) Marukawa bool KillSrc = MI.getOperand(1).isKill(); 93538621c45SKazushi (Jam) Marukawa int64_t Imm = MI.getOperand(2).getImm(); 93638621c45SKazushi (Jam) Marukawa Register VMZ = VMZl; 93738621c45SKazushi (Jam) Marukawa if (Imm >= 4) { 93838621c45SKazushi (Jam) Marukawa VMZ = VMZu; 93938621c45SKazushi (Jam) Marukawa Imm -= 4; 94038621c45SKazushi (Jam) Marukawa } 94138621c45SKazushi (Jam) Marukawa MachineBasicBlock *MBB = MI.getParent(); 94238621c45SKazushi (Jam) Marukawa DebugLoc DL = MI.getDebugLoc(); 94338621c45SKazushi (Jam) Marukawa MachineInstrBuilder MIB = 94438621c45SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, get(VE::SVMmi), Dest).addReg(VMZ).addImm(Imm); 94538621c45SKazushi (Jam) Marukawa MachineInstr *Inst = MIB.getInstr(); 94638621c45SKazushi (Jam) Marukawa if (KillSrc) { 94738621c45SKazushi (Jam) Marukawa const TargetRegisterInfo *TRI = &getRegisterInfo(); 94838621c45SKazushi (Jam) Marukawa Inst->addRegisterKilled(MI.getOperand(1).getReg(), TRI, true); 94938621c45SKazushi (Jam) Marukawa } 950435d44bfSSimon Moll MI.eraseFromParent(); 95138621c45SKazushi (Jam) Marukawa return true; 95238621c45SKazushi (Jam) Marukawa } 953398f29fbSKazushi (Jam) Marukawa case VE::VFMKyal: 954398f29fbSKazushi (Jam) Marukawa case VE::VFMKynal: 955398f29fbSKazushi (Jam) Marukawa case VE::VFMKWyvl: 956398f29fbSKazushi (Jam) Marukawa case VE::VFMKWyvyl: 957398f29fbSKazushi (Jam) Marukawa case VE::VFMKSyvl: 958398f29fbSKazushi (Jam) Marukawa case VE::VFMKSyvyl: 959398f29fbSKazushi (Jam) Marukawa expandPseudoVFMK(*this, MI); 960e37000f3SSimon Moll return true; 961064859bdSKazushi (Jam) Marukawa } 962064859bdSKazushi (Jam) Marukawa return false; 963064859bdSKazushi (Jam) Marukawa } 964064859bdSKazushi (Jam) Marukawa 965064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { 966064859bdSKazushi (Jam) Marukawa MachineBasicBlock &MBB = *MI.getParent(); 967064859bdSKazushi (Jam) Marukawa MachineFunction &MF = *MBB.getParent(); 968dedaf3a2SKazushi (Jam) Marukawa const VESubtarget &STI = MF.getSubtarget<VESubtarget>(); 969dedaf3a2SKazushi (Jam) Marukawa const VEInstrInfo &TII = *STI.getInstrInfo(); 970064859bdSKazushi (Jam) Marukawa DebugLoc dl = MBB.findDebugLoc(MI); 971064859bdSKazushi (Jam) Marukawa 972064859bdSKazushi (Jam) Marukawa // Create following instructions and multiple basic blocks. 973064859bdSKazushi (Jam) Marukawa // 974064859bdSKazushi (Jam) Marukawa // thisBB: 975064859bdSKazushi (Jam) Marukawa // brge.l.t %sp, %sl, sinkBB 976064859bdSKazushi (Jam) Marukawa // syscallBB: 977064859bdSKazushi (Jam) Marukawa // ld %s61, 0x18(, %tp) // load param area 978064859bdSKazushi (Jam) Marukawa // or %s62, 0, %s0 // spill the value of %s0 979064859bdSKazushi (Jam) Marukawa // lea %s63, 0x13b // syscall # of grow 980064859bdSKazushi (Jam) Marukawa // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 981064859bdSKazushi (Jam) Marukawa // shm.l %sl, 0x8(%s61) // store old limit at addr:8 982064859bdSKazushi (Jam) Marukawa // shm.l %sp, 0x10(%s61) // store new limit at addr:16 983064859bdSKazushi (Jam) Marukawa // monc // call monitor 984064859bdSKazushi (Jam) Marukawa // or %s0, 0, %s62 // restore the value of %s0 985064859bdSKazushi (Jam) Marukawa // sinkBB: 986064859bdSKazushi (Jam) Marukawa 987064859bdSKazushi (Jam) Marukawa // Create new MBB 988064859bdSKazushi (Jam) Marukawa MachineBasicBlock *BB = &MBB; 989064859bdSKazushi (Jam) Marukawa const BasicBlock *LLVM_BB = BB->getBasicBlock(); 990064859bdSKazushi (Jam) Marukawa MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); 991064859bdSKazushi (Jam) Marukawa MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); 992064859bdSKazushi (Jam) Marukawa MachineFunction::iterator It = ++(BB->getIterator()); 993064859bdSKazushi (Jam) Marukawa MF.insert(It, syscallMBB); 994064859bdSKazushi (Jam) Marukawa MF.insert(It, sinkMBB); 995064859bdSKazushi (Jam) Marukawa 996064859bdSKazushi (Jam) Marukawa // Transfer the remainder of BB and its successor edges to sinkMBB. 997064859bdSKazushi (Jam) Marukawa sinkMBB->splice(sinkMBB->begin(), BB, 998064859bdSKazushi (Jam) Marukawa std::next(std::next(MachineBasicBlock::iterator(MI))), 999064859bdSKazushi (Jam) Marukawa BB->end()); 1000064859bdSKazushi (Jam) Marukawa sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 1001064859bdSKazushi (Jam) Marukawa 1002064859bdSKazushi (Jam) Marukawa // Next, add the true and fallthrough blocks as its successors. 1003064859bdSKazushi (Jam) Marukawa BB->addSuccessor(syscallMBB); 1004064859bdSKazushi (Jam) Marukawa BB->addSuccessor(sinkMBB); 10053c80478dSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::BRCFLrr_t)) 1006064859bdSKazushi (Jam) Marukawa .addImm(VECC::CC_IGE) 1007064859bdSKazushi (Jam) Marukawa .addReg(VE::SX11) // %sp 1008064859bdSKazushi (Jam) Marukawa .addReg(VE::SX8) // %sl 1009064859bdSKazushi (Jam) Marukawa .addMBB(sinkMBB); 1010064859bdSKazushi (Jam) Marukawa 1011064859bdSKazushi (Jam) Marukawa BB = syscallMBB; 1012064859bdSKazushi (Jam) Marukawa 1013064859bdSKazushi (Jam) Marukawa // Update machine-CFG edges 1014064859bdSKazushi (Jam) Marukawa BB->addSuccessor(sinkMBB); 1015064859bdSKazushi (Jam) Marukawa 1016e981a46aSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::LDrii), VE::SX61) 1017064859bdSKazushi (Jam) Marukawa .addReg(VE::SX14) 1018e981a46aSKazushi (Jam) Marukawa .addImm(0) 1019064859bdSKazushi (Jam) Marukawa .addImm(0x18); 1020064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) 1021064859bdSKazushi (Jam) Marukawa .addReg(VE::SX0) 1022064859bdSKazushi (Jam) Marukawa .addImm(0); 1023e981a46aSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::LEAzii), VE::SX63) 1024e981a46aSKazushi (Jam) Marukawa .addImm(0) 1025e981a46aSKazushi (Jam) Marukawa .addImm(0) 1026064859bdSKazushi (Jam) Marukawa .addImm(0x13b); 102749e4faa0SKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMLri)) 1028064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 1029064859bdSKazushi (Jam) Marukawa .addImm(0) 1030064859bdSKazushi (Jam) Marukawa .addReg(VE::SX63); 103149e4faa0SKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMLri)) 1032064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 1033064859bdSKazushi (Jam) Marukawa .addImm(8) 1034064859bdSKazushi (Jam) Marukawa .addReg(VE::SX8); 103549e4faa0SKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::SHMLri)) 1036064859bdSKazushi (Jam) Marukawa .addReg(VE::SX61) 1037064859bdSKazushi (Jam) Marukawa .addImm(16) 1038064859bdSKazushi (Jam) Marukawa .addReg(VE::SX11); 1039064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::MONC)); 1040064859bdSKazushi (Jam) Marukawa 1041064859bdSKazushi (Jam) Marukawa BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) 1042064859bdSKazushi (Jam) Marukawa .addReg(VE::SX62) 1043064859bdSKazushi (Jam) Marukawa .addImm(0); 1044064859bdSKazushi (Jam) Marukawa 1045064859bdSKazushi (Jam) Marukawa MI.eraseFromParent(); // The pseudo instruction is gone now. 1046064859bdSKazushi (Jam) Marukawa return true; 1047064859bdSKazushi (Jam) Marukawa } 1048dedaf3a2SKazushi (Jam) Marukawa 1049dedaf3a2SKazushi (Jam) Marukawa bool VEInstrInfo::expandGetStackTopPseudo(MachineInstr &MI) const { 1050dedaf3a2SKazushi (Jam) Marukawa MachineBasicBlock *MBB = MI.getParent(); 1051dedaf3a2SKazushi (Jam) Marukawa MachineFunction &MF = *MBB->getParent(); 1052dedaf3a2SKazushi (Jam) Marukawa const VESubtarget &STI = MF.getSubtarget<VESubtarget>(); 1053dedaf3a2SKazushi (Jam) Marukawa const VEInstrInfo &TII = *STI.getInstrInfo(); 1054dedaf3a2SKazushi (Jam) Marukawa DebugLoc DL = MBB->findDebugLoc(MI); 1055dedaf3a2SKazushi (Jam) Marukawa 1056dedaf3a2SKazushi (Jam) Marukawa // Create following instruction 1057dedaf3a2SKazushi (Jam) Marukawa // 1058dedaf3a2SKazushi (Jam) Marukawa // dst = %sp + target specific frame + the size of parameter area 1059dedaf3a2SKazushi (Jam) Marukawa 1060dedaf3a2SKazushi (Jam) Marukawa const MachineFrameInfo &MFI = MF.getFrameInfo(); 1061dedaf3a2SKazushi (Jam) Marukawa const VEFrameLowering &TFL = *STI.getFrameLowering(); 1062dedaf3a2SKazushi (Jam) Marukawa 1063590aaa50SKazushi (Jam) Marukawa // The VE ABI requires a reserved area at the top of stack as described 1064590aaa50SKazushi (Jam) Marukawa // in VEFrameLowering.cpp. So, we adjust it here. 1065dedaf3a2SKazushi (Jam) Marukawa unsigned NumBytes = STI.getAdjustedFrameSize(0); 1066dedaf3a2SKazushi (Jam) Marukawa 1067dedaf3a2SKazushi (Jam) Marukawa // Also adds the size of parameter area. 1068dedaf3a2SKazushi (Jam) Marukawa if (MFI.adjustsStack() && TFL.hasReservedCallFrame(MF)) 1069dedaf3a2SKazushi (Jam) Marukawa NumBytes += MFI.getMaxCallFrameSize(); 1070dedaf3a2SKazushi (Jam) Marukawa 1071dedaf3a2SKazushi (Jam) Marukawa BuildMI(*MBB, MI, DL, TII.get(VE::LEArii)) 1072dedaf3a2SKazushi (Jam) Marukawa .addDef(MI.getOperand(0).getReg()) 1073dedaf3a2SKazushi (Jam) Marukawa .addReg(VE::SX11) 1074dedaf3a2SKazushi (Jam) Marukawa .addImm(0) 1075dedaf3a2SKazushi (Jam) Marukawa .addImm(NumBytes); 1076dedaf3a2SKazushi (Jam) Marukawa 1077dedaf3a2SKazushi (Jam) Marukawa MI.eraseFromParent(); // The pseudo instruction is gone now. 1078dedaf3a2SKazushi (Jam) Marukawa return true; 1079dedaf3a2SKazushi (Jam) Marukawa } 1080