mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-28 07:17:32 +00:00
First bits of 64 bit PowerPC stuff, currently disabled. A lot of this is
purely mechanical. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23778 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -27,8 +27,8 @@ enum PPCTargetEnum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
FunctionPass *createPPCBranchSelectionPass();
|
FunctionPass *createPPCBranchSelectionPass();
|
||||||
FunctionPass *createPPC32ISelPattern(TargetMachine &TM);
|
FunctionPass *createPPCISelPattern(TargetMachine &TM);
|
||||||
FunctionPass *createPPC32ISelDag(TargetMachine &TM);
|
FunctionPass *createPPCISelDag(TargetMachine &TM);
|
||||||
FunctionPass *createDarwinAsmPrinter(std::ostream &OS, TargetMachine &TM);
|
FunctionPass *createDarwinAsmPrinter(std::ostream &OS, TargetMachine &TM);
|
||||||
FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM);
|
FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM);
|
||||||
|
|
||||||
|
@@ -33,14 +33,14 @@ namespace {
|
|||||||
Statistic<> FrameOff("ppc-codegen", "Number of frame idx offsets collapsed");
|
Statistic<> FrameOff("ppc-codegen", "Number of frame idx offsets collapsed");
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
/// PPC32DAGToDAGISel - PPC32 specific code to select PPC32 machine
|
/// PPCDAGToDAGISel - PPC specific code to select PPC machine
|
||||||
/// instructions for SelectionDAG operations.
|
/// instructions for SelectionDAG operations.
|
||||||
///
|
///
|
||||||
class PPC32DAGToDAGISel : public SelectionDAGISel {
|
class PPCDAGToDAGISel : public SelectionDAGISel {
|
||||||
PPCTargetLowering PPCLowering;
|
PPCTargetLowering PPCLowering;
|
||||||
unsigned GlobalBaseReg;
|
unsigned GlobalBaseReg;
|
||||||
public:
|
public:
|
||||||
PPC32DAGToDAGISel(TargetMachine &TM)
|
PPCDAGToDAGISel(TargetMachine &TM)
|
||||||
: SelectionDAGISel(PPCLowering), PPCLowering(TM) {}
|
: SelectionDAGISel(PPCLowering), PPCLowering(TM) {}
|
||||||
|
|
||||||
virtual bool runOnFunction(Function &Fn) {
|
virtual bool runOnFunction(Function &Fn) {
|
||||||
@@ -99,7 +99,7 @@ private:
|
|||||||
|
|
||||||
/// InstructionSelectBasicBlock - This callback is invoked by
|
/// InstructionSelectBasicBlock - This callback is invoked by
|
||||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||||
void PPC32DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||||
DEBUG(BB->dump());
|
DEBUG(BB->dump());
|
||||||
|
|
||||||
// The selection process is inherently a bottom-up recursive process (users
|
// The selection process is inherently a bottom-up recursive process (users
|
||||||
@@ -156,13 +156,15 @@ void PPC32DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
/// getGlobalBaseReg - Output the instructions required to put the
|
/// getGlobalBaseReg - Output the instructions required to put the
|
||||||
/// base address to use for accessing globals into a register.
|
/// base address to use for accessing globals into a register.
|
||||||
///
|
///
|
||||||
SDOperand PPC32DAGToDAGISel::getGlobalBaseReg() {
|
SDOperand PPCDAGToDAGISel::getGlobalBaseReg() {
|
||||||
if (!GlobalBaseReg) {
|
if (!GlobalBaseReg) {
|
||||||
// Insert the set of GlobalBaseReg into the first MBB of the function
|
// Insert the set of GlobalBaseReg into the first MBB of the function
|
||||||
MachineBasicBlock &FirstMBB = BB->getParent()->front();
|
MachineBasicBlock &FirstMBB = BB->getParent()->front();
|
||||||
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
||||||
SSARegMap *RegMap = BB->getParent()->getSSARegMap();
|
SSARegMap *RegMap = BB->getParent()->getSSARegMap();
|
||||||
GlobalBaseReg = RegMap->createVirtualRegister(PPC32::GPRCRegisterClass);
|
// FIXME: when we get to LP64, we will need to create the appropriate
|
||||||
|
// type of register here.
|
||||||
|
GlobalBaseReg = RegMap->createVirtualRegister(PPC::GPRCRegisterClass);
|
||||||
BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
|
BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
|
||||||
BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg);
|
BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg);
|
||||||
}
|
}
|
||||||
@@ -290,7 +292,7 @@ static bool isIntImmediate(SDOperand N, unsigned& Imm) {
|
|||||||
/// 2. or and, shl 6. or shl, shr
|
/// 2. or and, shl 6. or shl, shr
|
||||||
/// 3. or shr, and 7. or shr, shl
|
/// 3. or shr, and 7. or shr, shl
|
||||||
/// 4. or and, shr
|
/// 4. or and, shr
|
||||||
SDNode *PPC32DAGToDAGISel::SelectBitfieldInsert(SDNode *N) {
|
SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) {
|
||||||
bool IsRotate = false;
|
bool IsRotate = false;
|
||||||
unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, SH = 0;
|
unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, SH = 0;
|
||||||
unsigned Value;
|
unsigned Value;
|
||||||
@@ -392,8 +394,8 @@ SDNode *PPC32DAGToDAGISel::SelectBitfieldInsert(SDNode *N) {
|
|||||||
/// SelectAddr - Given the specified address, return the two operands for a
|
/// SelectAddr - Given the specified address, return the two operands for a
|
||||||
/// load/store instruction, and return true if it should be an indexed [r+r]
|
/// load/store instruction, and return true if it should be an indexed [r+r]
|
||||||
/// operation.
|
/// operation.
|
||||||
bool PPC32DAGToDAGISel::SelectAddr(SDOperand Addr, SDOperand &Op1,
|
bool PPCDAGToDAGISel::SelectAddr(SDOperand Addr, SDOperand &Op1,
|
||||||
SDOperand &Op2) {
|
SDOperand &Op2) {
|
||||||
unsigned imm = 0;
|
unsigned imm = 0;
|
||||||
if (Addr.getOpcode() == ISD::ADD) {
|
if (Addr.getOpcode() == ISD::ADD) {
|
||||||
if (isIntImmediate(Addr.getOperand(1), imm) && isInt16(imm)) {
|
if (isIntImmediate(Addr.getOperand(1), imm) && isInt16(imm)) {
|
||||||
@@ -445,8 +447,8 @@ bool PPC32DAGToDAGISel::SelectAddr(SDOperand Addr, SDOperand &Op1,
|
|||||||
|
|
||||||
/// SelectCC - Select a comparison of the specified values with the specified
|
/// SelectCC - Select a comparison of the specified values with the specified
|
||||||
/// condition code, returning the CR# of the expression.
|
/// condition code, returning the CR# of the expression.
|
||||||
SDOperand PPC32DAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
|
SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
|
||||||
ISD::CondCode CC) {
|
ISD::CondCode CC) {
|
||||||
// Always select the LHS.
|
// Always select the LHS.
|
||||||
LHS = Select(LHS);
|
LHS = Select(LHS);
|
||||||
|
|
||||||
@@ -604,7 +606,7 @@ static struct mu magicu(unsigned d)
|
|||||||
/// return a DAG expression to select that will generate the same value by
|
/// return a DAG expression to select that will generate the same value by
|
||||||
/// multiplying by a magic number. See:
|
/// multiplying by a magic number. See:
|
||||||
/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
|
/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
|
||||||
SDOperand PPC32DAGToDAGISel::BuildSDIVSequence(SDNode *N) {
|
SDOperand PPCDAGToDAGISel::BuildSDIVSequence(SDNode *N) {
|
||||||
int d = (int)cast<ConstantSDNode>(N->getOperand(1))->getValue();
|
int d = (int)cast<ConstantSDNode>(N->getOperand(1))->getValue();
|
||||||
ms magics = magic(d);
|
ms magics = magic(d);
|
||||||
// Multiply the numerator (operand 0) by the magic value
|
// Multiply the numerator (operand 0) by the magic value
|
||||||
@@ -630,7 +632,7 @@ SDOperand PPC32DAGToDAGISel::BuildSDIVSequence(SDNode *N) {
|
|||||||
/// return a DAG expression to select that will generate the same value by
|
/// return a DAG expression to select that will generate the same value by
|
||||||
/// multiplying by a magic number. See:
|
/// multiplying by a magic number. See:
|
||||||
/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
|
/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
|
||||||
SDOperand PPC32DAGToDAGISel::BuildUDIVSequence(SDNode *N) {
|
SDOperand PPCDAGToDAGISel::BuildUDIVSequence(SDNode *N) {
|
||||||
unsigned d = (unsigned)cast<ConstantSDNode>(N->getOperand(1))->getValue();
|
unsigned d = (unsigned)cast<ConstantSDNode>(N->getOperand(1))->getValue();
|
||||||
mu magics = magicu(d);
|
mu magics = magicu(d);
|
||||||
// Multiply the numerator (operand 0) by the magic value
|
// Multiply the numerator (operand 0) by the magic value
|
||||||
@@ -649,7 +651,7 @@ SDOperand PPC32DAGToDAGISel::BuildUDIVSequence(SDNode *N) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDOperand PPC32DAGToDAGISel::SelectDYNAMIC_STACKALLOC(SDOperand Op) {
|
SDOperand PPCDAGToDAGISel::SelectDYNAMIC_STACKALLOC(SDOperand Op) {
|
||||||
SDNode *N = Op.Val;
|
SDNode *N = Op.Val;
|
||||||
|
|
||||||
// FIXME: We are currently ignoring the requested alignment for handling
|
// FIXME: We are currently ignoring the requested alignment for handling
|
||||||
@@ -686,7 +688,7 @@ SDOperand PPC32DAGToDAGISel::SelectDYNAMIC_STACKALLOC(SDOperand Op) {
|
|||||||
return SDOperand(Result.Val, Op.ResNo);
|
return SDOperand(Result.Val, Op.ResNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDOperand PPC32DAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
|
SDOperand PPCDAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
|
||||||
SDNode *N = Op.Val;
|
SDNode *N = Op.Val;
|
||||||
SDOperand LHSL = Select(N->getOperand(0));
|
SDOperand LHSL = Select(N->getOperand(0));
|
||||||
SDOperand LHSH = Select(N->getOperand(1));
|
SDOperand LHSH = Select(N->getOperand(1));
|
||||||
@@ -729,7 +731,7 @@ SDOperand PPC32DAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
|
|||||||
CodeGenMap[Op.getValue(1)] = Result[1];
|
CodeGenMap[Op.getValue(1)] = Result[1];
|
||||||
return Result[Op.ResNo];
|
return Result[Op.ResNo];
|
||||||
}
|
}
|
||||||
SDOperand PPC32DAGToDAGISel::SelectSUB_PARTS(SDOperand Op) {
|
SDOperand PPCDAGToDAGISel::SelectSUB_PARTS(SDOperand Op) {
|
||||||
SDNode *N = Op.Val;
|
SDNode *N = Op.Val;
|
||||||
SDOperand LHSL = Select(N->getOperand(0));
|
SDOperand LHSL = Select(N->getOperand(0));
|
||||||
SDOperand LHSH = Select(N->getOperand(1));
|
SDOperand LHSH = Select(N->getOperand(1));
|
||||||
@@ -746,7 +748,7 @@ SDOperand PPC32DAGToDAGISel::SelectSUB_PARTS(SDOperand Op) {
|
|||||||
return Result[Op.ResNo];
|
return Result[Op.ResNo];
|
||||||
}
|
}
|
||||||
|
|
||||||
SDOperand PPC32DAGToDAGISel::SelectSETCC(SDOperand Op) {
|
SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) {
|
||||||
SDNode *N = Op.Val;
|
SDNode *N = Op.Val;
|
||||||
unsigned Imm;
|
unsigned Imm;
|
||||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
||||||
@@ -854,7 +856,7 @@ SDOperand PPC32DAGToDAGISel::SelectSETCC(SDOperand Op) {
|
|||||||
return SDOperand(N, 0);
|
return SDOperand(N, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDOperand PPC32DAGToDAGISel::SelectCALL(SDOperand Op) {
|
SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||||
SDNode *N = Op.Val;
|
SDNode *N = Op.Val;
|
||||||
SDOperand Chain = Select(N->getOperand(0));
|
SDOperand Chain = Select(N->getOperand(0));
|
||||||
|
|
||||||
@@ -963,7 +965,7 @@ SDOperand PPC32DAGToDAGISel::SelectCALL(SDOperand Op) {
|
|||||||
|
|
||||||
// Select - Convert the specified operand from a target-independent to a
|
// Select - Convert the specified operand from a target-independent to a
|
||||||
// target-specific node if it hasn't already been changed.
|
// target-specific node if it hasn't already been changed.
|
||||||
SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||||
SDNode *N = Op.Val;
|
SDNode *N = Op.Val;
|
||||||
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
|
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
|
||||||
N->getOpcode() < PPCISD::FIRST_NUMBER)
|
N->getOpcode() < PPCISD::FIRST_NUMBER)
|
||||||
@@ -1391,6 +1393,11 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
SDOperand Val = Select(N->getOperand(1));
|
SDOperand Val = Select(N->getOperand(1));
|
||||||
if (N->getOperand(1).getValueType() == MVT::i32) {
|
if (N->getOperand(1).getValueType() == MVT::i32) {
|
||||||
Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val);
|
Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val);
|
||||||
|
} else if (N->getOperand(1).getValueType() == MVT::i64) {
|
||||||
|
SDOperand Srl = CurDAG->getTargetNode(PPC::RLDICL, MVT::i64, Val,
|
||||||
|
getI32Imm(32), getI32Imm(32));
|
||||||
|
Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Val);
|
||||||
|
Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Srl);
|
||||||
} else {
|
} else {
|
||||||
assert(MVT::isFloatingPoint(N->getOperand(1).getValueType()));
|
assert(MVT::isFloatingPoint(N->getOperand(1).getValueType()));
|
||||||
Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val);
|
Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val);
|
||||||
@@ -1465,10 +1472,10 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// createPPC32ISelDag - This pass converts a legalized DAG into a
|
/// createPPCISelDag - This pass converts a legalized DAG into a
|
||||||
/// PowerPC-specific DAG, ready for instruction scheduling.
|
/// PowerPC-specific DAG, ready for instruction scheduling.
|
||||||
///
|
///
|
||||||
FunctionPass *llvm::createPPC32ISelDag(TargetMachine &TM) {
|
FunctionPass *llvm::createPPCISelDag(TargetMachine &TM) {
|
||||||
return new PPC32DAGToDAGISel(TM);
|
return new PPCDAGToDAGISel(TM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
//===-- PPCISelLowering.cpp - PPC32 DAG Lowering Implementation -----------===//
|
//===-- PPCISelLowering.cpp - PPC DAG Lowering Implementation -------------===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
@@ -32,9 +32,9 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
|
|||||||
setUseUnderscoreSetJmpLongJmp(true);
|
setUseUnderscoreSetJmpLongJmp(true);
|
||||||
|
|
||||||
// Set up the register classes.
|
// Set up the register classes.
|
||||||
addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass);
|
addRegisterClass(MVT::i32, PPC::GPRCRegisterClass);
|
||||||
addRegisterClass(MVT::f32, PPC32::F4RCRegisterClass);
|
addRegisterClass(MVT::f32, PPC::F4RCRegisterClass);
|
||||||
addRegisterClass(MVT::f64, PPC32::F8RCRegisterClass);
|
addRegisterClass(MVT::f64, PPC::F8RCRegisterClass);
|
||||||
|
|
||||||
// PowerPC has no intrinsics for these particular operations
|
// PowerPC has no intrinsics for these particular operations
|
||||||
setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
|
setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
|
||||||
@@ -76,11 +76,6 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
|
|||||||
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
|
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
|
||||||
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
|
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
|
||||||
|
|
||||||
// PowerPC wants to expand i64 shifts itself.
|
|
||||||
setOperationAction(ISD::SHL, MVT::i64, Custom);
|
|
||||||
setOperationAction(ISD::SRL, MVT::i64, Custom);
|
|
||||||
setOperationAction(ISD::SRA, MVT::i64, Custom);
|
|
||||||
|
|
||||||
// PowerPC does not have BRCOND* which requires SetCC
|
// PowerPC does not have BRCOND* which requires SetCC
|
||||||
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
|
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
|
||||||
@@ -98,11 +93,25 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
|
|||||||
// PowerPC does not have truncstore for i1.
|
// PowerPC does not have truncstore for i1.
|
||||||
setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote);
|
setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote);
|
||||||
|
|
||||||
// 64 bit PowerPC implementations have instructions to facilitate conversion
|
|
||||||
// between i64 and fp.
|
|
||||||
if (TM.getSubtarget<PPCSubtarget>().is64Bit()) {
|
if (TM.getSubtarget<PPCSubtarget>().is64Bit()) {
|
||||||
|
// 64 bit PowerPC implementations can support i64 types directly
|
||||||
|
// FIXME: enable this once it works.
|
||||||
|
//addRegisterClass(MVT::i64, PPC::G8RCRegisterClass);
|
||||||
|
// They also have instructions for converting between i64 and fp.
|
||||||
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
|
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
|
||||||
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
|
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
|
||||||
|
// BUILD_PAIR can't be handled natively, and should be expanded to shl/or
|
||||||
|
setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
|
||||||
|
// 32 bit PowerPC wants to expand i64 shifts itself.
|
||||||
|
// FIXME: remove these once we natively handle i64 shifts.
|
||||||
|
setOperationAction(ISD::SHL, MVT::i64, Custom);
|
||||||
|
setOperationAction(ISD::SRL, MVT::i64, Custom);
|
||||||
|
setOperationAction(ISD::SRA, MVT::i64, Custom);
|
||||||
|
} else {
|
||||||
|
// 32 bit PowerPC wants to expand i64 shifts itself.
|
||||||
|
setOperationAction(ISD::SHL, MVT::i64, Custom);
|
||||||
|
setOperationAction(ISD::SRL, MVT::i64, Custom);
|
||||||
|
setOperationAction(ISD::SRA, MVT::i64, Custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSetCCResultContents(ZeroOrOneSetCCResult);
|
setSetCCResultContents(ZeroOrOneSetCCResult);
|
||||||
@@ -353,7 +362,7 @@ PPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
ObjSize = 4;
|
ObjSize = 4;
|
||||||
if (!ArgLive) break;
|
if (!ArgLive) break;
|
||||||
if (GPR_remaining > 0) {
|
if (GPR_remaining > 0) {
|
||||||
unsigned VReg = RegMap->createVirtualRegister(&PPC32::GPRCRegClass);
|
unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
|
||||||
MF.addLiveIn(GPR[GPR_idx], VReg);
|
MF.addLiveIn(GPR[GPR_idx], VReg);
|
||||||
argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
|
argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
|
||||||
if (ObjectVT != MVT::i32) {
|
if (ObjectVT != MVT::i32) {
|
||||||
@@ -371,7 +380,7 @@ PPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
if (!ArgLive) break;
|
if (!ArgLive) break;
|
||||||
if (GPR_remaining > 0) {
|
if (GPR_remaining > 0) {
|
||||||
SDOperand argHi, argLo;
|
SDOperand argHi, argLo;
|
||||||
unsigned VReg = RegMap->createVirtualRegister(&PPC32::GPRCRegClass);
|
unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
|
||||||
MF.addLiveIn(GPR[GPR_idx], VReg);
|
MF.addLiveIn(GPR[GPR_idx], VReg);
|
||||||
argHi = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
|
argHi = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
|
||||||
// If we have two or more remaining argument registers, then both halves
|
// If we have two or more remaining argument registers, then both halves
|
||||||
@@ -379,7 +388,7 @@ PPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
// have to come off the stack. This can happen when an i64 is preceded
|
// have to come off the stack. This can happen when an i64 is preceded
|
||||||
// by 28 bytes of arguments.
|
// by 28 bytes of arguments.
|
||||||
if (GPR_remaining > 1) {
|
if (GPR_remaining > 1) {
|
||||||
unsigned VReg = RegMap->createVirtualRegister(&PPC32::GPRCRegClass);
|
unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
|
||||||
MF.addLiveIn(GPR[GPR_idx+1], VReg);
|
MF.addLiveIn(GPR[GPR_idx+1], VReg);
|
||||||
argLo = DAG.getCopyFromReg(argHi, VReg, MVT::i32);
|
argLo = DAG.getCopyFromReg(argHi, VReg, MVT::i32);
|
||||||
} else {
|
} else {
|
||||||
@@ -402,9 +411,9 @@ PPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
if (FPR_remaining > 0) {
|
if (FPR_remaining > 0) {
|
||||||
unsigned VReg;
|
unsigned VReg;
|
||||||
if (ObjectVT == MVT::f32)
|
if (ObjectVT == MVT::f32)
|
||||||
VReg = RegMap->createVirtualRegister(&PPC32::F4RCRegClass);
|
VReg = RegMap->createVirtualRegister(&PPC::F4RCRegClass);
|
||||||
else
|
else
|
||||||
VReg = RegMap->createVirtualRegister(&PPC32::F8RCRegClass);
|
VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass);
|
||||||
MF.addLiveIn(FPR[FPR_idx], VReg);
|
MF.addLiveIn(FPR[FPR_idx], VReg);
|
||||||
argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, ObjectVT);
|
argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, ObjectVT);
|
||||||
--FPR_remaining;
|
--FPR_remaining;
|
||||||
@@ -453,7 +462,7 @@ PPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
// result of va_next.
|
// result of va_next.
|
||||||
std::vector<SDOperand> MemOps;
|
std::vector<SDOperand> MemOps;
|
||||||
for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
|
for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
|
||||||
unsigned VReg = RegMap->createVirtualRegister(&PPC32::GPRCRegClass);
|
unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
|
||||||
MF.addLiveIn(GPR[GPR_idx], VReg);
|
MF.addLiveIn(GPR[GPR_idx], VReg);
|
||||||
SDOperand Val = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
|
SDOperand Val = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
|
||||||
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
|
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
|
||||||
|
@@ -84,7 +84,7 @@ public:
|
|||||||
|
|
||||||
// convenience functions for virtual register creation
|
// convenience functions for virtual register creation
|
||||||
inline unsigned MakeIntReg() {
|
inline unsigned MakeIntReg() {
|
||||||
return RegMap->createVirtualRegister(PPC32::GPRCRegisterClass);
|
return RegMap->createVirtualRegister(PPC::GPRCRegisterClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dag -> dag expanders for integer divide by constant
|
// dag -> dag expanders for integer divide by constant
|
||||||
@@ -591,7 +591,7 @@ unsigned ISel::SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC) {
|
|||||||
bool AlreadySelected = false;
|
bool AlreadySelected = false;
|
||||||
|
|
||||||
// Allocate a condition register for this expression
|
// Allocate a condition register for this expression
|
||||||
Result = RegMap->createVirtualRegister(PPC32::CRRCRegisterClass);
|
Result = RegMap->createVirtualRegister(PPC::CRRCRegisterClass);
|
||||||
|
|
||||||
// Use U to determine whether the SETCC immediate range is signed or not.
|
// Use U to determine whether the SETCC immediate range is signed or not.
|
||||||
bool U = ISD::isUnsignedIntSetCC(CC);
|
bool U = ISD::isUnsignedIntSetCC(CC);
|
||||||
@@ -866,7 +866,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
// Subtract size from stack pointer, thereby allocating some space.
|
// Subtract size from stack pointer, thereby allocating some space.
|
||||||
BuildMI(BB, PPC::SUBF, 2, PPC::R1).addReg(Tmp1).addReg(PPC::R1);
|
BuildMI(BB, PPC::SUBF, 2, PPC::R1).addReg(Tmp1).addReg(PPC::R1);
|
||||||
// Put a pointer to the space into the result register by copying the SP
|
// Put a pointer to the space into the result register by copying the SP
|
||||||
BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R1).addReg(PPC::R1);
|
BuildMI(BB, PPC::OR4, 2, Result).addReg(PPC::R1).addReg(PPC::R1);
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
case ISD::ConstantPool:
|
case ISD::ConstantPool:
|
||||||
@@ -996,7 +996,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
} else {
|
} else {
|
||||||
Tmp1 = SelectExpr(N.getOperand(1));
|
Tmp1 = SelectExpr(N.getOperand(1));
|
||||||
BuildMI(BB, PPC::MTCTR, 1).addReg(Tmp1);
|
BuildMI(BB, PPC::MTCTR, 1).addReg(Tmp1);
|
||||||
BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
|
BuildMI(BB, PPC::OR4, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
|
||||||
CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
|
CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
|
||||||
.addReg(PPC::R12);
|
.addReg(PPC::R12);
|
||||||
}
|
}
|
||||||
@@ -1013,7 +1013,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
case MVT::i32:
|
case MVT::i32:
|
||||||
assert(GPR_idx < 8 && "Too many int args");
|
assert(GPR_idx < 8 && "Too many int args");
|
||||||
if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) {
|
if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) {
|
||||||
BuildMI(BB, PPC::OR,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]);
|
BuildMI(BB, PPC::OR4,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]);
|
||||||
CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
|
CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
|
||||||
}
|
}
|
||||||
++GPR_idx;
|
++GPR_idx;
|
||||||
@@ -1037,10 +1037,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
case MVT::Other: return 1;
|
case MVT::Other: return 1;
|
||||||
case MVT::i32:
|
case MVT::i32:
|
||||||
if (Node->getValueType(1) == MVT::i32) {
|
if (Node->getValueType(1) == MVT::i32) {
|
||||||
BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R3).addReg(PPC::R3);
|
BuildMI(BB, PPC::OR4, 2, Result+1).addReg(PPC::R3).addReg(PPC::R3);
|
||||||
BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R4).addReg(PPC::R4);
|
BuildMI(BB, PPC::OR4, 2, Result).addReg(PPC::R4).addReg(PPC::R4);
|
||||||
} else {
|
} else {
|
||||||
BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3);
|
BuildMI(BB, PPC::OR4, 2, Result).addReg(PPC::R3).addReg(PPC::R3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MVT::f32:
|
case MVT::f32:
|
||||||
@@ -1074,7 +1074,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
ExprMap[N.getValue(1)] = 1;
|
ExprMap[N.getValue(1)] = 1;
|
||||||
Tmp1 = dyn_cast<RegisterSDNode>(Node->getOperand(1))->getReg();
|
Tmp1 = dyn_cast<RegisterSDNode>(Node->getOperand(1))->getReg();
|
||||||
if (MVT::isInteger(DestType))
|
if (MVT::isInteger(DestType))
|
||||||
BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1);
|
BuildMI(BB, PPC::OR4, 2, Result).addReg(Tmp1).addReg(Tmp1);
|
||||||
else if (DestType == MVT::f32)
|
else if (DestType == MVT::f32)
|
||||||
BuildMI(BB, PPC::FMRS, 1, Result).addReg(Tmp1);
|
BuildMI(BB, PPC::FMRS, 1, Result).addReg(Tmp1);
|
||||||
else
|
else
|
||||||
@@ -1144,7 +1144,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
return Result;
|
return Result;
|
||||||
Tmp1 = SelectExpr(N.getOperand(0));
|
Tmp1 = SelectExpr(N.getOperand(0));
|
||||||
Tmp2 = SelectExpr(N.getOperand(1));
|
Tmp2 = SelectExpr(N.getOperand(1));
|
||||||
BuildMI(BB, PPC::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2);
|
BuildMI(BB, PPC::ADD4, 2, Result).addReg(Tmp1).addReg(Tmp2);
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
case ISD::FADD:
|
case ISD::FADD:
|
||||||
@@ -1250,7 +1250,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
// emit regular or
|
// emit regular or
|
||||||
Tmp1 = SelectExpr(N.getOperand(0));
|
Tmp1 = SelectExpr(N.getOperand(0));
|
||||||
Tmp2 = SelectExpr(N.getOperand(1));
|
Tmp2 = SelectExpr(N.getOperand(1));
|
||||||
Opc = Recording ? PPC::ORo : PPC::OR;
|
Opc = Recording ? PPC::ORo : PPC::OR4;
|
||||||
RecordSuccess = true;
|
RecordSuccess = true;
|
||||||
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
|
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
|
||||||
return Result;
|
return Result;
|
||||||
@@ -1755,7 +1755,7 @@ void ISel::Select(SDOperand N) {
|
|||||||
else if (N.getOperand(2).getValueType() == MVT::f32)
|
else if (N.getOperand(2).getValueType() == MVT::f32)
|
||||||
BuildMI(BB, PPC::FMRS, 1, Tmp2).addReg(Tmp1);
|
BuildMI(BB, PPC::FMRS, 1, Tmp2).addReg(Tmp1);
|
||||||
else
|
else
|
||||||
BuildMI(BB, PPC::OR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
|
BuildMI(BB, PPC::OR4, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case ISD::ImplicitDef:
|
case ISD::ImplicitDef:
|
||||||
@@ -1779,8 +1779,8 @@ void ISel::Select(SDOperand N) {
|
|||||||
Select(N.getOperand(0));
|
Select(N.getOperand(0));
|
||||||
Tmp1 = SelectExpr(N.getOperand(1));
|
Tmp1 = SelectExpr(N.getOperand(1));
|
||||||
Tmp2 = SelectExpr(N.getOperand(2));
|
Tmp2 = SelectExpr(N.getOperand(2));
|
||||||
BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp2).addReg(Tmp2);
|
BuildMI(BB, PPC::OR4, 2, PPC::R3).addReg(Tmp2).addReg(Tmp2);
|
||||||
BuildMI(BB, PPC::OR, 2, PPC::R4).addReg(Tmp1).addReg(Tmp1);
|
BuildMI(BB, PPC::OR4, 2, PPC::R4).addReg(Tmp1).addReg(Tmp1);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
Select(N.getOperand(0));
|
Select(N.getOperand(0));
|
||||||
@@ -1795,7 +1795,7 @@ void ISel::Select(SDOperand N) {
|
|||||||
BuildMI(BB, PPC::FMRS, 1, PPC::F1).addReg(Tmp1);
|
BuildMI(BB, PPC::FMRS, 1, PPC::F1).addReg(Tmp1);
|
||||||
break;
|
break;
|
||||||
case MVT::i32:
|
case MVT::i32:
|
||||||
BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1);
|
BuildMI(BB, PPC::OR4, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
@@ -1870,11 +1870,11 @@ void ISel::Select(SDOperand N) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// createPPC32PatternInstructionSelector - This pass converts an LLVM function
|
/// createPPCPatternInstructionSelector - This pass converts an LLVM function
|
||||||
/// into a machine code representation using pattern matching and a machine
|
/// into a machine code representation using pattern matching and a machine
|
||||||
/// description file.
|
/// description file.
|
||||||
///
|
///
|
||||||
FunctionPass *llvm::createPPC32ISelPattern(TargetMachine &TM) {
|
FunctionPass *llvm::createPPCISelPattern(TargetMachine &TM) {
|
||||||
return new ISel(TM);
|
return new ISel(TM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@ bool PPCInstrInfo::isMoveInstr(const MachineInstr& MI,
|
|||||||
unsigned& sourceReg,
|
unsigned& sourceReg,
|
||||||
unsigned& destReg) const {
|
unsigned& destReg) const {
|
||||||
MachineOpCode oc = MI.getOpcode();
|
MachineOpCode oc = MI.getOpcode();
|
||||||
if (oc == PPC::OR) { // or r1, r2, r2
|
if (oc == PPC::OR4 || oc == PPC::OR8) { // or r1, r2, r2
|
||||||
assert(MI.getNumOperands() == 3 &&
|
assert(MI.getNumOperands() == 3 &&
|
||||||
MI.getOperand(0).isRegister() &&
|
MI.getOperand(0).isRegister() &&
|
||||||
MI.getOperand(1).isRegister() &&
|
MI.getOperand(1).isRegister() &&
|
||||||
|
@@ -323,9 +323,12 @@ def ANDo : XForm_6<31, 28, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
|||||||
def ANDC : XForm_6<31, 60, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
def ANDC : XForm_6<31, 60, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||||
"andc $rA, $rS, $rB",
|
"andc $rA, $rS, $rB",
|
||||||
[(set GPRC:$rA, (and GPRC:$rS, (not GPRC:$rB)))]>;
|
[(set GPRC:$rA, (and GPRC:$rS, (not GPRC:$rB)))]>;
|
||||||
def OR : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
def OR4 : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||||
"or $rA, $rS, $rB",
|
"or $rA, $rS, $rB",
|
||||||
[(set GPRC:$rA, (or GPRC:$rS, GPRC:$rB))]>;
|
[(set GPRC:$rA, (or GPRC:$rS, GPRC:$rB))]>;
|
||||||
|
def OR8 : XForm_6<31, 444, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
|
||||||
|
"or $rA, $rS, $rB",
|
||||||
|
[(set G8RC:$rA, (or G8RC:$rS, G8RC:$rB))]>;
|
||||||
def NOR : XForm_6<31, 124, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
def NOR : XForm_6<31, 124, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||||
"nor $rA, $rS, $rB",
|
"nor $rA, $rS, $rB",
|
||||||
[(set GPRC:$rA, (not (or GPRC:$rS, GPRC:$rB)))]>;
|
[(set GPRC:$rA, (not (or GPRC:$rS, GPRC:$rB)))]>;
|
||||||
@@ -498,9 +501,12 @@ def SRADI : XSForm_1<31, 413, (ops GPRC:$rA, GPRC:$rS, u6imm:$SH),
|
|||||||
|
|
||||||
// XO-Form instructions. Arithmetic instructions that can set overflow bit
|
// XO-Form instructions. Arithmetic instructions that can set overflow bit
|
||||||
//
|
//
|
||||||
def ADD : XOForm_1<31, 266, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
|
def ADD4 : XOForm_1<31, 266, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
|
||||||
"add $rT, $rA, $rB",
|
"add $rT, $rA, $rB",
|
||||||
[(set GPRC:$rT, (add GPRC:$rA, GPRC:$rB))]>;
|
[(set GPRC:$rT, (add GPRC:$rA, GPRC:$rB))]>;
|
||||||
|
def ADD8 : XOForm_1<31, 266, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB),
|
||||||
|
"add $rT, $rA, $rB",
|
||||||
|
[(set G8RC:$rT, (add G8RC:$rA, G8RC:$rB))]>;
|
||||||
def ADDC : XOForm_1<31, 10, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
|
def ADDC : XOForm_1<31, 10, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
|
||||||
"addc $rT, $rA, $rB",
|
"addc $rT, $rA, $rB",
|
||||||
[]>;
|
[]>;
|
||||||
@@ -648,6 +654,9 @@ let isTwoAddress = 1, isCommutable = 1 in {
|
|||||||
def RLWIMI : MForm_2<20,
|
def RLWIMI : MForm_2<20,
|
||||||
(ops GPRC:$rA, GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB,
|
(ops GPRC:$rA, GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB,
|
||||||
u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME">;
|
u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME">;
|
||||||
|
def RLDIMI : MDForm_1<30, 3,
|
||||||
|
(ops G8RC:$rA, G8RC:$rSi, G8RC:$rS, u6imm:$SH, u6imm:$MB),
|
||||||
|
"rldimi $rA, $rS, $SH, $MB">, isPPC64;
|
||||||
}
|
}
|
||||||
def RLWINM : MForm_2<21,
|
def RLWINM : MForm_2<21,
|
||||||
(ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
|
(ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
|
||||||
@@ -662,10 +671,10 @@ def RLWNM : MForm_2<23,
|
|||||||
// MD-Form instructions. 64 bit rotate instructions.
|
// MD-Form instructions. 64 bit rotate instructions.
|
||||||
//
|
//
|
||||||
def RLDICL : MDForm_1<30, 0,
|
def RLDICL : MDForm_1<30, 0,
|
||||||
(ops GPRC:$rA, GPRC:$rS, u6imm:$SH, u6imm:$MB),
|
(ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$MB),
|
||||||
"rldicl $rA, $rS, $SH, $MB">, isPPC64;
|
"rldicl $rA, $rS, $SH, $MB">, isPPC64;
|
||||||
def RLDICR : MDForm_1<30, 1,
|
def RLDICR : MDForm_1<30, 1,
|
||||||
(ops GPRC:$rA, GPRC:$rS, u6imm:$SH, u6imm:$ME),
|
(ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$ME),
|
||||||
"rldicr $rA, $rS, $SH, $ME">, isPPC64;
|
"rldicr $rA, $rS, $SH, $ME">, isPPC64;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@@ -40,7 +40,7 @@ PPCRegisterInfo::PPCRegisterInfo()
|
|||||||
ImmToIdxMap[PPC::LFS] = PPC::LFSX; ImmToIdxMap[PPC::LFD] = PPC::LFDX;
|
ImmToIdxMap[PPC::LFS] = PPC::LFSX; ImmToIdxMap[PPC::LFD] = PPC::LFDX;
|
||||||
ImmToIdxMap[PPC::STH] = PPC::STHX; ImmToIdxMap[PPC::STW] = PPC::STWX;
|
ImmToIdxMap[PPC::STH] = PPC::STHX; ImmToIdxMap[PPC::STW] = PPC::STWX;
|
||||||
ImmToIdxMap[PPC::STFS] = PPC::STFSX; ImmToIdxMap[PPC::STFD] = PPC::STFDX;
|
ImmToIdxMap[PPC::STFS] = PPC::STFSX; ImmToIdxMap[PPC::STFD] = PPC::STFDX;
|
||||||
ImmToIdxMap[PPC::ADDI] = PPC::ADD;
|
ImmToIdxMap[PPC::ADDI] = PPC::ADD4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -51,14 +51,16 @@ PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
|||||||
if (SrcReg == PPC::LR) {
|
if (SrcReg == PPC::LR) {
|
||||||
BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11);
|
BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11);
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
|
||||||
} else if (RC == PPC32::CRRCRegisterClass) {
|
} else if (RC == PPC::CRRCRegisterClass) {
|
||||||
BuildMI(MBB, MI, PPC::MFCR, 0, PPC::R11);
|
BuildMI(MBB, MI, PPC::MFCR, 0, PPC::R11);
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
|
||||||
} else if (RC == PPC32::GPRCRegisterClass) {
|
} else if (RC == PPC::GPRCRegisterClass) {
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx);
|
||||||
} else if (RC == PPC32::F8RCRegisterClass) {
|
} else if (RC == PPC::G8RCRegisterClass) {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::STD, 3).addReg(SrcReg),FrameIdx);
|
||||||
|
} else if (RC == PPC::F8RCRegisterClass) {
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx);
|
||||||
} else if (RC == PPC32::F4RCRegisterClass) {
|
} else if (RC == PPC::F4RCRegisterClass) {
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx);
|
||||||
} else {
|
} else {
|
||||||
assert(0 && "Unknown regclass!");
|
assert(0 && "Unknown regclass!");
|
||||||
@@ -74,14 +76,16 @@ PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
|||||||
if (DestReg == PPC::LR) {
|
if (DestReg == PPC::LR) {
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
|
||||||
BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
|
BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
|
||||||
} else if (RC == PPC32::CRRCRegisterClass) {
|
} else if (RC == PPC::CRRCRegisterClass) {
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
|
||||||
BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R11);
|
BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R11);
|
||||||
} else if (RC == PPC32::GPRCRegisterClass) {
|
} else if (RC == PPC::GPRCRegisterClass) {
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx);
|
||||||
} else if (RC == PPC32::F8RCRegisterClass) {
|
} else if (RC == PPC::G8RCRegisterClass) {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::LD, 2, DestReg), FrameIdx);
|
||||||
|
} else if (RC == PPC::F8RCRegisterClass) {
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx);
|
||||||
} else if (RC == PPC32::F4RCRegisterClass) {
|
} else if (RC == PPC::F4RCRegisterClass) {
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx);
|
||||||
} else {
|
} else {
|
||||||
assert(0 && "Unknown regclass!");
|
assert(0 && "Unknown regclass!");
|
||||||
@@ -95,13 +99,15 @@ void PPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
|
|||||||
const TargetRegisterClass *RC) const {
|
const TargetRegisterClass *RC) const {
|
||||||
MachineInstr *I;
|
MachineInstr *I;
|
||||||
|
|
||||||
if (RC == PPC32::GPRCRegisterClass) {
|
if (RC == PPC::GPRCRegisterClass) {
|
||||||
BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
|
BuildMI(MBB, MI, PPC::OR4, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
|
||||||
} else if (RC == PPC32::F4RCRegisterClass) {
|
} else if (RC == PPC::G8RCRegisterClass) {
|
||||||
|
BuildMI(MBB, MI, PPC::OR8, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
|
||||||
|
} else if (RC == PPC::F4RCRegisterClass) {
|
||||||
BuildMI(MBB, MI, PPC::FMRS, 1, DestReg).addReg(SrcReg);
|
BuildMI(MBB, MI, PPC::FMRS, 1, DestReg).addReg(SrcReg);
|
||||||
} else if (RC == PPC32::F8RCRegisterClass) {
|
} else if (RC == PPC::F8RCRegisterClass) {
|
||||||
BuildMI(MBB, MI, PPC::FMRD, 1, DestReg).addReg(SrcReg);
|
BuildMI(MBB, MI, PPC::FMRD, 1, DestReg).addReg(SrcReg);
|
||||||
} else if (RC == PPC32::CRRCRegisterClass) {
|
} else if (RC == PPC::CRRCRegisterClass) {
|
||||||
BuildMI(MBB, MI, PPC::MCRF, 1, DestReg).addReg(SrcReg);
|
BuildMI(MBB, MI, PPC::MCRF, 1, DestReg).addReg(SrcReg);
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Attempt to copy register that is not GPR or FPR";
|
std::cerr << "Attempt to copy register that is not GPR or FPR";
|
||||||
@@ -113,6 +119,7 @@ unsigned PPCRegisterInfo::isLoadFromStackSlot(MachineInstr *MI,
|
|||||||
int &FrameIndex) const {
|
int &FrameIndex) const {
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
|
case PPC::LD:
|
||||||
case PPC::LWZ:
|
case PPC::LWZ:
|
||||||
case PPC::LFS:
|
case PPC::LFS:
|
||||||
case PPC::LFD:
|
case PPC::LFD:
|
||||||
@@ -135,7 +142,7 @@ MachineInstr *PPCRegisterInfo::foldMemoryOperand(MachineInstr *MI,
|
|||||||
// it takes more than one instruction to store it.
|
// it takes more than one instruction to store it.
|
||||||
unsigned Opc = MI->getOpcode();
|
unsigned Opc = MI->getOpcode();
|
||||||
|
|
||||||
if ((Opc == PPC::OR &&
|
if ((Opc == PPC::OR4 &&
|
||||||
MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) {
|
MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) {
|
||||||
if (OpNum == 0) { // move -> store
|
if (OpNum == 0) { // move -> store
|
||||||
unsigned InReg = MI->getOperand(1).getReg();
|
unsigned InReg = MI->getOperand(1).getReg();
|
||||||
@@ -145,7 +152,16 @@ MachineInstr *PPCRegisterInfo::foldMemoryOperand(MachineInstr *MI,
|
|||||||
unsigned OutReg = MI->getOperand(0).getReg();
|
unsigned OutReg = MI->getOperand(0).getReg();
|
||||||
return addFrameReference(BuildMI(PPC::LWZ, 2, OutReg), FrameIndex);
|
return addFrameReference(BuildMI(PPC::LWZ, 2, OutReg), FrameIndex);
|
||||||
}
|
}
|
||||||
|
} else if ((Opc == PPC::OR8 &&
|
||||||
|
MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) {
|
||||||
|
if (OpNum == 0) { // move -> store
|
||||||
|
unsigned InReg = MI->getOperand(1).getReg();
|
||||||
|
return addFrameReference(BuildMI(PPC::STD,
|
||||||
|
3).addReg(InReg), FrameIndex);
|
||||||
|
} else { // move -> load
|
||||||
|
unsigned OutReg = MI->getOperand(0).getReg();
|
||||||
|
return addFrameReference(BuildMI(PPC::LD, 2, OutReg), FrameIndex);
|
||||||
|
}
|
||||||
} else if (Opc == PPC::FMRD) {
|
} else if (Opc == PPC::FMRD) {
|
||||||
if (OpNum == 0) { // move -> store
|
if (OpNum == 0) { // move -> store
|
||||||
unsigned InReg = MI->getOperand(1).getReg();
|
unsigned InReg = MI->getOperand(1).getReg();
|
||||||
@@ -315,7 +331,7 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
if (hasFP(MF)) {
|
if (hasFP(MF)) {
|
||||||
MI = BuildMI(PPC::STW, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1);
|
MI = BuildMI(PPC::STW, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1);
|
||||||
MBB.insert(MBBI, MI);
|
MBB.insert(MBBI, MI);
|
||||||
MI = BuildMI(PPC::OR, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1);
|
MI = BuildMI(PPC::OR4, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1);
|
||||||
MBB.insert(MBBI, MI);
|
MBB.insert(MBBI, MI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -87,7 +87,7 @@ def CTR : SPR<3, "ctr">;
|
|||||||
/// Register classes
|
/// Register classes
|
||||||
// Allocate volatiles first
|
// Allocate volatiles first
|
||||||
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31
|
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31
|
||||||
def GPRC : RegisterClass<"PPC32", i32, 32,
|
def GPRC : RegisterClass<"PPC", i32, 32,
|
||||||
[R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12,
|
[R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12,
|
||||||
R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17,
|
R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17,
|
||||||
R16, R15, R14, R13, R31, R0, R1, LR]>
|
R16, R15, R14, R13, R31, R0, R1, LR]>
|
||||||
@@ -110,13 +110,38 @@ def GPRC : RegisterClass<"PPC32", i32, 32,
|
|||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
def G8RC : RegisterClass<"PPC", i64, 64,
|
||||||
|
[R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12,
|
||||||
|
R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17,
|
||||||
|
R16, R15, R14, R13, R31, R0, R1, LR]>
|
||||||
|
{
|
||||||
|
let MethodProtos = [{
|
||||||
|
iterator allocation_order_begin(MachineFunction &MF) const;
|
||||||
|
iterator allocation_order_end(MachineFunction &MF) const;
|
||||||
|
}];
|
||||||
|
let MethodBodies = [{
|
||||||
|
G8RCClass::iterator
|
||||||
|
G8RCClass::allocation_order_begin(MachineFunction &MF) const {
|
||||||
|
return begin() + ((TargetAIX == PPCTarget) ? 1 : 0);
|
||||||
|
}
|
||||||
|
G8RCClass::iterator
|
||||||
|
G8RCClass::allocation_order_end(MachineFunction &MF) const {
|
||||||
|
if (hasFP(MF))
|
||||||
|
return end()-4;
|
||||||
|
else
|
||||||
|
return end()-3;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
def F8RC : RegisterClass<"PPC32", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
|
|
||||||
|
|
||||||
|
def F8RC : RegisterClass<"PPC", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
|
||||||
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
||||||
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||||
def F4RC : RegisterClass<"PPC32", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7,
|
def F4RC : RegisterClass<"PPC", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7,
|
||||||
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
||||||
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||||
|
|
||||||
|
|
||||||
def CRRC : RegisterClass<"PPC32", i32, 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]>;
|
def CRRC : RegisterClass<"PPC", i32, 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]>;
|
||||||
|
@@ -99,9 +99,9 @@ bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM,
|
|||||||
|
|
||||||
// Install an instruction selector.
|
// Install an instruction selector.
|
||||||
if (!DisablePPCDAGDAG)
|
if (!DisablePPCDAGDAG)
|
||||||
PM.add(createPPC32ISelDag(*this));
|
PM.add(createPPCISelDag(*this));
|
||||||
else
|
else
|
||||||
PM.add(createPPC32ISelPattern(*this));
|
PM.add(createPPCISelPattern(*this));
|
||||||
|
|
||||||
if (PrintMachineCode)
|
if (PrintMachineCode)
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
||||||
@@ -156,9 +156,9 @@ void PPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
|
|||||||
|
|
||||||
// Install an instruction selector.
|
// Install an instruction selector.
|
||||||
if (!DisablePPCDAGDAG)
|
if (!DisablePPCDAGDAG)
|
||||||
PM.add(createPPC32ISelDag(TM));
|
PM.add(createPPCISelDag(TM));
|
||||||
else
|
else
|
||||||
PM.add(createPPC32ISelPattern(TM));
|
PM.add(createPPCISelPattern(TM));
|
||||||
|
|
||||||
PM.add(createRegisterAllocator());
|
PM.add(createRegisterAllocator());
|
||||||
PM.add(createPrologEpilogCodeInserter());
|
PM.add(createPrologEpilogCodeInserter());
|
||||||
|
Reference in New Issue
Block a user