#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
+#define GET_INSTRINFO_CTOR
#include "PTXGenInstrInfo.inc"
+using namespace llvm;
+
PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
- : TargetInstrInfoImpl(PTXInsts, array_lengthof(PTXInsts)),
+ : PTXGenInstrInfo(),
RI(_TM, *this), TM(_TM) {}
static const struct map_entry {
const TargetRegisterClass *cls;
const int opcode;
} map[] = {
- { &PTX::RRegu16RegClass, PTX::MOVU16rr },
- { &PTX::RRegu32RegClass, PTX::MOVU32rr },
- { &PTX::RRegu64RegClass, PTX::MOVU64rr },
- { &PTX::RRegf32RegClass, PTX::MOVF32rr },
- { &PTX::RRegf64RegClass, PTX::MOVF64rr },
- { &PTX::PredsRegClass, PTX::MOVPREDrr }
+ { &PTX::RegI16RegClass, PTX::MOVU16rr },
+ { &PTX::RegI32RegClass, PTX::MOVU32rr },
+ { &PTX::RegI64RegClass, PTX::MOVU64rr },
+ { &PTX::RegF32RegClass, PTX::MOVF32rr },
+ { &PTX::RegF64RegClass, PTX::MOVF64rr },
+ { &PTX::RegPredRegClass, PTX::MOVPREDrr }
};
void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
bool KillSrc) const {
for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i) {
if (map[i].cls->contains(DstReg, SrcReg)) {
- const TargetInstrDesc &TID = get(map[i].opcode);
- MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).
+ const MCInstrDesc &MCID = get(map[i].opcode);
+ MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).
addReg(SrcReg, getKillRegState(KillSrc));
AddDefaultPredicate(MI);
return;
for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i)
if (DstRC == map[i].cls) {
- const TargetInstrDesc &TID = get(map[i].opcode);
- MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).addReg(SrcReg);
+ const MCInstrDesc &MCID = get(map[i].opcode);
+ MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).addReg(SrcReg);
AddDefaultPredicate(MI);
return true;
}
bool PTXInstrInfo::
SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
const SmallVectorImpl<MachineOperand> &Pred2) const {
- // TODO Implement SubsumesPredicate
- // Returns true if the first specified predicate subsumes the second,
- // e.g. GE subsumes GT.
- return false;
+ const MachineOperand &PredReg1 = Pred1[0];
+ const MachineOperand &PredReg2 = Pred2[0];
+ if (PredReg1.getReg() != PredReg2.getReg())
+ return false;
+
+ const MachineOperand &PredOp1 = Pred1[1];
+ const MachineOperand &PredOp2 = Pred2[1];
+ if (PredOp1.getImm() != PredOp2.getImm())
+ return false;
+
+ return true;
}
bool PTXInstrInfo::
DefinesPredicate(MachineInstr *MI,
std::vector<MachineOperand> &Pred) const {
- // TODO Implement DefinesPredicate
- // If the specified instruction defines any predicate or condition code
- // register(s) used for predication, returns true as well as the definition
- // predicate(s) by reference.
+ // If an instruction sets a predicate register, it defines a predicate.
- switch (MI->getOpcode()) {
- default:
+ // TODO supprot 5-operand format of setp instruction
+
+ if (MI->getNumOperands() < 1)
return false;
- case PTX::SETPEQu32rr:
- case PTX::SETPEQu32ri:
- case PTX::SETPNEu32rr:
- case PTX::SETPNEu32ri:
- case PTX::SETPLTu32rr:
- case PTX::SETPLTu32ri:
- case PTX::SETPLEu32rr:
- case PTX::SETPLEu32ri:
- case PTX::SETPGTu32rr:
- case PTX::SETPGTu32ri:
- case PTX::SETPGEu32rr:
- case PTX::SETPGEu32ri: {
- const MachineOperand &MO = MI->getOperand(0);
- assert(MO.isReg() && RI.getRegClass(MO.getReg()) == &PTX::PredsRegClass);
- Pred.push_back(MO);
- Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL));
- return true;
- }
- }
+
+ const MachineOperand &MO = MI->getOperand(0);
+
+ if (!MO.isReg() || RI.getRegClass(MO.getReg()) != &PTX::RegPredRegClass)
+ return false;
+
+ Pred.push_back(MO);
+ Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL));
+ return true;
}
// branch support
MachineBasicBlock::const_iterator iter = MBB.end();
const MachineInstr& instLast1 = *--iter;
- const TargetInstrDesc &desc1 = instLast1.getDesc();
+ const MCInstrDesc &desc1 = instLast1.getDesc();
// for special case that MBB has only 1 instruction
const bool IsSizeOne = MBB.size() == 1;
// if IsSizeOne is true, *--iter and instLast2 are invalid
// we put a dummy value in instLast2 and desc2 since they are used
const MachineInstr& instLast2 = IsSizeOne ? instLast1 : *--iter;
- const TargetInstrDesc &desc2 = IsSizeOne ? desc1 : instLast2.getDesc();
+ const MCInstrDesc &desc2 = IsSizeOne ? desc1 : instLast2.getDesc();
DEBUG(dbgs() << "\n");
DEBUG(dbgs() << "AnalyzeBranch: opcode: " << instLast1.getOpcode() << "\n");
}
unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
- unsigned count;
- for (count = 0; IsAnyKindOfBranch(MBB.back()); ++count)
- MBB.pop_back();
+ unsigned count = 0;
+ while (!MBB.empty())
+ if (IsAnyKindOfBranch(MBB.back())) {
+ MBB.pop_back();
+ ++count;
+ } else
+ break;
DEBUG(dbgs() << "RemoveBranch: MBB: " << MBB.getName().str() << "\n");
- DEBUG(dbgs() << "RemoveBranch: count: " << count << "\n");
+ DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n");
return count;
}
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const {
DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
- DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: "
- << TBB->getName().str() << "\n";
- else dbgs() << "InsertBranch: TBB: (NULL)\n");
- DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: "
- << FBB->getName().str() << "\n";
- else dbgs() << "InsertBranch: FBB: (NULL)\n");
+ DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str()
+ << "\n";
+ else dbgs() << "InsertBranch: TBB: (NULL)\n");
+ DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str()
+ << "\n";
+ else dbgs() << "InsertBranch: FBB: (NULL)\n");
DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");
assert(TBB && "TBB is NULL");
}
}
+// Memory operand folding for spills
+void PTXInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MII,
+ unsigned SrcReg, bool isKill, int FrameIdx,
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
+ MachineInstr& MI = *MII;
+ DebugLoc DL = MI.getDebugLoc();
+
+ DEBUG(dbgs() << "storeRegToStackSlot: " << MI);
+
+ int OpCode;
+
+ // Select the appropriate opcode based on the register class
+ if (RC == PTX::RegI16RegisterClass) {
+ OpCode = PTX::STACKSTOREI16;
+ } else if (RC == PTX::RegI32RegisterClass) {
+ OpCode = PTX::STACKSTOREI32;
+ } else if (RC == PTX::RegI64RegisterClass) {
+ OpCode = PTX::STACKSTOREI32;
+ } else if (RC == PTX::RegF32RegisterClass) {
+ OpCode = PTX::STACKSTOREF32;
+ } else if (RC == PTX::RegF64RegisterClass) {
+ OpCode = PTX::STACKSTOREF64;
+ } else {
+ llvm_unreachable("Unknown PTX register class!");
+ }
+
+ // Build the store instruction (really a mov)
+ MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode));
+ MIB.addFrameIndex(FrameIdx);
+ MIB.addReg(SrcReg);
+
+ AddDefaultPredicate(MIB);
+}
+
+void PTXInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MII,
+ unsigned DestReg, int FrameIdx,
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
+ MachineInstr& MI = *MII;
+ DebugLoc DL = MI.getDebugLoc();
+
+ DEBUG(dbgs() << "loadRegToStackSlot: " << MI);
+
+ int OpCode;
+
+ // Select the appropriate opcode based on the register class
+ if (RC == PTX::RegI16RegisterClass) {
+ OpCode = PTX::STACKLOADI16;
+ } else if (RC == PTX::RegI32RegisterClass) {
+ OpCode = PTX::STACKLOADI32;
+ } else if (RC == PTX::RegI64RegisterClass) {
+ OpCode = PTX::STACKLOADI32;
+ } else if (RC == PTX::RegF32RegisterClass) {
+ OpCode = PTX::STACKLOADF32;
+ } else if (RC == PTX::RegF64RegisterClass) {
+ OpCode = PTX::STACKLOADF64;
+ } else {
+ llvm_unreachable("Unknown PTX register class!");
+ }
+
+ // Build the load instruction (really a mov)
+ MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode));
+ MIB.addReg(DestReg);
+ MIB.addFrameIndex(FrameIdx);
+
+ AddDefaultPredicate(MIB);
+}
+
// static helper routines
MachineSDNode *PTXInstrInfo::
}
bool PTXInstrInfo::IsAnyKindOfBranch(const MachineInstr& inst) {
- const TargetInstrDesc &desc = inst.getDesc();
+ const MCInstrDesc &desc = inst.getDesc();
return desc.isTerminator() || desc.isBranch() || desc.isIndirectBranch();
}