mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-08 13:00:43 +00:00
Modify the ppc backend to use two register classes for FP: F8RC and F4RC.
These are used to represent float and double values, and the two regclasses contain the same physical registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23577 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f85a55b096
commit
919c032fa4
@ -39,8 +39,12 @@ def GPRC : RegisterClass<"PPC32", i32, 32,
|
||||
}];
|
||||
}
|
||||
|
||||
def FPRC : RegisterClass<"PPC32", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
|
||||
def F8RC : RegisterClass<"PPC32", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
|
||||
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
||||
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||
def F4RC : RegisterClass<"PPC32", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7,
|
||||
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
||||
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||
|
||||
|
||||
def CRRC : RegisterClass<"PPC32", i32, 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]>;
|
||||
|
@ -41,7 +41,8 @@ namespace {
|
||||
// keeping the offsets up to date later when we emit long branch glue.
|
||||
return 12;
|
||||
case PPC::IMPLICIT_DEF_GPR: // no asm emitted
|
||||
case PPC::IMPLICIT_DEF_FP: // no asm emitted
|
||||
case PPC::IMPLICIT_DEF_F4: // no asm emitted
|
||||
case PPC::IMPLICIT_DEF_F8: // no asm emitted
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
|
@ -125,7 +125,8 @@ void PPC32CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
|
||||
emitWord(getBinaryCodeForInstr(*I));
|
||||
break;
|
||||
case PPC::IMPLICIT_DEF_GPR:
|
||||
case PPC::IMPLICIT_DEF_FP:
|
||||
case PPC::IMPLICIT_DEF_F8:
|
||||
case PPC::IMPLICIT_DEF_F4:
|
||||
break; // pseudo opcode, no side effects
|
||||
case PPC::MovePCtoLR:
|
||||
assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
|
||||
|
@ -443,8 +443,10 @@ SDOperand PPC32DAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
|
||||
LHS, getI32Imm(Lo16(Imm)));
|
||||
return CurDAG->getTargetNode(U ? PPC::CMPLW : PPC::CMPW, MVT::i32,
|
||||
LHS, Select(RHS));
|
||||
} else if (LHS.getValueType() == MVT::f32) {
|
||||
return CurDAG->getTargetNode(PPC::FCMPUS, MVT::i32, LHS, Select(RHS));
|
||||
} else {
|
||||
return CurDAG->getTargetNode(PPC::FCMPU, MVT::i32, LHS, Select(RHS));
|
||||
return CurDAG->getTargetNode(PPC::FCMPUD, MVT::i32, LHS, Select(RHS));
|
||||
}
|
||||
}
|
||||
|
||||
@ -679,8 +681,10 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
case ISD::UNDEF:
|
||||
if (N->getValueType(0) == MVT::i32)
|
||||
CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_GPR, MVT::i32);
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_FP, N->getValueType(0));
|
||||
else if (N->getValueType(0) == MVT::f32)
|
||||
CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32);
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64);
|
||||
return SDOperand(N, 0);
|
||||
case ISD::FrameIndex: {
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
@ -749,10 +753,16 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
return SDOperand(Result.Val, Op.ResNo);
|
||||
}
|
||||
case PPCISD::FSEL:
|
||||
CurDAG->SelectNodeTo(N, PPC::FSEL, N->getValueType(0),
|
||||
Select(N->getOperand(0)),
|
||||
Select(N->getOperand(1)),
|
||||
Select(N->getOperand(2)));
|
||||
if (N->getValueType(0) == MVT::f32)
|
||||
CurDAG->SelectNodeTo(N, PPC::FSELS, MVT::f32,
|
||||
Select(N->getOperand(0)),
|
||||
Select(N->getOperand(1)),
|
||||
Select(N->getOperand(2)));
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::FSELD, MVT::f64,
|
||||
Select(N->getOperand(0)),
|
||||
Select(N->getOperand(1)),
|
||||
Select(N->getOperand(2)));
|
||||
return SDOperand(N, 0);
|
||||
case PPCISD::FCFID:
|
||||
CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0),
|
||||
@ -956,15 +966,17 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
case ISD::FABS:
|
||||
CurDAG->SelectNodeTo(N, PPC::FABS, N->getValueType(0),
|
||||
Select(N->getOperand(0)));
|
||||
if (N->getValueType(0) == MVT::f32)
|
||||
CurDAG->SelectNodeTo(N, PPC::FABSS, MVT::f32, Select(N->getOperand(0)));
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::FABSD, MVT::f64, Select(N->getOperand(0)));
|
||||
return SDOperand(N, 0);
|
||||
case ISD::FP_EXTEND:
|
||||
assert(MVT::f64 == N->getValueType(0) &&
|
||||
MVT::f32 == N->getOperand(0).getValueType() && "Illegal FP_EXTEND");
|
||||
// We need to emit an FMR to make sure that the result has the right value
|
||||
// type.
|
||||
CurDAG->SelectNodeTo(N, PPC::FMR, MVT::f64, Select(N->getOperand(0)));
|
||||
CurDAG->SelectNodeTo(N, PPC::FMRSD, MVT::f64, Select(N->getOperand(0)));
|
||||
return SDOperand(N, 0);
|
||||
case ISD::FP_ROUND:
|
||||
assert(MVT::f32 == N->getValueType(0) &&
|
||||
@ -978,7 +990,8 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
unsigned Opc;
|
||||
switch (Val.isTargetOpcode() ? Val.getTargetOpcode() : 0) {
|
||||
default: Opc = 0; break;
|
||||
case PPC::FABS: Opc = PPC::FNABS; break;
|
||||
case PPC::FABSS: Opc = PPC::FNABSS; break;
|
||||
case PPC::FABSD: Opc = PPC::FNABSD; break;
|
||||
case PPC::FMADD: Opc = PPC::FNMADD; break;
|
||||
case PPC::FMADDS: Opc = PPC::FNMADDS; break;
|
||||
case PPC::FMSUB: Opc = PPC::FNMSUB; break;
|
||||
@ -988,7 +1001,7 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
// inverted opcode and the original instruction's operands. Otherwise,
|
||||
// fall through and generate a fneg instruction.
|
||||
if (Opc) {
|
||||
if (PPC::FNABS == Opc)
|
||||
if (Opc == PPC::FNABSS || Opc == PPC::FNABSD)
|
||||
CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0));
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0),
|
||||
@ -996,7 +1009,10 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
}
|
||||
CurDAG->SelectNodeTo(N, PPC::FNEG, Ty, Val);
|
||||
if (Ty == MVT::f32)
|
||||
CurDAG->SelectNodeTo(N, PPC::FNEGS, MVT::f32, Val);
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::FNEGS, MVT::f64, Val);
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
case ISD::FSQRT: {
|
||||
@ -1090,9 +1106,26 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
case MVT::f64: Opc = isIdx ? PPC::LFDX : PPC::LFD; break;
|
||||
}
|
||||
|
||||
CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other,
|
||||
Op1, Op2, Select(N->getOperand(0)));
|
||||
return SDOperand(N, Op.ResNo);
|
||||
// If this is an f32 -> f64 load, emit the f32 load, then use an 'extending
|
||||
// copy'.
|
||||
if (TypeBeingLoaded != MVT::f32 || N->getOpcode() == ISD::LOAD) {
|
||||
CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other,
|
||||
Op1, Op2, Select(N->getOperand(0)));
|
||||
return SDOperand(N, Op.ResNo);
|
||||
} else {
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Op1);
|
||||
Ops.push_back(Op2);
|
||||
Ops.push_back(Select(N->getOperand(0)));
|
||||
SDOperand Res = CurDAG->getTargetNode(Opc, MVT::f32, MVT::Other, Ops);
|
||||
SDOperand Ext = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Res);
|
||||
CodeGenMap[Op.getValue(0)] = Ext;
|
||||
CodeGenMap[Op.getValue(1)] = Res.getValue(1);
|
||||
if (Op.ResNo)
|
||||
return Res.getValue(1);
|
||||
else
|
||||
return Ext;
|
||||
}
|
||||
}
|
||||
|
||||
case ISD::TRUNCSTORE:
|
||||
@ -1250,7 +1283,13 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
unsigned BROpc = getBCCForSetCC(CC);
|
||||
|
||||
bool isFP = MVT::isFloatingPoint(N->getValueType(0));
|
||||
unsigned SelectCCOp = isFP ? PPC::SELECT_CC_FP : PPC::SELECT_CC_Int;
|
||||
unsigned SelectCCOp;
|
||||
if (MVT::isInteger(N->getValueType(0)))
|
||||
SelectCCOp = PPC::SELECT_CC_Int;
|
||||
else if (N->getValueType(0) == MVT::f32)
|
||||
SelectCCOp = PPC::SELECT_CC_F4;
|
||||
else
|
||||
SelectCCOp = PPC::SELECT_CC_F8;
|
||||
CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg,
|
||||
Select(N->getOperand(2)), Select(N->getOperand(3)),
|
||||
getI32Imm(BROpc));
|
||||
|
@ -33,8 +33,8 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
|
||||
|
||||
// Set up the register classes.
|
||||
addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass);
|
||||
addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass);
|
||||
addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass);
|
||||
addRegisterClass(MVT::f32, PPC32::F4RCRegisterClass);
|
||||
addRegisterClass(MVT::f64, PPC32::F8RCRegisterClass);
|
||||
|
||||
// PowerPC has no intrinsics for these particular operations
|
||||
setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
|
||||
@ -396,7 +396,11 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
||||
ObjSize = (ObjectVT == MVT::f64) ? 8 : 4;
|
||||
if (!ArgLive) break;
|
||||
if (FPR_remaining > 0) {
|
||||
unsigned VReg = RegMap->createVirtualRegister(&PPC32::FPRCRegClass);
|
||||
unsigned VReg;
|
||||
if (ObjectVT == MVT::f32)
|
||||
VReg = RegMap->createVirtualRegister(&PPC32::F4RCRegClass);
|
||||
else
|
||||
VReg = RegMap->createVirtualRegister(&PPC32::F8RCRegClass);
|
||||
MF.addLiveIn(FPR[FPR_idx], VReg);
|
||||
argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, ObjectVT);
|
||||
--FPR_remaining;
|
||||
@ -724,7 +728,8 @@ MachineBasicBlock *
|
||||
PPC32TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) {
|
||||
assert((MI->getOpcode() == PPC::SELECT_CC_Int ||
|
||||
MI->getOpcode() == PPC::SELECT_CC_FP) &&
|
||||
MI->getOpcode() == PPC::SELECT_CC_F4 ||
|
||||
MI->getOpcode() == PPC::SELECT_CC_F8) &&
|
||||
"Unexpected instr type to insert");
|
||||
|
||||
// To "insert" a SELECT_CC instruction, we actually have to insert the diamond
|
||||
|
@ -87,9 +87,6 @@ public:
|
||||
inline unsigned MakeIntReg() {
|
||||
return RegMap->createVirtualRegister(PPC32::GPRCRegisterClass);
|
||||
}
|
||||
inline unsigned MakeFPReg() {
|
||||
return RegMap->createVirtualRegister(PPC32::FPRCRegisterClass);
|
||||
}
|
||||
|
||||
// dag -> dag expanders for integer divide by constant
|
||||
SDOperand BuildSDIVSequence(SDOperand N);
|
||||
@ -593,8 +590,6 @@ unsigned ISel::FoldIfWideZeroExtend(SDOperand N) {
|
||||
unsigned ISel::SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC) {
|
||||
unsigned Result, Tmp1, Tmp2;
|
||||
bool AlreadySelected = false;
|
||||
static const unsigned CompareOpcodes[] =
|
||||
{ PPC::FCMPU, PPC::FCMPU, PPC::CMPW, PPC::CMPLW };
|
||||
|
||||
// Allocate a condition register for this expression
|
||||
Result = RegMap->createVirtualRegister(PPC32::CRRCRegisterClass);
|
||||
@ -626,8 +621,13 @@ unsigned ISel::SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC) {
|
||||
else
|
||||
BuildMI(BB, PPC::CMPWI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
|
||||
} else {
|
||||
bool IsInteger = MVT::isInteger(LHS.getValueType());
|
||||
unsigned CompareOpc = CompareOpcodes[2 * IsInteger + U];
|
||||
unsigned CompareOpc;
|
||||
if (MVT::isInteger(LHS.getValueType()))
|
||||
CompareOpc = U ? PPC::CMPLW : PPC::CMPW;
|
||||
else if (LHS.getValueType() == MVT::f32)
|
||||
CompareOpc = PPC::FCMPUS;
|
||||
else
|
||||
CompareOpc = PPC::FCMPUD;
|
||||
Tmp1 = SelectExpr(LHS);
|
||||
Tmp2 = SelectExpr(RHS);
|
||||
BuildMI(BB, CompareOpc, 2, Result).addReg(Tmp1).addReg(Tmp2);
|
||||
@ -815,7 +815,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
Tmp2 = SelectExpr(N.getOperand(1));
|
||||
Tmp3 = SelectExpr(N.getOperand(2));
|
||||
BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
|
||||
if (N.getOperand(0).getValueType() == MVT::f32)
|
||||
BuildMI(BB, PPC::FSELS, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
|
||||
else
|
||||
BuildMI(BB, PPC::FSELD, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
|
||||
return Result;
|
||||
case PPCISD::FCFID:
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
@ -832,8 +835,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
case ISD::UNDEF:
|
||||
if (Node->getValueType(0) == MVT::i32)
|
||||
BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Result);
|
||||
else if (Node->getValueType(0) == MVT::f32)
|
||||
BuildMI(BB, PPC::IMPLICIT_DEF_F4, 0, Result);
|
||||
else
|
||||
BuildMI(BB, PPC::IMPLICIT_DEF_FP, 0, Result);
|
||||
BuildMI(BB, PPC::IMPLICIT_DEF_F8, 0, Result);
|
||||
return Result;
|
||||
case ISD::DYNAMIC_STACKALLOC:
|
||||
// Generate both result values. FIXME: Need a better commment here?
|
||||
@ -1011,7 +1016,8 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
case MVT::f64:
|
||||
case MVT::f32:
|
||||
assert(FPR_idx < 13 && "Too many fp args");
|
||||
BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]);
|
||||
BuildMI(BB, N.getOperand(i+2).getValueType() == MVT::f32 ? PPC::FMRS :
|
||||
PPC::FMRD, 1, FPR[FPR_idx]).addReg(ArgVR[i]);
|
||||
CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use);
|
||||
++FPR_idx;
|
||||
break;
|
||||
@ -1033,14 +1039,15 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
}
|
||||
break;
|
||||
case MVT::f32:
|
||||
BuildMI(BB, PPC::FMRS, 1, Result).addReg(PPC::F1);
|
||||
break;
|
||||
case MVT::f64:
|
||||
BuildMI(BB, PPC::FMR, 1, Result).addReg(PPC::F1);
|
||||
BuildMI(BB, PPC::FMRD, 1, Result).addReg(PPC::F1);
|
||||
break;
|
||||
}
|
||||
return Result+N.ResNo;
|
||||
}
|
||||
|
||||
case ISD::SIGN_EXTEND:
|
||||
case ISD::SIGN_EXTEND_INREG:
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
switch(cast<VTSDNode>(Node->getOperand(1))->getVT()) {
|
||||
@ -1063,8 +1070,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
Tmp1 = dyn_cast<RegisterSDNode>(Node->getOperand(1))->getReg();
|
||||
if (MVT::isInteger(DestType))
|
||||
BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1);
|
||||
else if (DestType == MVT::f32)
|
||||
BuildMI(BB, PPC::FMRS, 1, Result).addReg(Tmp1);
|
||||
else
|
||||
BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
|
||||
BuildMI(BB, PPC::FMRD, 1, Result).addReg(Tmp1);
|
||||
return Result;
|
||||
|
||||
case ISD::SHL:
|
||||
@ -1655,16 +1664,26 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
|
||||
} else if (ISD::FABS == N.getOperand(0).getOpcode()) {
|
||||
Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
|
||||
BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1);
|
||||
if (N.getOperand(0).getValueType() == MVT::f32)
|
||||
BuildMI(BB, PPC::FNABSS, 1, Result).addReg(Tmp1);
|
||||
else
|
||||
BuildMI(BB, PPC::FNABSD, 1, Result).addReg(Tmp1);
|
||||
|
||||
} else {
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1);
|
||||
if (N.getOperand(0).getValueType() == MVT::f32)
|
||||
BuildMI(BB, PPC::FNEGS, 1, Result).addReg(Tmp1);
|
||||
else
|
||||
BuildMI(BB, PPC::FNEGD, 1, Result).addReg(Tmp1);
|
||||
}
|
||||
return Result;
|
||||
|
||||
case ISD::FABS:
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1);
|
||||
if (N.getOperand(0).getValueType() == MVT::f32)
|
||||
BuildMI(BB, PPC::FABSS, 1, Result).addReg(Tmp1);
|
||||
else
|
||||
BuildMI(BB, PPC::FABSD, 1, Result).addReg(Tmp1);
|
||||
return Result;
|
||||
|
||||
case ISD::FSQRT:
|
||||
@ -1686,7 +1705,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
N.getOperand(0).getValueType() == MVT::f32 &&
|
||||
"only f32 to f64 conversion supported here");
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
|
||||
BuildMI(BB, PPC::FMRSD, 1, Result).addReg(Tmp1);
|
||||
return Result;
|
||||
}
|
||||
return 0;
|
||||
@ -1735,9 +1754,10 @@ void ISel::Select(SDOperand N) {
|
||||
Tmp2 = cast<RegisterSDNode>(N.getOperand(1))->getReg();
|
||||
|
||||
if (Tmp1 != Tmp2) {
|
||||
if (N.getOperand(2).getValueType() == MVT::f64 ||
|
||||
N.getOperand(2).getValueType() == MVT::f32)
|
||||
BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1);
|
||||
if (N.getOperand(2).getValueType() == MVT::f64)
|
||||
BuildMI(BB, PPC::FMRD, 1, Tmp2).addReg(Tmp1);
|
||||
else if (N.getOperand(2).getValueType() == MVT::f32)
|
||||
BuildMI(BB, PPC::FMRS, 1, Tmp2).addReg(Tmp1);
|
||||
else
|
||||
BuildMI(BB, PPC::OR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
|
||||
}
|
||||
@ -1747,8 +1767,10 @@ void ISel::Select(SDOperand N) {
|
||||
Tmp1 = cast<RegisterSDNode>(N.getOperand(1))->getReg();
|
||||
if (N.getOperand(1).getValueType() == MVT::i32)
|
||||
BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Tmp1);
|
||||
else if (N.getOperand(1).getValueType() == MVT::f32)
|
||||
BuildMI(BB, PPC::IMPLICIT_DEF_F4, 0, Tmp1);
|
||||
else
|
||||
BuildMI(BB, PPC::IMPLICIT_DEF_FP, 0, Tmp1);
|
||||
BuildMI(BB, PPC::IMPLICIT_DEF_F8, 0, Tmp1);
|
||||
return;
|
||||
case ISD::RET:
|
||||
switch (N.getNumOperands()) {
|
||||
@ -1771,8 +1793,10 @@ void ISel::Select(SDOperand N) {
|
||||
default:
|
||||
assert(0 && "Unknown return type!");
|
||||
case MVT::f64:
|
||||
BuildMI(BB, PPC::FMRD, 1, PPC::F1).addReg(Tmp1);
|
||||
break;
|
||||
case MVT::f32:
|
||||
BuildMI(BB, PPC::FMR, 1, PPC::F1).addReg(Tmp1);
|
||||
BuildMI(BB, PPC::FMRS, 1, PPC::F1).addReg(Tmp1);
|
||||
break;
|
||||
case MVT::i32:
|
||||
BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1);
|
||||
|
@ -57,7 +57,7 @@ bool PPC32InstrInfo::isMoveInstr(const MachineInstr& MI,
|
||||
destReg = MI.getOperand(0).getReg();
|
||||
return true;
|
||||
}
|
||||
} else if (oc == PPC::FMR) { // fmr r1, r2
|
||||
} else if (oc == PPC::FMRS || oc == PPC::FMRD) { // fmr r1, r2
|
||||
assert(MI.getNumOperands() == 2 &&
|
||||
MI.getOperand(0).isRegister() &&
|
||||
MI.getOperand(1).isRegister() &&
|
||||
|
@ -317,14 +317,17 @@ def ADJCALLSTACKDOWN : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKDOWN">;
|
||||
def ADJCALLSTACKUP : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKUP">;
|
||||
}
|
||||
def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC">;
|
||||
def IMPLICIT_DEF_FP : Pseudo<(ops FPRC:$rD), "; %rD = IMPLICIT_DEF_FP">;
|
||||
def IMPLICIT_DEF_F8 : Pseudo<(ops F8RC:$rD), "; %rD = IMPLICIT_DEF_F8">;
|
||||
def IMPLICIT_DEF_F4 : Pseudo<(ops F4RC:$rD), "; %rD = IMPLICIT_DEF_F4">;
|
||||
|
||||
// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the
|
||||
// scheduler into a branch sequence.
|
||||
let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
|
||||
def SELECT_CC_Int : Pseudo<(ops GPRC:$dst, CRRC:$cond, GPRC:$T, GPRC:$F,
|
||||
i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
|
||||
def SELECT_CC_FP : Pseudo<(ops FPRC:$dst, CRRC:$cond, FPRC:$T, FPRC:$F,
|
||||
def SELECT_CC_F4 : Pseudo<(ops F4RC:$dst, CRRC:$cond, F4RC:$T, F4RC:$F,
|
||||
i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
|
||||
def SELECT_CC_F8 : Pseudo<(ops F8RC:$dst, CRRC:$cond, F8RC:$T, F8RC:$F,
|
||||
i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
|
||||
}
|
||||
|
||||
@ -463,15 +466,15 @@ def CMPLWI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
|
||||
def CMPLDI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
|
||||
"cmpldi $dst, $src1, $src2">, isPPC64;
|
||||
let isLoad = 1 in {
|
||||
def LFS : DForm_8<48, (ops FPRC:$rD, symbolLo:$disp, GPRC:$rA),
|
||||
def LFS : DForm_8<48, (ops F4RC:$rD, symbolLo:$disp, GPRC:$rA),
|
||||
"lfs $rD, $disp($rA)">;
|
||||
def LFD : DForm_8<50, (ops FPRC:$rD, symbolLo:$disp, GPRC:$rA),
|
||||
def LFD : DForm_8<50, (ops F8RC:$rD, symbolLo:$disp, GPRC:$rA),
|
||||
"lfd $rD, $disp($rA)">;
|
||||
}
|
||||
let isStore = 1 in {
|
||||
def STFS : DForm_9<52, (ops FPRC:$rS, symbolLo:$disp, GPRC:$rA),
|
||||
def STFS : DForm_9<52, (ops F4RC:$rS, symbolLo:$disp, GPRC:$rA),
|
||||
"stfs $rS, $disp($rA)">;
|
||||
def STFD : DForm_9<54, (ops FPRC:$rS, symbolLo:$disp, GPRC:$rA),
|
||||
def STFD : DForm_9<54, (ops F8RC:$rS, symbolLo:$disp, GPRC:$rA),
|
||||
"stfd $rS, $disp($rA)">;
|
||||
}
|
||||
|
||||
@ -596,51 +599,74 @@ def CMPLW : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
|
||||
"cmplw $crD, $rA, $rB">;
|
||||
def CMPLD : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
|
||||
"cmpld $crD, $rA, $rB">, isPPC64;
|
||||
def FCMPO : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
|
||||
"fcmpo $crD, $fA, $fB">;
|
||||
def FCMPU : XForm_17<63, 0, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
|
||||
//def FCMPO : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
|
||||
// "fcmpo $crD, $fA, $fB">;
|
||||
def FCMPUS : XForm_17<63, 0, (ops CRRC:$crD, F4RC:$fA, F4RC:$fB),
|
||||
"fcmpu $crD, $fA, $fB">;
|
||||
def FCMPUD : XForm_17<63, 0, (ops CRRC:$crD, F8RC:$fA, F8RC:$fB),
|
||||
"fcmpu $crD, $fA, $fB">;
|
||||
|
||||
let isLoad = 1 in {
|
||||
def LFSX : XForm_25<31, 535, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
|
||||
def LFSX : XForm_25<31, 535, (ops F4RC:$dst, GPRC:$base, GPRC:$index),
|
||||
"lfsx $dst, $base, $index">;
|
||||
def LFDX : XForm_25<31, 599, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
|
||||
def LFDX : XForm_25<31, 599, (ops F8RC:$dst, GPRC:$base, GPRC:$index),
|
||||
"lfdx $dst, $base, $index">;
|
||||
}
|
||||
def FCFID : XForm_26<63, 846, (ops FPRC:$frD, FPRC:$frB),
|
||||
def FCFID : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB),
|
||||
"fcfid $frD, $frB",
|
||||
[]>, isPPC64;
|
||||
def FCTIDZ : XForm_26<63, 815, (ops FPRC:$frD, FPRC:$frB),
|
||||
def FCTIDZ : XForm_26<63, 815, (ops F8RC:$frD, F8RC:$frB),
|
||||
"fctidz $frD, $frB",
|
||||
[]>, isPPC64;
|
||||
def FCTIWZ : XForm_26<63, 15, (ops FPRC:$frD, FPRC:$frB),
|
||||
def FCTIWZ : XForm_26<63, 15, (ops F8RC:$frD, F8RC:$frB),
|
||||
"fctiwz $frD, $frB",
|
||||
[]>;
|
||||
def FABS : XForm_26<63, 264, (ops FPRC:$frD, FPRC:$frB),
|
||||
"fabs $frD, $frB",
|
||||
[(set FPRC:$frD, (fabs FPRC:$frB))]>;
|
||||
def FMR : XForm_26<63, 72, (ops FPRC:$frD, FPRC:$frB),
|
||||
"fmr $frD, $frB",
|
||||
[]>; // (set FPRC:$frD, FPRC:$frB)
|
||||
def FNABS : XForm_26<63, 136, (ops FPRC:$frD, FPRC:$frB),
|
||||
"fnabs $frD, $frB",
|
||||
[(set FPRC:$frD, (fneg (fabs FPRC:$frB)))]>;
|
||||
def FNEG : XForm_26<63, 40, (ops FPRC:$frD, FPRC:$frB),
|
||||
"fneg $frD, $frB",
|
||||
[(set FPRC:$frD, (fneg FPRC:$frB))]>;
|
||||
def FRSP : XForm_26<63, 12, (ops FPRC:$frD, FPRC:$frB),
|
||||
def FRSP : XForm_26<63, 12, (ops F4RC:$frD, F8RC:$frB),
|
||||
"frsp $frD, $frB",
|
||||
[]>;
|
||||
def FSQRT : XForm_26<63, 22, (ops FPRC:$frD, FPRC:$frB),
|
||||
def FSQRT : XForm_26<63, 22, (ops F8RC:$frD, F8RC:$frB),
|
||||
"fsqrt $frD, $frB",
|
||||
[(set FPRC:$frD, (fsqrt FPRC:$frB))]>;
|
||||
def FSQRTS : XForm_26<59, 22, (ops FPRC:$frD, FPRC:$frB),
|
||||
[(set F8RC:$frD, (fsqrt F8RC:$frB))]>;
|
||||
def FSQRTS : XForm_26<59, 22, (ops F4RC:$frD, F4RC:$frB),
|
||||
"fsqrts $frD, $frB",
|
||||
[]>;
|
||||
|
||||
/// FMR is split into 3 versions, one for 4/8 byte FP, and one for extending.
|
||||
def FMRS : XForm_26<63, 72, (ops F4RC:$frD, F4RC:$frB),
|
||||
"fmr $frD, $frB",
|
||||
[]>; // (set F4RC:$frD, F4RC:$frB)
|
||||
def FMRD : XForm_26<63, 72, (ops F8RC:$frD, F8RC:$frB),
|
||||
"fmr $frD, $frB",
|
||||
[]>; // (set F8RC:$frD, F8RC:$frB)
|
||||
def FMRSD : XForm_26<63, 72, (ops F8RC:$frD, F4RC:$frB),
|
||||
"fmr $frD, $frB",
|
||||
[]>; // (set F8RC:$frD, (fpextend F4RC:$frB))
|
||||
|
||||
// These are artificially split into two different forms, for 4/8 byte FP.
|
||||
def FABSS : XForm_26<63, 264, (ops F4RC:$frD, F4RC:$frB),
|
||||
"fabs $frD, $frB",
|
||||
[(set F4RC:$frD, (fabs F4RC:$frB))]>;
|
||||
def FABSD : XForm_26<63, 264, (ops F8RC:$frD, F8RC:$frB),
|
||||
"fabs $frD, $frB",
|
||||
[(set F8RC:$frD, (fabs F8RC:$frB))]>;
|
||||
def FNABSS : XForm_26<63, 136, (ops F4RC:$frD, F4RC:$frB),
|
||||
"fnabs $frD, $frB",
|
||||
[(set F4RC:$frD, (fneg (fabs F4RC:$frB)))]>;
|
||||
def FNABSD : XForm_26<63, 136, (ops F8RC:$frD, F8RC:$frB),
|
||||
"fnabs $frD, $frB",
|
||||
[(set F8RC:$frD, (fneg (fabs F8RC:$frB)))]>;
|
||||
def FNEGS : XForm_26<63, 40, (ops F4RC:$frD, F4RC:$frB),
|
||||
"fneg $frD, $frB",
|
||||
[(set F4RC:$frD, (fneg F4RC:$frB))]>;
|
||||
def FNEGD : XForm_26<63, 40, (ops F8RC:$frD, F8RC:$frB),
|
||||
"fneg $frD, $frB",
|
||||
[(set F8RC:$frD, (fneg F8RC:$frB))]>;
|
||||
|
||||
|
||||
let isStore = 1 in {
|
||||
def STFSX : XForm_28<31, 663, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
|
||||
def STFSX : XForm_28<31, 663, (ops F4RC:$frS, GPRC:$rA, GPRC:$rB),
|
||||
"stfsx $frS, $rA, $rB">;
|
||||
def STFDX : XForm_28<31, 727, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
|
||||
def STFDX : XForm_28<31, 727, (ops F8RC:$frS, GPRC:$rA, GPRC:$rB),
|
||||
"stfdx $frS, $rA, $rB">;
|
||||
}
|
||||
|
||||
@ -730,75 +756,80 @@ def SUBFZE : XOForm_3<31, 200, 0, (ops GPRC:$rT, GPRC:$rA),
|
||||
// this type.
|
||||
//
|
||||
def FMADD : AForm_1<63, 29,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
|
||||
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
|
||||
"fmadd $FRT, $FRA, $FRC, $FRB",
|
||||
[(set FPRC:$FRT, (fadd (fmul FPRC:$FRA, FPRC:$FRC),
|
||||
FPRC:$FRB))]>;
|
||||
[(set F8RC:$FRT, (fadd (fmul F8RC:$FRA, F8RC:$FRC),
|
||||
F8RC:$FRB))]>;
|
||||
def FMADDS : AForm_1<59, 29,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
|
||||
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
|
||||
"fmadds $FRT, $FRA, $FRC, $FRB",
|
||||
[]>;
|
||||
def FMSUB : AForm_1<63, 28,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
|
||||
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
|
||||
"fmsub $FRT, $FRA, $FRC, $FRB",
|
||||
[(set FPRC:$FRT, (fsub (fmul FPRC:$FRA, FPRC:$FRC),
|
||||
FPRC:$FRB))]>;
|
||||
[(set F8RC:$FRT, (fsub (fmul F8RC:$FRA, F8RC:$FRC),
|
||||
F8RC:$FRB))]>;
|
||||
def FMSUBS : AForm_1<59, 28,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
|
||||
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
|
||||
"fmsubs $FRT, $FRA, $FRC, $FRB",
|
||||
[]>;
|
||||
def FNMADD : AForm_1<63, 31,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
|
||||
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
|
||||
"fnmadd $FRT, $FRA, $FRC, $FRB",
|
||||
[(set FPRC:$FRT, (fneg (fadd (fmul FPRC:$FRA, FPRC:$FRC),
|
||||
FPRC:$FRB)))]>;
|
||||
[(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC),
|
||||
F8RC:$FRB)))]>;
|
||||
def FNMADDS : AForm_1<59, 31,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
|
||||
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
|
||||
"fnmadds $FRT, $FRA, $FRC, $FRB",
|
||||
[]>;
|
||||
def FNMSUB : AForm_1<63, 30,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
|
||||
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
|
||||
"fnmsub $FRT, $FRA, $FRC, $FRB",
|
||||
[(set FPRC:$FRT, (fneg (fsub (fmul FPRC:$FRA, FPRC:$FRC),
|
||||
FPRC:$FRB)))]>;
|
||||
[(set F8RC:$FRT, (fneg (fsub (fmul F8RC:$FRA, F8RC:$FRC),
|
||||
F8RC:$FRB)))]>;
|
||||
def FNMSUBS : AForm_1<59, 30,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
|
||||
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
|
||||
"fnmsubs $FRT, $FRA, $FRC, $FRB",
|
||||
[]>;
|
||||
def FSEL : AForm_1<63, 23,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
|
||||
// FSEL is artificially split into 4 and 8-byte forms.
|
||||
def FSELD : AForm_1<63, 23,
|
||||
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
|
||||
"fsel $FRT, $FRA, $FRC, $FRB",
|
||||
[]>;
|
||||
def FSELS : AForm_1<63, 23,
|
||||
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
|
||||
"fsel $FRT, $FRA, $FRC, $FRB",
|
||||
[]>;
|
||||
def FADD : AForm_2<63, 21,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
|
||||
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
|
||||
"fadd $FRT, $FRA, $FRB",
|
||||
[(set FPRC:$FRT, (fadd FPRC:$FRA, FPRC:$FRB))]>;
|
||||
[(set F8RC:$FRT, (fadd F8RC:$FRA, F8RC:$FRB))]>;
|
||||
def FADDS : AForm_2<59, 21,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
|
||||
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
|
||||
"fadds $FRT, $FRA, $FRB",
|
||||
[]>;
|
||||
def FDIV : AForm_2<63, 18,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
|
||||
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
|
||||
"fdiv $FRT, $FRA, $FRB",
|
||||
[(set FPRC:$FRT, (fdiv FPRC:$FRA, FPRC:$FRB))]>;
|
||||
[(set F8RC:$FRT, (fdiv F8RC:$FRA, F8RC:$FRB))]>;
|
||||
def FDIVS : AForm_2<59, 18,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
|
||||
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
|
||||
"fdivs $FRT, $FRA, $FRB",
|
||||
[]>;
|
||||
def FMUL : AForm_3<63, 25,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
|
||||
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
|
||||
"fmul $FRT, $FRA, $FRB",
|
||||
[(set FPRC:$FRT, (fmul FPRC:$FRA, FPRC:$FRB))]>;
|
||||
[(set F8RC:$FRT, (fmul F8RC:$FRA, F8RC:$FRB))]>;
|
||||
def FMULS : AForm_3<59, 25,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
|
||||
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
|
||||
"fmuls $FRT, $FRA, $FRB",
|
||||
[]>;
|
||||
def FSUB : AForm_2<63, 20,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
|
||||
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
|
||||
"fsub $FRT, $FRA, $FRB",
|
||||
[(set FPRC:$FRT, (fsub FPRC:$FRA, FPRC:$FRB))]>;
|
||||
[(set F8RC:$FRT, (fsub F8RC:$FRA, F8RC:$FRB))]>;
|
||||
def FSUBS : AForm_2<59, 20,
|
||||
(ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
|
||||
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
|
||||
"fsubs $FRT, $FRA, $FRB",
|
||||
[]>;
|
||||
|
||||
|
@ -43,47 +43,26 @@ PPC32RegisterInfo::PPC32RegisterInfo()
|
||||
ImmToIdxMap[PPC::ADDI] = PPC::ADD;
|
||||
}
|
||||
|
||||
static unsigned getIdx(const TargetRegisterClass *RC) {
|
||||
if (RC == PPC32::GPRCRegisterClass) {
|
||||
switch (RC->getSize()) {
|
||||
default: assert(0 && "Invalid data size!");
|
||||
case 1: return 0;
|
||||
case 2: return 1;
|
||||
case 4: return 2;
|
||||
}
|
||||
} else if (RC == PPC32::FPRCRegisterClass) {
|
||||
switch (RC->getSize()) {
|
||||
default: assert(0 && "Invalid data size!");
|
||||
case 4: return 3;
|
||||
case 8: return 4;
|
||||
}
|
||||
} else if (RC == PPC32::CRRCRegisterClass) {
|
||||
switch (RC->getSize()) {
|
||||
default: assert(0 && "Invalid data size!");
|
||||
case 4: return 2;
|
||||
}
|
||||
}
|
||||
std::cerr << "Invalid register class to getIdx()!\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
PPC32RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
unsigned SrcReg, int FrameIdx,
|
||||
const TargetRegisterClass *RC) const {
|
||||
static const unsigned Opcode[] = {
|
||||
PPC::STB, PPC::STH, PPC::STW, PPC::STFS, PPC::STFD
|
||||
};
|
||||
unsigned OC = Opcode[getIdx(RC)];
|
||||
if (SrcReg == PPC::LR) {
|
||||
BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11);
|
||||
addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx);
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
|
||||
} else if (RC == PPC32::CRRCRegisterClass) {
|
||||
BuildMI(MBB, MI, PPC::MFCR, 0, PPC::R11);
|
||||
addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx);
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
|
||||
} else if (RC == PPC32::GPRCRegisterClass) {
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx);
|
||||
} else if (RC == PPC32::F8RCRegisterClass) {
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx);
|
||||
} else if (RC == PPC32::F4RCRegisterClass) {
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx);
|
||||
} else {
|
||||
addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(SrcReg),FrameIdx);
|
||||
assert(0 && "Unknown regclass!");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,18 +71,21 @@ PPC32RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
unsigned DestReg, int FrameIdx,
|
||||
const TargetRegisterClass *RC) const {
|
||||
static const unsigned Opcode[] = {
|
||||
PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LFS, PPC::LFD
|
||||
};
|
||||
unsigned OC = Opcode[getIdx(RC)];
|
||||
if (DestReg == PPC::LR) {
|
||||
addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx);
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
|
||||
BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
|
||||
} else if (RC == PPC32::CRRCRegisterClass) {
|
||||
addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx);
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
|
||||
BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R11);
|
||||
} else if (RC == PPC32::GPRCRegisterClass) {
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx);
|
||||
} else if (RC == PPC32::F8RCRegisterClass) {
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx);
|
||||
} else if (RC == PPC32::F4RCRegisterClass) {
|
||||
addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx);
|
||||
} else {
|
||||
addFrameReference(BuildMI(MBB, MI, OC, 2, DestReg), FrameIdx);
|
||||
assert(0 && "Unknown regclass!");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,8 +97,10 @@ void PPC32RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
|
||||
|
||||
if (RC == PPC32::GPRCRegisterClass) {
|
||||
BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
|
||||
} else if (RC == PPC32::FPRCRegisterClass) {
|
||||
BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg);
|
||||
} else if (RC == PPC32::F4RCRegisterClass) {
|
||||
BuildMI(MBB, MI, PPC::FMRS, 1, DestReg).addReg(SrcReg);
|
||||
} else if (RC == PPC32::F8RCRegisterClass) {
|
||||
BuildMI(MBB, MI, PPC::FMRD, 1, DestReg).addReg(SrcReg);
|
||||
} else if (RC == PPC32::CRRCRegisterClass) {
|
||||
BuildMI(MBB, MI, PPC::MCRF, 1, DestReg).addReg(SrcReg);
|
||||
} else {
|
||||
@ -130,6 +114,9 @@ unsigned PPC32RegisterInfo::isLoadFromStackSlot(MachineInstr *MI,
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case PPC::LWZ:
|
||||
//
|
||||
// case PPC::LFS: // ENABLE!!
|
||||
//
|
||||
case PPC::LFD:
|
||||
if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() &&
|
||||
MI->getOperand(2).isFrameIndex()) {
|
||||
@ -161,8 +148,7 @@ MachineInstr *PPC32RegisterInfo::foldMemoryOperand(MachineInstr *MI,
|
||||
return addFrameReference(BuildMI(PPC::LWZ, 2, OutReg), FrameIndex);
|
||||
}
|
||||
|
||||
} else if (Opc == PPC::FMR) {
|
||||
// We currently always spill FP values as doubles. :(
|
||||
} else if (Opc == PPC::FMRD) {
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned InReg = MI->getOperand(1).getReg();
|
||||
return addFrameReference(BuildMI(PPC::STFD,
|
||||
@ -171,6 +157,15 @@ MachineInstr *PPC32RegisterInfo::foldMemoryOperand(MachineInstr *MI,
|
||||
unsigned OutReg = MI->getOperand(0).getReg();
|
||||
return addFrameReference(BuildMI(PPC::LFD, 2, OutReg), FrameIndex);
|
||||
}
|
||||
} else if (Opc == PPC::FMRS) {
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned InReg = MI->getOperand(1).getReg();
|
||||
return addFrameReference(BuildMI(PPC::STFS,
|
||||
3).addReg(InReg), FrameIndex);
|
||||
} else { // move -> load
|
||||
unsigned OutReg = MI->getOperand(0).getReg();
|
||||
return addFrameReference(BuildMI(PPC::LFS, 2, OutReg), FrameIndex);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -262,7 +257,8 @@ PPC32RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
|
||||
MI.SetMachineOperandReg(1, MI.getOperand(i).getReg());
|
||||
MI.SetMachineOperandReg(2, PPC::R0);
|
||||
} else {
|
||||
MI.SetMachineOperandConst(OffIdx,MachineOperand::MO_SignExtendedImmed,Offset);
|
||||
MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed,
|
||||
Offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user