#include "PowerPC.h"
#include "PPC32TargetMachine.h"
#include "PPC32ISelLowering.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Constants.h"
#include "llvm/GlobalValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
// look for the first zero bit after the run of ones
ME = CountLeadingZeros_32((Val - 1) ^ Val);
return true;
- } else if (isShiftedMask_32(Val = ~Val)) { // invert mask
- // effectively look for the first zero bit
- ME = CountLeadingZeros_32(Val) - 1;
- // effectively look for the first one bit after the run of zeros
- MB = CountLeadingZeros_32((Val - 1) ^ Val) + 1;
- return true;
+ } else {
+ Val = ~Val; // invert mask
+ if (isShiftedMask_32(Val)) {
+ // effectively look for the first zero bit
+ ME = CountLeadingZeros_32(Val) - 1;
+ // effectively look for the first one bit after the run of zeros
+ MB = CountLeadingZeros_32((Val - 1) ^ Val) + 1;
+ return true;
+ }
}
// no run present
return false;
if (Addr.getOpcode() == ISD::ADD) {
if (isIntImmediate(Addr.getOperand(1), imm) && isInt16(imm)) {
Op1 = getI32Imm(Lo16(imm));
- if (isa<FrameIndexSDNode>(Addr.getOperand(0))) {
+ if (FrameIndexSDNode *FI =
+ dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
++FrameOff;
- Op2 = Addr.getOperand(0);
+ Op2 = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32);
} else {
Op2 = Select(Addr.getOperand(0));
}
Op2 = CurDAG->getTargetNode(PPC::LIS, MVT::i32, Op1);
return false;
}
- } else if (isa<FrameIndexSDNode>(Addr)) {
+ } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Addr)) {
Op1 = getI32Imm(0);
- Op2 = Addr;
+ Op2 = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32);
return false;
} else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Addr)) {
Op1 = Addr;
}
break;
}
+ case ISD::ConstantFP: { // FIXME: this should get sucked into the legalizer
+ MachineConstantPool *CP = CurDAG->getMachineFunction().getConstantPool();
+ Constant *CFP = ConstantFP::get(Type::FloatTy,
+ cast<ConstantFPSDNode>(N)->getValue());
+ SDOperand CPN = CurDAG->getConstantPool(CP->getConstantPoolIndex(CFP),
+ MVT::i32);
+ SDOperand Tmp;
+ if (PICEnabled)
+ Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPN);
+ else
+ Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPN);
+ CurDAG->SelectNodeTo(N, N->getValueType(0), PPC::LFS, CPN, Tmp);
+ break;
+ }
case ISD::UNDEF:
if (N->getValueType(0) == MVT::i32)
CurDAG->SelectNodeTo(N, MVT::i32, PPC::IMPLICIT_DEF_GPR);
else
CurDAG->SelectNodeTo(N, N->getValueType(0), PPC::IMPLICIT_DEF_FP);
break;
+ case ISD::FrameIndex: {
+ int FI = cast<FrameIndexSDNode>(N)->getIndex();
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::ADDI,
+ CurDAG->getTargetFrameIndex(FI, MVT::i32),
+ getI32Imm(0));
+ break;
+ }
+ case ISD::ConstantPool: {
+ unsigned CPIIdx = cast<ConstantPoolSDNode>(N)->getIndex();
+ SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(CPIIdx, MVT::i32);
+ if (PICEnabled)
+ Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI);
+ else
+ Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI);
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::LA, Tmp, CPI);
+ break;
+ }
case ISD::GlobalAddress: {
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
SDOperand Tmp;
case MVT::f32: Opc = PPC::FMULS; break;
case MVT::f64: Opc = PPC::FMUL; break;
}
- CurDAG->SelectNodeTo(N, N->getValueType(0), Opc, Select(N->getOperand(0)),
+ CurDAG->SelectNodeTo(N, MVT::i32, Opc, Select(N->getOperand(0)),
Select(N->getOperand(1)));
break;
}
+ case ISD::SDIV: {
+ unsigned Imm;
+ if (isIntImmediate(N->getOperand(1), Imm)) {
+ if ((signed)Imm > 0 && isPowerOf2_32(Imm)) {
+ SDOperand Op =
+ CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag,
+ Select(N->getOperand(0)),
+ getI32Imm(Log2_32(Imm)));
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::ADDZE,
+ Op.getValue(0), Op.getValue(1));
+ break;
+ } else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) {
+ SDOperand Op =
+ CurDAG->getTargetNode(PPC::SRAWI, MVT::Flag, MVT::i32,
+ Select(N->getOperand(0)),
+ getI32Imm(Log2_32(-Imm)));
+ SDOperand PT =
+ CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, Op.getValue(1),
+ Op.getValue(0));
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::NEG, PT);
+ break;
+ }
+ }
+ assert(0 && "SDIV not implemented yet!");
+ abort();
+ }
case ISD::MULHS:
assert(N->getValueType(0) == MVT::i32);
CurDAG->SelectNodeTo(N, MVT::i32, PPC::MULHW, Select(N->getOperand(0)),
DestReg = GPR[GPR_idx++];
RegTy = MVT::i32;
} else {
- assert(MVT::isFloatingPoint(Op.getValueType()) &&
+ assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) &&
"Unpromoted integer arg?");
assert(FPR_idx < 13 && "Too many fp args");
DestReg = FPR[FPR_idx++];
CurDAG->SelectNodeTo(N, MVT::Other, PPC::BLR, Chain);
break;
}
-
+ case ISD::BR:
+ CurDAG->SelectNodeTo(N, MVT::Other, PPC::B, N->getOperand(1),
+ Select(N->getOperand(0)));
+ break;
case ISD::BR_CC:
case ISD::BRTWOWAY_CC: {
SDOperand Chain = Select(N->getOperand(0));