aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Sparc/SparcInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Sparc/SparcInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/Sparc/SparcInstrInfo.cpp120
1 files changed, 80 insertions, 40 deletions
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp
index a8a0b2cc9e67..63f662c41f93 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp
@@ -117,33 +117,63 @@ static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
case SPCC::CPCC_A: return SPCC::CPCC_N;
case SPCC::CPCC_N: return SPCC::CPCC_A;
- case SPCC::CPCC_3: LLVM_FALLTHROUGH;
- case SPCC::CPCC_2: LLVM_FALLTHROUGH;
- case SPCC::CPCC_23: LLVM_FALLTHROUGH;
- case SPCC::CPCC_1: LLVM_FALLTHROUGH;
- case SPCC::CPCC_13: LLVM_FALLTHROUGH;
- case SPCC::CPCC_12: LLVM_FALLTHROUGH;
- case SPCC::CPCC_123: LLVM_FALLTHROUGH;
- case SPCC::CPCC_0: LLVM_FALLTHROUGH;
- case SPCC::CPCC_03: LLVM_FALLTHROUGH;
- case SPCC::CPCC_02: LLVM_FALLTHROUGH;
- case SPCC::CPCC_023: LLVM_FALLTHROUGH;
- case SPCC::CPCC_01: LLVM_FALLTHROUGH;
- case SPCC::CPCC_013: LLVM_FALLTHROUGH;
+ case SPCC::CPCC_3: [[fallthrough]];
+ case SPCC::CPCC_2: [[fallthrough]];
+ case SPCC::CPCC_23: [[fallthrough]];
+ case SPCC::CPCC_1: [[fallthrough]];
+ case SPCC::CPCC_13: [[fallthrough]];
+ case SPCC::CPCC_12: [[fallthrough]];
+ case SPCC::CPCC_123: [[fallthrough]];
+ case SPCC::CPCC_0: [[fallthrough]];
+ case SPCC::CPCC_03: [[fallthrough]];
+ case SPCC::CPCC_02: [[fallthrough]];
+ case SPCC::CPCC_023: [[fallthrough]];
+ case SPCC::CPCC_01: [[fallthrough]];
+ case SPCC::CPCC_013: [[fallthrough]];
case SPCC::CPCC_012:
// "Opposite" code is not meaningful, as we don't know
// what the CoProc condition means here. The cond-code will
// only be used in inline assembler, so this code should
// not be reached in a normal compilation pass.
llvm_unreachable("Meaningless inversion of co-processor cond code");
+
+ case SPCC::REG_BEGIN:
+ llvm_unreachable("Use of reserved cond code");
+ case SPCC::REG_Z:
+ return SPCC::REG_NZ;
+ case SPCC::REG_LEZ:
+ return SPCC::REG_GZ;
+ case SPCC::REG_LZ:
+ return SPCC::REG_GEZ;
+ case SPCC::REG_NZ:
+ return SPCC::REG_Z;
+ case SPCC::REG_GZ:
+ return SPCC::REG_LEZ;
+ case SPCC::REG_GEZ:
+ return SPCC::REG_LZ;
}
llvm_unreachable("Invalid cond code");
}
-static bool isUncondBranchOpcode(int Opc) { return Opc == SP::BA; }
+static bool isUncondBranchOpcode(int Opc) {
+ return Opc == SP::BA || Opc == SP::BPA;
+}
+
+static bool isI32CondBranchOpcode(int Opc) {
+ return Opc == SP::BCOND || Opc == SP::BPICC || Opc == SP::BPICCA ||
+ Opc == SP::BPICCNT || Opc == SP::BPICCANT;
+}
+
+static bool isI64CondBranchOpcode(int Opc) {
+ return Opc == SP::BPXCC || Opc == SP::BPXCCA || Opc == SP::BPXCCNT ||
+ Opc == SP::BPXCCANT;
+}
+
+static bool isFCondBranchOpcode(int Opc) { return Opc == SP::FBCOND; }
static bool isCondBranchOpcode(int Opc) {
- return Opc == SP::FBCOND || Opc == SP::BCOND;
+ return isI32CondBranchOpcode(Opc) || isI64CondBranchOpcode(Opc) ||
+ isFCondBranchOpcode(Opc);
}
static bool isIndirectBranchOpcode(int Opc) {
@@ -152,7 +182,14 @@ static bool isIndirectBranchOpcode(int Opc) {
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,
SmallVectorImpl<MachineOperand> &Cond) {
- Cond.push_back(MachineOperand::CreateImm(LastInst->getOperand(1).getImm()));
+ unsigned Opc = LastInst->getOpcode();
+ int64_t CC = LastInst->getOperand(1).getImm();
+
+ // Push the branch opcode into Cond too so later in insertBranch
+ // it can use the information to emit the correct SPARC branch opcode.
+ Cond.push_back(MachineOperand::CreateImm(Opc));
+ Cond.push_back(MachineOperand::CreateImm(CC));
+
Target = LastInst->getOperand(0).getMBB();
}
@@ -246,27 +283,29 @@ unsigned SparcInstrInfo::insertBranch(MachineBasicBlock &MBB,
const DebugLoc &DL,
int *BytesAdded) const {
assert(TBB && "insertBranch must not be told to insert a fallthrough");
- assert((Cond.size() == 1 || Cond.size() == 0) &&
- "Sparc branch conditions should have one component!");
+ assert((Cond.size() <= 2) &&
+ "Sparc branch conditions should have at most two components!");
assert(!BytesAdded && "code size not handled");
if (Cond.empty()) {
assert(!FBB && "Unconditional branch with multiple successors!");
- BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);
+ BuildMI(&MBB, DL, get(Subtarget.isV9() ? SP::BPA : SP::BA)).addMBB(TBB);
return 1;
}
// Conditional branch
- unsigned CC = Cond[0].getImm();
+ unsigned Opc = Cond[0].getImm();
+ unsigned CC = Cond[1].getImm();
- if (IsIntegerCC(CC))
- BuildMI(&MBB, DL, get(SP::BCOND)).addMBB(TBB).addImm(CC);
- else
+ if (IsIntegerCC(CC)) {
+ BuildMI(&MBB, DL, get(Opc)).addMBB(TBB).addImm(CC);
+ } else {
BuildMI(&MBB, DL, get(SP::FBCOND)).addMBB(TBB).addImm(CC);
+ }
if (!FBB)
return 1;
- BuildMI(&MBB, DL, get(SP::BA)).addMBB(FBB);
+ BuildMI(&MBB, DL, get(Subtarget.isV9() ? SP::BPA : SP::BA)).addMBB(FBB);
return 2;
}
@@ -282,9 +321,8 @@ unsigned SparcInstrInfo::removeBranch(MachineBasicBlock &MBB,
if (I->isDebugInstr())
continue;
- if (I->getOpcode() != SP::BA
- && I->getOpcode() != SP::BCOND
- && I->getOpcode() != SP::FBCOND)
+ if (!isCondBranchOpcode(I->getOpcode()) &&
+ !isUncondBranchOpcode(I->getOpcode()))
break; // Not a branch
I->eraseFromParent();
@@ -296,9 +334,9 @@ unsigned SparcInstrInfo::removeBranch(MachineBasicBlock &MBB,
bool SparcInstrInfo::reverseBranchCondition(
SmallVectorImpl<MachineOperand> &Cond) const {
- assert(Cond.size() == 1);
- SPCC::CondCodes CC = static_cast<SPCC::CondCodes>(Cond[0].getImm());
- Cond[0].setImm(GetOppositeBranchCondition(CC));
+ assert(Cond.size() <= 2);
+ SPCC::CondCodes CC = static_cast<SPCC::CondCodes>(Cond[1].getImm());
+ Cond[1].setImm(GetOppositeBranchCondition(CC));
return false;
}
@@ -391,11 +429,12 @@ void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MovMI->addRegisterKilled(SrcReg, TRI);
}
-void SparcInstrInfo::
-storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
- Register SrcReg, bool isKill, int FI,
- const TargetRegisterClass *RC,
- const TargetRegisterInfo *TRI) const {
+void SparcInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ Register SrcReg, bool isKill, int FI,
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI,
+ Register VReg) const {
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
@@ -430,11 +469,12 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
llvm_unreachable("Can't store this register to stack slot");
}
-void SparcInstrInfo::
-loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
- Register DestReg, int FI,
- const TargetRegisterClass *RC,
- const TargetRegisterInfo *TRI) const {
+void SparcInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ Register DestReg, int FI,
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI,
+ Register VReg) const {
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();