[llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaBranchSelector.cpp Alpha.h AlphaISelLowering.cpp AlphaISelLowering.h AlphaInstrFormats.td AlphaInstrInfo.cpp AlphaInstrInfo.h AlphaInstrInfo.td AlphaTargetMachine.cpp
Andrew Lenharth
alenhar2 at cs.uiuc.edu
Tue Oct 31 08:50:09 PST 2006
Changes in directory llvm/lib/Target/Alpha:
AlphaBranchSelector.cpp added (r1.1)
Alpha.h updated: 1.7 -> 1.8
AlphaISelLowering.cpp updated: 1.70 -> 1.71
AlphaISelLowering.h updated: 1.21 -> 1.22
AlphaInstrFormats.td updated: 1.28 -> 1.29
AlphaInstrInfo.cpp updated: 1.11 -> 1.12
AlphaInstrInfo.h updated: 1.6 -> 1.7
AlphaInstrInfo.td updated: 1.130 -> 1.131
AlphaTargetMachine.cpp updated: 1.34 -> 1.35
---
Log message:
Add all that branch mangling niftiness
---
Diffs of the changes: (+414 -129)
Alpha.h | 1
AlphaBranchSelector.cpp | 63 +++++++++++
AlphaISelLowering.cpp | 2
AlphaISelLowering.h | 10 +
AlphaInstrFormats.td | 28 +----
AlphaInstrInfo.cpp | 166 +++++++++++++++++++++++++++++-
AlphaInstrInfo.h | 8 +
AlphaInstrInfo.td | 263 ++++++++++++++++++++++++++++--------------------
AlphaTargetMachine.cpp | 2
9 files changed, 414 insertions(+), 129 deletions(-)
Index: llvm/lib/Target/Alpha/AlphaBranchSelector.cpp
diff -c /dev/null llvm/lib/Target/Alpha/AlphaBranchSelector.cpp:1.1
*** /dev/null Tue Oct 31 10:50:05 2006
--- llvm/lib/Target/Alpha/AlphaBranchSelector.cpp Tue Oct 31 10:49:55 2006
***************
*** 0 ****
--- 1,63 ----
+ //===-- AlphaBranchSelector.cpp - Convert Pseudo branchs ----------*- C++ -*-=//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Andrew Lenharth and is distributed under the
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // Replace Pseudo COND_BRANCH_* with their appropriate real branch
+ // Simplified version of the PPC Branch Selector
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "Alpha.h"
+ #include "AlphaInstrInfo.h"
+ #include "llvm/CodeGen/MachineFunctionPass.h"
+ #include "llvm/Support/Compiler.h"
+ #include "llvm/Target/TargetMachine.h"
+ #include "llvm/Target/TargetAsmInfo.h"
+ using namespace llvm;
+
+ namespace {
+ struct VISIBILITY_HIDDEN AlphaBSel : public MachineFunctionPass {
+
+ virtual bool runOnMachineFunction(MachineFunction &Fn);
+
+ virtual const char *getPassName() const {
+ return "Alpha Branch Selection";
+ }
+ };
+ }
+
+ /// createAlphaBranchSelectionPass - returns an instance of the Branch Selection
+ /// Pass
+ ///
+ FunctionPass *llvm::createAlphaBranchSelectionPass() {
+ return new AlphaBSel();
+ }
+
+ bool AlphaBSel::runOnMachineFunction(MachineFunction &Fn) {
+
+ for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
+ ++MFI) {
+ MachineBasicBlock *MBB = MFI;
+
+ for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
+ MBBI != EE; ++MBBI) {
+ if (MBBI->getOpcode() == Alpha::COND_BRANCH_I ||
+ MBBI->getOpcode() == Alpha::COND_BRANCH_F) {
+
+ // condbranch operands:
+ // 0. bc opcode
+ // 1. reg
+ // 2. target MBB
+ MBBI->setOpcode(MBBI->getOperand(0).getImm());
+ }
+ }
+ }
+
+ return true;
+ }
+
Index: llvm/lib/Target/Alpha/Alpha.h
diff -u llvm/lib/Target/Alpha/Alpha.h:1.7 llvm/lib/Target/Alpha/Alpha.h:1.8
--- llvm/lib/Target/Alpha/Alpha.h:1.7 Mon Sep 18 14:44:29 2006
+++ llvm/lib/Target/Alpha/Alpha.h Tue Oct 31 10:49:55 2006
@@ -32,6 +32,7 @@
FunctionPass *createAlphaCodeEmitterPass(AlphaTargetMachine &TM,
MachineCodeEmitter &MCE);
FunctionPass *createAlphaLLRPPass(AlphaTargetMachine &tm);
+ FunctionPass *createAlphaBranchSelectionPass();
} // end namespace llvm;
Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp
diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.70 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.71
--- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.70 Mon Oct 30 02:02:39 2006
+++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Tue Oct 31 10:49:55 2006
@@ -164,6 +164,8 @@
case AlphaISD::CALL: return "Alpha::CALL";
case AlphaISD::DivCall: return "Alpha::DivCall";
case AlphaISD::RET_FLAG: return "Alpha::RET_FLAG";
+ case AlphaISD::COND_BRANCH_I: return "Alpha::COND_BRANCH_I";
+ case AlphaISD::COND_BRANCH_F: return "Alpha::COND_BRANCH_F";
}
}
Index: llvm/lib/Target/Alpha/AlphaISelLowering.h
diff -u llvm/lib/Target/Alpha/AlphaISelLowering.h:1.21 llvm/lib/Target/Alpha/AlphaISelLowering.h:1.22
--- llvm/lib/Target/Alpha/AlphaISelLowering.h:1.21 Wed Oct 11 11:24:51 2006
+++ llvm/lib/Target/Alpha/AlphaISelLowering.h Tue Oct 31 10:49:55 2006
@@ -46,7 +46,15 @@
DivCall,
/// return flag operand
- RET_FLAG
+ RET_FLAG,
+
+ /// CHAIN = COND_BRANCH CHAIN, OPC, (G|F)PRC, DESTBB [, INFLAG] - This
+ /// corresponds to the COND_BRANCH pseudo instruction.
+ /// *PRC is the input register to compare to zero,
+ /// OPC is the branch opcode to use (e.g. Alpha::BEQ),
+ /// DESTBB is the destination block to branch to, and INFLAG is
+ /// an optional input flag argument.
+ COND_BRANCH_I, COND_BRANCH_F
};
}
Index: llvm/lib/Target/Alpha/AlphaInstrFormats.td
diff -u llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.28 llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.29
--- llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.28 Mon Jun 12 13:09:24 2006
+++ llvm/lib/Target/Alpha/AlphaInstrFormats.td Tue Oct 31 10:49:55 2006
@@ -22,6 +22,7 @@
def s16imm : Operand<i64>;
def s21imm : Operand<i64>;
def s64imm : Operand<i64>;
+def u64imm : Operand<i64>;
//===----------------------------------------------------------------------===//
// Instruction format superclass
@@ -92,36 +93,25 @@
//3.3.2
def target : Operand<OtherVT> {}
-let isBranch = 1, isTerminator = 1 in
-class BFormD<bits<6> opcode, string asmstr, list<dag> pattern, InstrItinClass itin>
- : InstAlpha<opcode, asmstr, itin> {
- let Pattern = pattern;
- let OperandList = (ops target:$DISP);
- bits<5> Ra;
- bits<21> disp;
-
- let Inst{25-21} = Ra;
- let Inst{20-0} = disp;
-}
-let isBranch = 1, isTerminator = 1 in
-class BForm<bits<6> opcode, string asmstr, list<dag> pattern, InstrItinClass itin>
- : InstAlpha<opcode, asmstr, itin> {
- let Pattern = pattern;
- let OperandList = (ops GPRC:$RA, target:$DISP);
+let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in {
+class BFormN<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+ : InstAlpha<opcode, asmstr, itin> {
+ let OperandList = OL;
+ bits<64> Opc; //dummy
bits<5> Ra;
bits<21> disp;
let Inst{25-21} = Ra;
let Inst{20-0} = disp;
}
+}
let isBranch = 1, isTerminator = 1 in
-class FBForm<bits<6> opcode, string asmstr, list<dag> pattern, InstrItinClass itin>
+class BFormD<bits<6> opcode, string asmstr, list<dag> pattern, InstrItinClass itin>
: InstAlpha<opcode, asmstr, itin> {
let Pattern = pattern;
- let OperandList = (ops F8RC:$RA, target:$DISP);
-
+ let OperandList = (ops target:$DISP);
bits<5> Ra;
bits<21> disp;
Index: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp
diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.11 llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.12
--- llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.11 Tue Oct 24 12:07:11 2006
+++ llvm/lib/Target/Alpha/AlphaInstrInfo.cpp Tue Oct 31 10:49:55 2006
@@ -83,10 +83,170 @@
return 0;
}
+static bool isAlphaIntCondCode(unsigned Opcode) {
+ switch (Opcode) {
+ case Alpha::BEQ:
+ case Alpha::BNE:
+ case Alpha::BGE:
+ case Alpha::BGT:
+ case Alpha::BLE:
+ case Alpha::BLT:
+ case Alpha::BLBC:
+ case Alpha::BLBS:
+ return true;
+ default:
+ return false;
+ }
+}
+
void AlphaInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const std::vector<MachineOperand> &Cond)const{
- // Can only insert uncond branches so far.
- assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
- BuildMI(&MBB, Alpha::BR, 1).addMBB(TBB);
+ assert(TBB && "InsertBranch must not be told to insert a fallthrough");
+ assert((Cond.size() == 2 || Cond.size() == 0) &&
+ "Alpha branch conditions have two components!");
+
+ // One-way branch.
+ if (FBB == 0) {
+ if (Cond.empty()) // Unconditional branch
+ BuildMI(&MBB, Alpha::BR, 1).addMBB(TBB);
+ else // Conditional branch
+ if (isAlphaIntCondCode(Cond[0].getImm()))
+ BuildMI(&MBB, Alpha::COND_BRANCH_I, 3)
+ .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
+ else
+ BuildMI(&MBB, Alpha::COND_BRANCH_F, 3)
+ .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
+ return;
+ }
+
+ // Two-way Conditional Branch.
+ if (isAlphaIntCondCode(Cond[0].getImm()))
+ BuildMI(&MBB, Alpha::COND_BRANCH_I, 3)
+ .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
+ else
+ BuildMI(&MBB, Alpha::COND_BRANCH_F, 3)
+ .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
+ BuildMI(&MBB, Alpha::BR, 1).addMBB(FBB);
+}
+
+static unsigned AlphaRevCondCode(unsigned Opcode) {
+ switch (Opcode) {
+ case Alpha::BEQ: return Alpha::BNE;
+ case Alpha::BNE: return Alpha::BEQ;
+ case Alpha::BGE: return Alpha::BLT;
+ case Alpha::BGT: return Alpha::BLE;
+ case Alpha::BLE: return Alpha::BGT;
+ case Alpha::BLT: return Alpha::BGE;
+ case Alpha::BLBC: return Alpha::BLBS;
+ case Alpha::BLBS: return Alpha::BLBC;
+ case Alpha::FBEQ: return Alpha::FBNE;
+ case Alpha::FBNE: return Alpha::FBEQ;
+ case Alpha::FBGE: return Alpha::FBLT;
+ case Alpha::FBGT: return Alpha::FBLE;
+ case Alpha::FBLE: return Alpha::FBGT;
+ case Alpha::FBLT: return Alpha::FBGE;
+ default:
+ assert(0 && "Unknown opcode");
+ }
+}
+
+// Branch analysis.
+bool AlphaInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
+ MachineBasicBlock *&FBB,
+ std::vector<MachineOperand> &Cond) const {
+ // If the block has no terminators, it just falls into the block after it.
+ MachineBasicBlock::iterator I = MBB.end();
+ if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode()))
+ return false;
+
+ // Get the last instruction in the block.
+ MachineInstr *LastInst = I;
+
+ // If there is only one terminator instruction, process it.
+ if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode())) {
+ if (LastInst->getOpcode() == Alpha::BR) {
+ TBB = LastInst->getOperand(0).getMachineBasicBlock();
+ return false;
+ } else if (LastInst->getOpcode() == Alpha::COND_BRANCH_I ||
+ LastInst->getOpcode() == Alpha::COND_BRANCH_F) {
+ // Block ends with fall-through condbranch.
+ TBB = LastInst->getOperand(2).getMachineBasicBlock();
+ Cond.push_back(LastInst->getOperand(0));
+ Cond.push_back(LastInst->getOperand(1));
+ return false;
+ }
+ // Otherwise, don't know what this is.
+ return true;
+ }
+
+ // Get the instruction before it if it's a terminator.
+ MachineInstr *SecondLastInst = I;
+
+ // If there are three terminators, we don't know what sort of block this is.
+ if (SecondLastInst && I != MBB.begin() &&
+ isTerminatorInstr((--I)->getOpcode()))
+ return true;
+
+ // If the block ends with Alpha::BR and Alpha::COND_BRANCH_*, handle it.
+ if ((SecondLastInst->getOpcode() == Alpha::COND_BRANCH_I ||
+ SecondLastInst->getOpcode() == Alpha::COND_BRANCH_F) &&
+ LastInst->getOpcode() == Alpha::BR) {
+ TBB = SecondLastInst->getOperand(2).getMachineBasicBlock();
+ Cond.push_back(SecondLastInst->getOperand(0));
+ Cond.push_back(SecondLastInst->getOperand(1));
+ FBB = LastInst->getOperand(0).getMachineBasicBlock();
+ return false;
+ }
+
+ // Otherwise, can't handle this.
+ return true;
+}
+
+void AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
+ MachineBasicBlock::iterator I = MBB.end();
+ if (I == MBB.begin()) return;
+ --I;
+ if (I->getOpcode() != Alpha::BR &&
+ I->getOpcode() != Alpha::COND_BRANCH_I &&
+ I->getOpcode() != Alpha::COND_BRANCH_F)
+ return;
+
+ // Remove the branch.
+ I->eraseFromParent();
+
+ I = MBB.end();
+
+ if (I == MBB.begin()) return;
+ --I;
+ if (I->getOpcode() != Alpha::COND_BRANCH_I &&
+ I->getOpcode() != Alpha::COND_BRANCH_F)
+ return;
+
+ // Remove the branch.
+ I->eraseFromParent();
+}
+
+void AlphaInstrInfo::insertNoop(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const {
+ BuildMI(MBB, MI, Alpha::BIS, 2, Alpha::R31).addReg(Alpha::R31)
+ .addReg(Alpha::R31);
+}
+
+bool AlphaInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
+ if (MBB.empty()) return false;
+
+ switch (MBB.back().getOpcode()) {
+ case Alpha::BR: // Uncond branch.
+ case Alpha::JMP: // Indirect branch.
+ return true;
+ default: return false;
+ }
+}
+bool AlphaInstrInfo::
+ReverseBranchCondition(std::vector<MachineOperand> &Cond) const {
+ assert(Cond.size() == 2 && "Invalid Alpha branch opcode!");
+ Cond[0].setImm(AlphaRevCondCode(Cond[0].getImm()));
+ return false;
}
+
Index: llvm/lib/Target/Alpha/AlphaInstrInfo.h
diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.6 llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.7
--- llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.6 Tue Oct 24 11:41:36 2006
+++ llvm/lib/Target/Alpha/AlphaInstrInfo.h Tue Oct 31 10:49:55 2006
@@ -42,6 +42,14 @@
virtual void InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const std::vector<MachineOperand> &Cond) const;
+ bool AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
+ MachineBasicBlock *&FBB,
+ std::vector<MachineOperand> &Cond) const;
+ void RemoveBranch(MachineBasicBlock &MBB) const;
+ void insertNoop(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const;
+ bool BlockHasNoFallThrough(MachineBasicBlock &MBB) const;
+ bool ReverseBranchCondition(std::vector<MachineOperand> &Cond) const;
};
}
Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td
diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.130 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.131
--- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.130 Fri Oct 13 16:14:26 2006
+++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Tue Oct 31 10:49:55 2006
@@ -847,120 +847,173 @@
/////////////////////////////////////////////////////////
//Branching
/////////////////////////////////////////////////////////
+class br_icc<bits<6> opc, string asmstr>
+ : BFormN<opc, (ops u64imm:$opc, GPRC:$R, target:$dst),
+ !strconcat(asmstr, " $R,$dst"), s_icbr>;
+class br_fcc<bits<6> opc, string asmstr>
+ : BFormN<opc, (ops u64imm:$opc, F8RC:$R, target:$dst),
+ !strconcat(asmstr, " $R,$dst"), s_fbr>;
+
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in {
let Ra = 31 in
def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
+def COND_BRANCH_I : BFormN<0, (ops u64imm:$opc, GPRC:$R, target:$dst),
+ "{:comment} COND_BRANCH imm:$opc, GPRC:$R, bb:$dst",
+ s_icbr>;
+def COND_BRANCH_F : BFormN<0, (ops u64imm:$opc, F8RC:$R, target:$dst),
+ "{:comment} COND_BRANCH imm:$opc, F8RC:$R, bb:$dst",
+ s_fbr>;
//Branches, int
-def BEQ : BForm<0x39, "beq $RA,$DISP",
- [(brcond (seteq GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BGE : BForm<0x3E, "bge $RA,$DISP",
- [(brcond (setge GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BGT : BForm<0x3F, "bgt $RA,$DISP",
- [(brcond (setgt GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BLBC : BForm<0x38, "blbc $RA,$DISP", [], s_icbr>; //TODO: Low bit clear
-def BLBS : BForm<0x3C, "blbs $RA,$DISP",
- [(brcond (and GPRC:$RA, 1), bb:$DISP)], s_icbr>;
-def BLE : BForm<0x3B, "ble $RA,$DISP",
- [(brcond (setle GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BLT : BForm<0x3A, "blt $RA,$DISP",
- [(brcond (setlt GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BNE : BForm<0x3D, "bne $RA,$DISP",
- [(brcond (setne GPRC:$RA, 0), bb:$DISP)], s_icbr>;
+def BEQ : br_icc<0x39, "beq">;
+def BGE : br_icc<0x3E, "bge">;
+def BGT : br_icc<0x3F, "bgt">;
+def BLBC : br_icc<0x38, "blbc">;
+def BLBS : br_icc<0x3C, "blbs">;
+def BLE : br_icc<0x3B, "ble">;
+def BLT : br_icc<0x3A, "blt">;
+def BNE : br_icc<0x3D, "bne">;
//Branches, float
-def FBEQ : FBForm<0x31, "fbeq $RA,$DISP",
- [(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBGE : FBForm<0x36, "fbge $RA,$DISP",
- [(brcond (setge F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBGT : FBForm<0x37, "fbgt $RA,$DISP",
- [(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBLE : FBForm<0x33, "fble $RA,$DISP",
- [(brcond (setle F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBLT : FBForm<0x32, "fblt $RA,$DISP",
- [(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBNE : FBForm<0x35, "fbne $RA,$DISP",
- [(brcond (setne F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
+def FBEQ : br_fcc<0x31, "fbeq">;
+def FBGE : br_fcc<0x36, "fbge">;
+def FBGT : br_fcc<0x37, "fbgt">;
+def FBLE : br_fcc<0x33, "fble">;
+def FBLT : br_fcc<0x32, "fblt">;
+def FBNE : br_fcc<0x36, "fbne">;
}
-def : Pat<(brcond GPRC:$RA, bb:$DISP), (BNE GPRC:$RA, bb:$DISP)>;
-def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
- (BEQ (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
- (BEQ (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
-
-def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-
-def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-
-def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-
-def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-
-def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-
-def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBEQ (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBEQ (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBEQ (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-
-
-def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP),
- (FBEQ F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP),
- (FBEQ F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP),
- (FBGE F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP),
- (FBGE F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP),
- (FBGT F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP),
- (FBGT F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP),
- (FBLE F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP),
- (FBLE F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP),
- (FBLT F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP),
- (FBLT F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP),
- (FBNE F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP),
- (FBNE F8RC:$RA,bb:$DISP)>;
+//An ugly trick to get the opcode as an imm I can use
+def immBRCond : SDNodeXForm<imm, [{
+ switch((uint64_t)N->getValue()) {
+ case 0: return getI64Imm(Alpha::BEQ);
+ case 1: return getI64Imm(Alpha::BNE);
+ case 2: return getI64Imm(Alpha::BGE);
+ case 3: return getI64Imm(Alpha::BGT);
+ case 4: return getI64Imm(Alpha::BLE);
+ case 5: return getI64Imm(Alpha::BLT);
+ case 6: return getI64Imm(Alpha::BLBS);
+ case 7: return getI64Imm(Alpha::BLBC);
+ case 20: return getI64Imm(Alpha::FBEQ);
+ case 21: return getI64Imm(Alpha::FBNE);
+ case 22: return getI64Imm(Alpha::FBGE);
+ case 23: return getI64Imm(Alpha::FBGT);
+ case 24: return getI64Imm(Alpha::FBLE);
+ case 25: return getI64Imm(Alpha::FBLT);
+ default: assert(0 && "Unknown branch type");
+ }
+}]>;
+
+//Int cond patterns
+def : Pat<(brcond (seteq GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 0), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setge GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 2), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setgt GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 3), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (and GPRC:$RA, 1), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 6), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setle GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 4), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setlt GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 5), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setne GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
+
+def : Pat<(brcond GPRC:$RA, bb:$DISP),
+ (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 0), (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 0), (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
+
+//FP cond patterns
+def : Pat<(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setne F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setge F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 22), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 23), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setle F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 24), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 25), F8RC:$RA, bb:$DISP)>;
+
+
+def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+
+def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+
+def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+
+def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+
+def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+
+def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+
+
+def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
//End Branches
Index: llvm/lib/Target/Alpha/AlphaTargetMachine.cpp
diff -u llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.34 llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.35
--- llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.34 Tue Oct 10 23:29:42 2006
+++ llvm/lib/Target/Alpha/AlphaTargetMachine.cpp Tue Oct 31 10:49:55 2006
@@ -74,7 +74,7 @@
}
bool AlphaTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
// Must run branch selection immediately preceding the asm printer
- //PM.add(createAlphaBranchSelectionPass());
+ PM.add(createAlphaBranchSelectionPass());
return false;
}
bool AlphaTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
More information about the llvm-commits
mailing list