mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-23 12:08:25 +00:00
Go through all kinds of trouble to mark 'blr' as having a predicate operand
that takes a register and condition code. Print these pieces of BLR the right way, even though it is currently set to 'always'. Next up: get the JIT encoding right, then enhance branch folding to produce predicated blr for simple examples. llvm-svn: 31449
This commit is contained in:
parent
8dac4564af
commit
a7687f805c
@ -17,12 +17,30 @@
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class PPCTargetMachine;
|
||||
class FunctionPassManager;
|
||||
class FunctionPass;
|
||||
class MachineCodeEmitter;
|
||||
// GCC #defines PPC on Linux but we use it as our namespace name
|
||||
#undef PPC
|
||||
|
||||
namespace llvm {
|
||||
class PPCTargetMachine;
|
||||
class FunctionPassManager;
|
||||
class FunctionPass;
|
||||
class MachineCodeEmitter;
|
||||
|
||||
namespace PPC {
|
||||
/// Predicate - These are "(BO << 5) | BI" for various predicates.
|
||||
enum Predicate {
|
||||
PRED_ALWAYS = (20 << 5) | 0,
|
||||
PRED_LT = (12 << 5) | 0,
|
||||
PRED_LE = ( 4 << 5) | 1,
|
||||
PRED_EQ = (12 << 5) | 2,
|
||||
PRED_GE = ( 4 << 5) | 0,
|
||||
PRED_GT = (12 << 5) | 1,
|
||||
PRED_NE = ( 4 << 5) | 2,
|
||||
PRED_UN = (12 << 5) | 3,
|
||||
PRED_NU = ( 4 << 5) | 3
|
||||
};
|
||||
}
|
||||
|
||||
FunctionPass *createPPCBranchSelectionPass();
|
||||
FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
|
||||
@ -34,9 +52,6 @@ void addPPCMachOObjectWriterPass(FunctionPassManager &FPM, std::ostream &o,
|
||||
PPCTargetMachine &tm);
|
||||
} // end namespace llvm;
|
||||
|
||||
// GCC #defines PPC on Linux but we use it as our namespace name
|
||||
#undef PPC
|
||||
|
||||
// Defines symbolic names for PowerPC registers. This defines a mapping from
|
||||
// register name to register number.
|
||||
//
|
||||
|
@ -236,6 +236,9 @@ namespace {
|
||||
printOperand(MI, OpNo+1);
|
||||
}
|
||||
|
||||
void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
const char *Modifier);
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &F) = 0;
|
||||
virtual bool doFinalization(Module &M) = 0;
|
||||
};
|
||||
@ -363,6 +366,33 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
return false;
|
||||
}
|
||||
|
||||
void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
const char *Modifier) {
|
||||
assert(Modifier && "Must specify 'cc' or 'reg' as predicate op modifier!");
|
||||
unsigned Code = MI->getOperand(OpNo).getImm();
|
||||
if (!strcmp(Modifier, "cc")) {
|
||||
switch ((PPC::Predicate)Code) {
|
||||
case PPC::PRED_ALWAYS: return; // Don't print anything for always.
|
||||
case PPC::PRED_LT: O << "lt"; return;
|
||||
case PPC::PRED_LE: O << "le"; return;
|
||||
case PPC::PRED_EQ: O << "eq"; return;
|
||||
case PPC::PRED_GE: O << "ge"; return;
|
||||
case PPC::PRED_GT: O << "gt"; return;
|
||||
case PPC::PRED_NE: O << "ne"; return;
|
||||
case PPC::PRED_UN: O << "un"; return;
|
||||
case PPC::PRED_NU: O << "nu"; return;
|
||||
}
|
||||
|
||||
} else {
|
||||
assert(!strcmp(Modifier, "reg") &&
|
||||
"Need to specify 'cc' or 'reg' as predicate op modifier!");
|
||||
// Don't print the register for 'always'.
|
||||
if (Code == PPC::PRED_ALWAYS) return;
|
||||
printOperand(MI, OpNo+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
|
||||
/// the current output stream.
|
||||
///
|
||||
|
@ -255,9 +255,11 @@ def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits.
|
||||
let MIOperandInfo = (ops i32imm, ptr_rc);
|
||||
}
|
||||
|
||||
// PowerPC Predicate operand. 20 = always, CR0 is a dummy reg that doesn't
|
||||
// matter.
|
||||
def pred : PredicateOperand<(ops imm, CRRC), (ops 20, CR0)>;
|
||||
// PowerPC Predicate operand. 640 = ((20<<5)|0) = always, CR0 is a dummy reg
|
||||
// that doesn't matter.
|
||||
def pred : PredicateOperand<(ops imm, CRRC), (ops (i32 640), CR0)> {
|
||||
let PrintMethod = "printPredicateOperand";
|
||||
}
|
||||
|
||||
// Define PowerPC specific addressing mode.
|
||||
def iaddr : ComplexPattern<iPTR, 2, "SelectAddrImm", [], []>;
|
||||
@ -315,10 +317,13 @@ let usesCustomDAGSchedInserter = 1, // Expanded by the scheduler.
|
||||
|
||||
let isTerminator = 1, isBarrier = 1, noResults = 1, PPC970_Unit = 7 in {
|
||||
let isReturn = 1 in
|
||||
def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(retflag)]>;
|
||||
def BLR : XLForm_2_ext<19, 16, 20, 0, 0,
|
||||
(ops pred:$p),
|
||||
"b${p:cc}lr ${p:reg}", BrB, [(retflag)]>;
|
||||
def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB, []>;
|
||||
}
|
||||
|
||||
|
||||
let Defs = [LR] in
|
||||
def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>,
|
||||
PPC970_Unit_BRU;
|
||||
|
Loading…
Reference in New Issue
Block a user