* Make indentation consistent at 2 chars

* Doxygenify function comments
* Wrap code at 80 cols

llvm-svn: 14295
This commit is contained in:
Misha Brukman 2004-06-21 20:22:03 +00:00
parent a97f29237e
commit 5e323e10df
2 changed files with 616 additions and 394 deletions

View File

@ -518,8 +518,10 @@ void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
// Copy zero (null pointer) to the register. // Copy zero (null pointer) to the register.
BuildMI(*MBB, IP, PPC32::ADDI, 2, R).addReg(PPC32::R0).addImm(0); BuildMI(*MBB, IP, PPC32::ADDI, 2, R).addReg(PPC32::R0).addImm(0);
} else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) { } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) {
BuildMI(*MBB, IP, PPC32::ADDIS, 2, R).addReg(PPC32::R0).addGlobalAddress(CPR->getValue()); BuildMI(*MBB, IP, PPC32::ADDIS, 2, R).addReg(PPC32::R0)
BuildMI(*MBB, IP, PPC32::ORI, 2, R).addReg(PPC32::R0).addGlobalAddress(CPR->getValue()); .addGlobalAddress(CPR->getValue());
BuildMI(*MBB, IP, PPC32::ORI, 2, R).addReg(PPC32::R0)
.addGlobalAddress(CPR->getValue());
} else { } else {
std::cerr << "Offending constant: " << C << "\n"; std::cerr << "Offending constant: " << C << "\n";
assert(0 && "Type not handled yet!"); assert(0 && "Type not handled yet!");
@ -550,7 +552,8 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) { if (ArgLive) {
FI = MFI->CreateFixedObject(1, ArgOffset); FI = MFI->CreateFixedObject(1, ArgOffset);
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx).addReg(PPC32::R0+GPR_idx); BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx)
.addReg(PPC32::R0+GPR_idx);
} else { } else {
addFrameReference(BuildMI(BB, PPC32::LBZ, 2, Reg), FI); addFrameReference(BuildMI(BB, PPC32::LBZ, 2, Reg), FI);
} }
@ -560,7 +563,8 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) { if (ArgLive) {
FI = MFI->CreateFixedObject(2, ArgOffset); FI = MFI->CreateFixedObject(2, ArgOffset);
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx).addReg(PPC32::R0+GPR_idx); BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx)
.addReg(PPC32::R0+GPR_idx);
} else { } else {
addFrameReference(BuildMI(BB, PPC32::LHZ, 2, Reg), FI); addFrameReference(BuildMI(BB, PPC32::LHZ, 2, Reg), FI);
} }
@ -570,7 +574,8 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) { if (ArgLive) {
FI = MFI->CreateFixedObject(4, ArgOffset); FI = MFI->CreateFixedObject(4, ArgOffset);
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx).addReg(PPC32::R0+GPR_idx); BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx)
.addReg(PPC32::R0+GPR_idx);
} else { } else {
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI); addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI);
} }
@ -580,8 +585,10 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) { if (ArgLive) {
FI = MFI->CreateFixedObject(8, ArgOffset); FI = MFI->CreateFixedObject(8, ArgOffset);
if (GPR_remaining > 1) { if (GPR_remaining > 1) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx).addReg(PPC32::R0+GPR_idx); BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx)
BuildMI(BB, PPC32::OR, 2, Reg+1).addReg(PPC32::R0+GPR_idx+1).addReg(PPC32::R0+GPR_idx+1); .addReg(PPC32::R0+GPR_idx);
BuildMI(BB, PPC32::OR, 2, Reg+1).addReg(PPC32::R0+GPR_idx+1)
.addReg(PPC32::R0+GPR_idx+1);
} else { } else {
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI); addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI);
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg+1), FI, 4); addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg+1), FI, 4);
@ -794,10 +801,12 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
// Compare immediate or promote to reg? // Compare immediate or promote to reg?
if (Op1v <= 32767) { if (Op1v <= 32767) {
BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMPI : PPC32::CMPLI, 3, PPC32::CR0).addImm(0).addReg(Op0r).addImm(Op1v); BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMPI : PPC32::CMPLI, 3,
PPC32::CR0).addImm(0).addReg(Op0r).addImm(Op1v);
} else { } else {
unsigned Op1r = getReg(Op1, MBB, IP); unsigned Op1r = getReg(Op1, MBB, IP);
BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMP : PPC32::CMPL, 3, PPC32::CR0).addImm(0).addReg(Op0r).addReg(Op1r); BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMP : PPC32::CMPL, 3,
PPC32::CR0).addImm(0).addReg(Op0r).addReg(Op1r);
} }
return OpNum; return OpNum;
} else { } else {
@ -810,14 +819,16 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
unsigned LoLow = makeAnotherReg(Type::IntTy); unsigned LoLow = makeAnotherReg(Type::IntTy);
unsigned LoTmp = makeAnotherReg(Type::IntTy); unsigned LoTmp = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::XORI, 2, LoLow).addReg(Op0r).addImm(LowCst); BuildMI(*MBB, IP, PPC32::XORI, 2, LoLow).addReg(Op0r).addImm(LowCst);
BuildMI(*MBB, IP, PPC32::XORIS, 2, LoTmp).addReg(LoLow).addImm(LowCst >> 16); BuildMI(*MBB, IP, PPC32::XORIS, 2, LoTmp).addReg(LoLow)
.addImm(LowCst >> 16);
} }
unsigned HiTmp = Op0r+1; unsigned HiTmp = Op0r+1;
if (HiCst != 0) { if (HiCst != 0) {
unsigned HiLow = makeAnotherReg(Type::IntTy); unsigned HiLow = makeAnotherReg(Type::IntTy);
unsigned HiTmp = makeAnotherReg(Type::IntTy); unsigned HiTmp = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::XORI, 2, HiLow).addReg(Op0r+1).addImm(HiCst); BuildMI(*MBB, IP, PPC32::XORI, 2, HiLow).addReg(Op0r+1).addImm(HiCst);
BuildMI(*MBB, IP, PPC32::XORIS, 2, HiTmp).addReg(HiLow).addImm(HiCst >> 16); BuildMI(*MBB, IP, PPC32::XORIS, 2, HiTmp).addReg(HiLow)
.addImm(HiCst >> 16);
} }
unsigned FinalTmp = makeAnotherReg(Type::IntTy); unsigned FinalTmp = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::ORo, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp); BuildMI(*MBB, IP, PPC32::ORo, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp);
@ -845,7 +856,8 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
case cByte: case cByte:
case cShort: case cShort:
case cInt: case cInt:
BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMP : PPC32::CMPL, 2, PPC32::CR0).addReg(Op0r).addReg(Op1r); BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMP : PPC32::CMPL, 2,
PPC32::CR0).addReg(Op0r).addReg(Op1r);
break; break;
case cFP: case cFP:
emitUCOM(MBB, IP, Op0r, Op1r); emitUCOM(MBB, IP, Op0r, Op1r);
@ -887,7 +899,8 @@ void ISel::visitSetCondInst(SetCondInst &I) {
unsigned DestReg = getReg(I); unsigned DestReg = getReg(I);
MachineBasicBlock::iterator MII = BB->end(); MachineBasicBlock::iterator MII = BB->end();
emitSetCCOperation(BB, MII, I.getOperand(0), I.getOperand(1), I.getOpcode(),DestReg); emitSetCCOperation(BB, MII, I.getOperand(0), I.getOperand(1), I.getOpcode(),
DestReg);
} }
/// emitSetCCOperation - Common code shared between visitSetCondInst and /// emitSetCCOperation - Common code shared between visitSetCondInst and
@ -909,7 +922,8 @@ void ISel::emitSetCCOperation(MachineBasicBlock *MBB,
void ISel::visitSelectInst(SelectInst &SI) { void ISel::visitSelectInst(SelectInst &SI) {
unsigned DestReg = getReg(SI); unsigned DestReg = getReg(SI);
MachineBasicBlock::iterator MII = BB->end(); MachineBasicBlock::iterator MII = BB->end();
emitSelectOperation(BB, MII, SI.getCondition(), SI.getTrueValue(),SI.getFalseValue(), DestReg); emitSelectOperation(BB, MII, SI.getCondition(), SI.getTrueValue(),
SI.getFalseValue(), DestReg);
} }
/// emitSelect - Common code shared between visitSelectInst and the constant /// emitSelect - Common code shared between visitSelectInst and the constant
@ -933,7 +947,8 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB,
} }
if (SelectClass == cLong) if (SelectClass == cLong)
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(TrueReg+1).addReg(TrueReg+1); BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(TrueReg+1)
.addReg(TrueReg+1);
return; return;
} }
@ -946,7 +961,8 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB,
unsigned Temp2 = makeAnotherReg(Type::IntTy); unsigned Temp2 = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::CNTLZW, 1, numZeros).addReg(CondReg); BuildMI(*MBB, IP, PPC32::CNTLZW, 1, numZeros).addReg(CondReg);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, falseHi).addReg(numZeros).addImm(26).addImm(0).addImm(0); BuildMI(*MBB, IP, PPC32::RLWINM, 4, falseHi).addReg(numZeros).addImm(26)
.addImm(0).addImm(0);
BuildMI(*MBB, IP, PPC32::SRAWI, 2, falseAll).addReg(falseHi).addImm(31); BuildMI(*MBB, IP, PPC32::SRAWI, 2, falseAll).addReg(falseHi).addImm(31);
BuildMI(*MBB, IP, PPC32::NOR, 2, trueAll).addReg(falseAll).addReg(falseAll); BuildMI(*MBB, IP, PPC32::NOR, 2, trueAll).addReg(falseAll).addReg(falseAll);
BuildMI(*MBB, IP, PPC32::AND, 2, Temp1).addReg(TrueReg).addReg(trueAll); BuildMI(*MBB, IP, PPC32::AND, 2, Temp1).addReg(TrueReg).addReg(trueAll);
@ -980,7 +996,7 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
Ty = Type::IntTy; Ty = Type::IntTy;
} }
// If this is a simple constant, just emit a load directly to avoid the copy. // If this is a simple constant, just emit a load directly to avoid the copy
if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) { if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
int TheVal = CI->getRawValue() & 0xFFFFFFFF; int TheVal = CI->getRawValue() & 0xFFFFFFFF;
@ -988,8 +1004,10 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
BuildMI(BB, PPC32::ADDI, 2, targetReg).addReg(PPC32::R0).addImm(TheVal); BuildMI(BB, PPC32::ADDI, 2, targetReg).addReg(PPC32::R0).addImm(TheVal);
} else { } else {
unsigned TmpReg = makeAnotherReg(Type::IntTy); unsigned TmpReg = makeAnotherReg(Type::IntTy);
BuildMI(BB, PPC32::ADDIS, 2, TmpReg).addReg(PPC32::R0).addImm(TheVal >> 16); BuildMI(BB, PPC32::ADDIS, 2, TmpReg).addReg(PPC32::R0)
BuildMI(BB, PPC32::ORI, 2, targetReg).addReg(TmpReg).addImm(TheVal & 0xFFFF); .addImm(TheVal >> 16);
BuildMI(BB, PPC32::ORI, 2, targetReg).addReg(TmpReg)
.addImm(TheVal & 0xFFFF);
} }
return; return;
} }
@ -1002,14 +1020,16 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
case cByte: case cByte:
// Extend value into target register (8->32) // Extend value into target register (8->32)
if (isUnsigned) if (isUnsigned)
BuildMI(BB, PPC32::RLWINM, 4, targetReg).addReg(Reg).addZImm(0).addZImm(24).addZImm(31); BuildMI(BB, PPC32::RLWINM, 4, targetReg).addReg(Reg).addZImm(0)
.addZImm(24).addZImm(31);
else else
BuildMI(BB, PPC32::EXTSB, 1, targetReg).addReg(Reg); BuildMI(BB, PPC32::EXTSB, 1, targetReg).addReg(Reg);
break; break;
case cShort: case cShort:
// Extend value into target register (16->32) // Extend value into target register (16->32)
if (isUnsigned) if (isUnsigned)
BuildMI(BB, PPC32::RLWINM, 4, targetReg).addReg(Reg).addZImm(0).addZImm(16).addZImm(31); BuildMI(BB, PPC32::RLWINM, 4, targetReg).addReg(Reg).addZImm(0)
.addZImm(16).addZImm(31);
else else
BuildMI(BB, PPC32::EXTSH, 1, targetReg).addReg(Reg); BuildMI(BB, PPC32::EXTSH, 1, targetReg).addReg(Reg);
break; break;
@ -1022,7 +1042,8 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
} }
} }
// just emit blr. /// visitReturnInst - implemented with BLR
///
void ISel::visitReturnInst(ReturnInst &I) { void ISel::visitReturnInst(ReturnInst &I) {
Value *RetVal = I.getOperand(0); Value *RetVal = I.getOperand(0);
@ -1081,12 +1102,15 @@ void ISel::visitBranchInst(BranchInst &BI) {
// Nope, cannot fold setcc into this branch. Emit a branch on a condition // Nope, cannot fold setcc into this branch. Emit a branch on a condition
// computed some other way... // computed some other way...
unsigned condReg = getReg(BI.getCondition()); unsigned condReg = getReg(BI.getCondition());
BuildMI(BB, PPC32::CMPLI, 3, PPC32::CR0).addImm(0).addReg(condReg).addImm(0); BuildMI(BB, PPC32::CMPLI, 3, PPC32::CR0).addImm(0).addReg(condReg)
.addImm(0);
if (BI.getSuccessor(1) == NextBB) { if (BI.getSuccessor(1) == NextBB) {
if (BI.getSuccessor(0) != NextBB) if (BI.getSuccessor(0) != NextBB)
BuildMI(BB, PPC32::BC, 3).addImm(4).addImm(2).addMBB(MBBMap[BI.getSuccessor(0)]); BuildMI(BB, PPC32::BC, 3).addImm(4).addImm(2)
.addMBB(MBBMap[BI.getSuccessor(0)]);
} else { } else {
BuildMI(BB, PPC32::BC, 3).addImm(12).addImm(2).addMBB(MBBMap[BI.getSuccessor(1)]); BuildMI(BB, PPC32::BC, 3).addImm(12).addImm(2)
.addMBB(MBBMap[BI.getSuccessor(1)]);
if (BI.getSuccessor(0) != NextBB) if (BI.getSuccessor(0) != NextBB)
BuildMI(BB, PPC32::B, 1).addMBB(MBBMap[BI.getSuccessor(0)]); BuildMI(BB, PPC32::B, 1).addMBB(MBBMap[BI.getSuccessor(0)]);
@ -1117,13 +1141,15 @@ void ISel::visitBranchInst(BranchInst &BI) {
unsigned BIval = BITab[0]; unsigned BIval = BITab[0];
if (BI.getSuccessor(0) != NextBB) { if (BI.getSuccessor(0) != NextBB) {
BuildMI(BB, PPC32::BC, 3).addImm(BO_true).addImm(BIval).addMBB(MBBMap[BI.getSuccessor(0)]); BuildMI(BB, PPC32::BC, 3).addImm(BO_true).addImm(BIval)
.addMBB(MBBMap[BI.getSuccessor(0)]);
if (BI.getSuccessor(1) != NextBB) if (BI.getSuccessor(1) != NextBB)
BuildMI(BB, PPC32::B, 1).addMBB(MBBMap[BI.getSuccessor(1)]); BuildMI(BB, PPC32::B, 1).addMBB(MBBMap[BI.getSuccessor(1)]);
} else { } else {
// Change to the inverse condition... // Change to the inverse condition...
if (BI.getSuccessor(1) != NextBB) { if (BI.getSuccessor(1) != NextBB) {
BuildMI(BB, PPC32::BC, 3).addImm(BO_false).addImm(BIval).addMBB(MBBMap[BI.getSuccessor(1)]); BuildMI(BB, PPC32::BC, 3).addImm(BO_false).addImm(BIval)
.addMBB(MBBMap[BI.getSuccessor(1)]);
} }
} }
} }
@ -1174,9 +1200,11 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
// Reg or stack? // Reg or stack?
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg).addReg(ArgReg); BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg)
.addReg(ArgReg);
} else { } else {
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset)
.addReg(PPC32::R1);
} }
break; break;
case cInt: case cInt:
@ -1184,9 +1212,11 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
// Reg or stack? // Reg or stack?
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg).addReg(ArgReg); BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg)
.addReg(ArgReg);
} else { } else {
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset)
.addReg(PPC32::R1);
} }
break; break;
case cLong: case cLong:
@ -1194,11 +1224,15 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
// Reg or stack? // Reg or stack?
if (GPR_remaining > 1) { if (GPR_remaining > 1) {
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg).addReg(ArgReg); BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg)
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx + 1).addReg(ArgReg+1).addReg(ArgReg+1); .addReg(ArgReg);
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx + 1).addReg(ArgReg+1)
.addReg(ArgReg+1);
} else { } else {
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset)
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg+1).addImm(ArgOffset+4).addReg(PPC32::R1); .addReg(PPC32::R1);
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg+1).addImm(ArgOffset+4)
.addReg(PPC32::R1);
} }
ArgOffset += 4; // 8 byte entry, not 4. ArgOffset += 4; // 8 byte entry, not 4.
@ -1216,7 +1250,8 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
FPR_remaining--; FPR_remaining--;
FPR_idx++; FPR_idx++;
} else { } else {
BuildMI(BB, PPC32::STFS, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STFS, 3).addReg(ArgReg).addImm(ArgOffset)
.addReg(PPC32::R1);
} }
} else { } else {
assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!"); assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!");
@ -1226,7 +1261,8 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
FPR_remaining--; FPR_remaining--;
FPR_idx++; FPR_idx++;
} else { } else {
BuildMI(BB, PPC32::STFD, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STFD, 3).addReg(ArgReg).addImm(ArgOffset)
.addReg(PPC32::R1);
} }
ArgOffset += 4; // 8 byte entry, not 4. ArgOffset += 4; // 8 byte entry, not 4.
@ -1559,7 +1595,8 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
unsigned TmpReg = makeAnotherReg(Type::IntTy); unsigned TmpReg = makeAnotherReg(Type::IntTy);
emitUCOM(MBB, IP, Op0Reg, Op1Reg); emitUCOM(MBB, IP, Op0Reg, Op1Reg);
BuildMI(*MBB, IP, PPC32::MFCR, TmpReg); BuildMI(*MBB, IP, PPC32::MFCR, TmpReg);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(TmpReg).addImm(4).addImm(31).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(TmpReg).addImm(4)
.addImm(31).addImm(31);
return; return;
} }
} }
@ -1575,7 +1612,8 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
unsigned overflow = makeAnotherReg(Type::IntTy); unsigned overflow = makeAnotherReg(Type::IntTy);
unsigned T = makeAnotherReg(Type::IntTy); unsigned T = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::CNTLZW, 1, zeroes).addReg(op1Reg); BuildMI(*MBB, IP, PPC32::CNTLZW, 1, zeroes).addReg(op1Reg);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, overflow).addReg(zeroes).addImm(27).addImm(5).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, overflow).addReg(zeroes).addImm(27)
.addImm(5).addImm(31);
BuildMI(*MBB, IP, PPC32::ADD, 2, T).addReg(op1Reg+1).addReg(overflow); BuildMI(*MBB, IP, PPC32::ADD, 2, T).addReg(op1Reg+1).addReg(overflow);
BuildMI(*MBB, IP, PPC32::NEG, 1, DestReg+1).addReg(T); BuildMI(*MBB, IP, PPC32::NEG, 1, DestReg+1).addReg(T);
} }
@ -1590,7 +1628,8 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
if (OperatorClass == 4 && Op1C->isAllOnesValue()) { if (OperatorClass == 4 && Op1C->isAllOnesValue()) {
BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg).addReg(Op0r).addReg(Op0r); BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg).addReg(Op0r).addReg(Op0r);
if (Class == cLong) // Invert the top part too if (Class == cLong) // Invert the top part too
BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg+1).addReg(Op0r+1).addReg(Op0r+1); BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg+1).addReg(Op0r+1)
.addReg(Op0r+1);
return; return;
} }
@ -1632,8 +1671,10 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
// TODO: We could handle lots of other special cases here, such as AND'ing // TODO: We could handle lots of other special cases here, such as AND'ing
// with 0xFFFFFFFF00000000 -> noop, etc. // with 0xFFFFFFFF00000000 -> noop, etc.
BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r).addImm(Op1r); BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r)
BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1).addImm(Op1r+1); .addImm(Op1r);
BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
.addImm(Op1r+1);
return; return;
} }
@ -1644,8 +1685,10 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
unsigned Opcode = OpcodeTab[OperatorClass]; unsigned Opcode = OpcodeTab[OperatorClass];
BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r); BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r);
} else { } else {
BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r).addImm(Op1r); BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r)
BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1).addImm(Op1r+1); .addImm(Op1r);
BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
.addImm(Op1r+1);
} }
return; return;
} }
@ -1660,7 +1703,8 @@ void ISel::doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI,
unsigned Class = getClass(DestTy); unsigned Class = getClass(DestTy);
switch (Class) { switch (Class) {
case cLong: case cLong:
BuildMI(*MBB, MBBI, PPC32::MULHW, 2, DestReg+1).addReg(op0Reg+1).addReg(op1Reg+1); BuildMI(*MBB, MBBI, PPC32::MULHW, 2, DestReg+1).addReg(op0Reg+1)
.addReg(op1Reg+1);
case cInt: case cInt:
case cShort: case cShort:
case cByte: case cByte:
@ -1686,6 +1730,7 @@ static unsigned ExactLog2(unsigned Val) {
/// doMultiplyConst - This function is specialized to efficiently codegen an 8, /// doMultiplyConst - This function is specialized to efficiently codegen an 8,
/// 16, or 32-bit integer multiply by a constant. /// 16, or 32-bit integer multiply by a constant.
///
void ISel::doMultiplyConst(MachineBasicBlock *MBB, void ISel::doMultiplyConst(MachineBasicBlock *MBB,
MachineBasicBlock::iterator IP, MachineBasicBlock::iterator IP,
unsigned DestReg, const Type *DestTy, unsigned DestReg, const Type *DestTy,
@ -1711,7 +1756,8 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB,
case cByte: case cByte:
case cShort: case cShort:
case cInt: case cInt:
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(op0Reg).addImm(Shift-1).addImm(0).addImm(31-Shift-1); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(op0Reg)
.addImm(Shift-1).addImm(0).addImm(31-Shift-1);
return; return;
} }
} }
@ -1719,7 +1765,8 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB,
// Most general case, emit a normal multiply... // Most general case, emit a normal multiply...
unsigned TmpReg1 = makeAnotherReg(Type::IntTy); unsigned TmpReg1 = makeAnotherReg(Type::IntTy);
unsigned TmpReg2 = makeAnotherReg(Type::IntTy); unsigned TmpReg2 = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::ADDIS, 2, TmpReg1).addReg(PPC32::R0).addImm(ConstRHS >> 16); BuildMI(*MBB, IP, PPC32::ADDIS, 2, TmpReg1).addReg(PPC32::R0)
.addImm(ConstRHS >> 16);
BuildMI(*MBB, IP, PPC32::ORI, 2, TmpReg2).addReg(TmpReg1).addImm(ConstRHS); BuildMI(*MBB, IP, PPC32::ORI, 2, TmpReg2).addReg(TmpReg1).addImm(ConstRHS);
// Emit a MUL to multiply the register holding the index by // Emit a MUL to multiply the register holding the index by
@ -1783,10 +1830,12 @@ void ISel::emitMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
unsigned TmpRegL = makeAnotherReg(Type::UIntTy); unsigned TmpRegL = makeAnotherReg(Type::UIntTy);
unsigned Op1RegL = makeAnotherReg(Type::UIntTy); unsigned Op1RegL = makeAnotherReg(Type::UIntTy);
OverflowReg = makeAnotherReg(Type::UIntTy); OverflowReg = makeAnotherReg(Type::UIntTy);
BuildMI(BB, IP, PPC32::ADDIS, 2, TmpRegL).addReg(PPC32::R0).addImm(CLow >> 16); BuildMI(BB, IP, PPC32::ADDIS, 2, TmpRegL).addReg(PPC32::R0)
.addImm(CLow >> 16);
BuildMI(BB, IP, PPC32::ORI, 2, Op1RegL).addReg(TmpRegL).addImm(CLow); BuildMI(BB, IP, PPC32::ORI, 2, Op1RegL).addReg(TmpRegL).addImm(CLow);
BuildMI(BB, IP, PPC32::MULLW, 2, DestReg).addReg(Op0Reg).addReg(Op1RegL); BuildMI(BB, IP, PPC32::MULLW, 2, DestReg).addReg(Op0Reg).addReg(Op1RegL);
BuildMI(BB, IP, PPC32::MULHW, 2, OverflowReg).addReg(Op0Reg).addReg(Op1RegL); BuildMI(BB, IP, PPC32::MULHW, 2, OverflowReg).addReg(Op0Reg)
.addReg(Op1RegL);
} }
unsigned AHBLReg = makeAnotherReg(Type::UIntTy); unsigned AHBLReg = makeAnotherReg(Type::UIntTy);
@ -1802,7 +1851,8 @@ void ISel::emitMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
} }
if (CHi == 0) { if (CHi == 0) {
BuildMI(BB, IP, PPC32::OR, 2, DestReg+1).addReg(AHBLplusOverflowReg).addReg(AHBLplusOverflowReg); BuildMI(BB, IP, PPC32::OR, 2, DestReg+1).addReg(AHBLplusOverflowReg)
.addReg(AHBLplusOverflowReg);
} else { } else {
unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH
doMultiplyConst(&BB, IP, ALBHReg, Type::UIntTy, Op0Reg, CHi); doMultiplyConst(&BB, IP, ALBHReg, Type::UIntTy, Op0Reg, CHi);
@ -1848,7 +1898,8 @@ void ISel::visitDivRem(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
MachineBasicBlock::iterator IP = BB->end(); MachineBasicBlock::iterator IP = BB->end();
emitDivRemOperation(BB, IP, Op0, Op1, I.getOpcode() == Instruction::Div, ResultReg); emitDivRemOperation(BB, IP, Op0, Op1, I.getOpcode() == Instruction::Div,
ResultReg);
} }
void ISel::emitDivRemOperation(MachineBasicBlock *BB, void ISel::emitDivRemOperation(MachineBasicBlock *BB,
@ -1926,7 +1977,8 @@ void ISel::emitDivRemOperation(MachineBasicBlock *BB,
BuildMI(*BB, IP, PPC32::OR, 2, TmpReg).addReg(Op0Reg).addReg(Op0Reg); BuildMI(*BB, IP, PPC32::OR, 2, TmpReg).addReg(Op0Reg).addReg(Op0Reg);
unsigned TmpReg2 = makeAnotherReg(Op0->getType()); unsigned TmpReg2 = makeAnotherReg(Op0->getType());
BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg2).addReg(TmpReg).addImm(Log).addImm(32-Log).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg2).addReg(TmpReg).addImm(Log)
.addImm(32-Log).addImm(31);
unsigned TmpReg3 = makeAnotherReg(Op0->getType()); unsigned TmpReg3 = makeAnotherReg(Op0->getType());
BuildMI(*BB, IP, PPC32::ADD, 2, TmpReg3).addReg(Op0Reg).addReg(TmpReg2); BuildMI(*BB, IP, PPC32::ADD, 2, TmpReg3).addReg(Op0Reg).addReg(TmpReg2);
@ -1978,6 +2030,7 @@ void ISel::visitShiftInst(ShiftInst &I) {
/// emitShiftOperation - Common code shared between visitShiftInst and /// emitShiftOperation - Common code shared between visitShiftInst and
/// constant expression support. /// constant expression support.
///
void ISel::emitShiftOperation(MachineBasicBlock *MBB, void ISel::emitShiftOperation(MachineBasicBlock *MBB,
MachineBasicBlock::iterator IP, MachineBasicBlock::iterator IP,
Value *Op, Value *ShiftAmount, bool isLeftShift, Value *Op, Value *ShiftAmount, bool isLeftShift,
@ -1996,32 +2049,43 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
if (Amount < 32) { if (Amount < 32) {
if (isLeftShift) { if (isLeftShift) {
// FIXME: RLWIMI is a use-and-def of DestReg+1, but that violates SSA // FIXME: RLWIMI is a use-and-def of DestReg+1, but that violates SSA
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg+1).addImm(Amount).addImm(0).addImm(31-Amount); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg+1)
BuildMI(*MBB, IP, PPC32::RLWIMI, 5).addReg(DestReg+1).addReg(SrcReg).addImm(Amount).addImm(32-Amount).addImm(31); .addImm(Amount).addImm(0).addImm(31-Amount);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addImm(Amount).addImm(0).addImm(31-Amount); BuildMI(*MBB, IP, PPC32::RLWIMI, 5).addReg(DestReg+1).addReg(SrcReg)
.addImm(Amount).addImm(32-Amount).addImm(31);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg)
.addImm(Amount).addImm(0).addImm(31-Amount);
} else { } else {
// FIXME: RLWIMI is a use-and-def of DestReg, but that violates SSA // FIXME: RLWIMI is a use-and-def of DestReg, but that violates SSA
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addImm(32-Amount).addImm(Amount).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg)
BuildMI(*MBB, IP, PPC32::RLWIMI, 5).addReg(DestReg).addReg(SrcReg+1).addImm(32-Amount).addImm(0).addImm(Amount-1); .addImm(32-Amount).addImm(Amount).addImm(31);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg+1).addImm(32-Amount).addImm(Amount).addImm(31); BuildMI(*MBB, IP, PPC32::RLWIMI, 5).addReg(DestReg).addReg(SrcReg+1)
.addImm(32-Amount).addImm(0).addImm(Amount-1);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg+1)
.addImm(32-Amount).addImm(Amount).addImm(31);
} }
} else { // Shifting more than 32 bits } else { // Shifting more than 32 bits
Amount -= 32; Amount -= 32;
if (isLeftShift) { if (isLeftShift) {
if (Amount != 0) { if (Amount != 0) {
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg).addImm(Amount).addImm(0).addImm(31-Amount); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg)
.addImm(Amount).addImm(0).addImm(31-Amount);
} else { } else {
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(SrcReg).addReg(SrcReg); BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(SrcReg)
.addReg(SrcReg);
} }
BuildMI(*MBB, IP, PPC32::ADDI, 2,DestReg).addReg(PPC32::R0).addImm(0); BuildMI(*MBB, IP, PPC32::ADDI, 2,DestReg).addReg(PPC32::R0).addImm(0);
} else { } else {
if (Amount != 0) { if (Amount != 0) {
if (isSigned) if (isSigned)
BuildMI(*MBB, IP, PPC32::SRAWI, 2, DestReg).addReg(SrcReg+1).addImm(Amount); BuildMI(*MBB, IP, PPC32::SRAWI, 2, DestReg).addReg(SrcReg+1)
.addImm(Amount);
else else
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg+1).addImm(32-Amount).addImm(Amount).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg+1)
.addImm(32-Amount).addImm(Amount).addImm(31);
} else { } else {
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg+1).addReg(SrcReg+1); BuildMI(*MBB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg+1)
.addReg(SrcReg+1);
} }
BuildMI(*MBB, IP,PPC32::ADDI,2,DestReg+1).addReg(PPC32::R0).addImm(0); BuildMI(*MBB, IP,PPC32::ADDI,2,DestReg+1).addReg(PPC32::R0).addImm(0);
} }
@ -2036,27 +2100,40 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
unsigned ShiftAmountReg = getReg (ShiftAmount, MBB, IP); unsigned ShiftAmountReg = getReg (ShiftAmount, MBB, IP);
if (isLeftShift) { if (isLeftShift) {
BuildMI(*MBB, IP, PPC32::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg).addImm(32); BuildMI(*MBB, IP, PPC32::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg)
BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg2).addReg(SrcReg+1).addReg(ShiftAmountReg); .addImm(32);
BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg2).addReg(SrcReg+1)
.addReg(ShiftAmountReg);
BuildMI(*MBB, IP, PPC32::SRW, 2,TmpReg3).addReg(SrcReg).addReg(TmpReg1); BuildMI(*MBB, IP, PPC32::SRW, 2,TmpReg3).addReg(SrcReg).addReg(TmpReg1);
BuildMI(*MBB, IP, PPC32::OR, 2,TmpReg4).addReg(TmpReg2).addReg(TmpReg3); BuildMI(*MBB, IP, PPC32::OR, 2,TmpReg4).addReg(TmpReg2).addReg(TmpReg3);
BuildMI(*MBB, IP, PPC32::ADDI, 2, TmpReg5).addReg(ShiftAmountReg).addImm(-32); BuildMI(*MBB, IP, PPC32::ADDI, 2, TmpReg5).addReg(ShiftAmountReg)
.addImm(-32);
BuildMI(*MBB, IP, PPC32::SLW, 2,TmpReg6).addReg(SrcReg).addReg(TmpReg5); BuildMI(*MBB, IP, PPC32::SLW, 2,TmpReg6).addReg(SrcReg).addReg(TmpReg5);
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(TmpReg4).addReg(TmpReg6); BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(TmpReg4)
BuildMI(*MBB, IP, PPC32::SLW, 2, DestReg).addReg(SrcReg).addReg(ShiftAmountReg); .addReg(TmpReg6);
BuildMI(*MBB, IP, PPC32::SLW, 2, DestReg).addReg(SrcReg)
.addReg(ShiftAmountReg);
} else { } else {
if (isSigned) { if (isSigned) {
// FIXME: Unimplmented // FIXME: Unimplmented
// Page C-3 of the PowerPC 32bit Programming Environments Manual // Page C-3 of the PowerPC 32bit Programming Environments Manual
} else { } else {
BuildMI(*MBB, IP, PPC32::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg).addImm(32); BuildMI(*MBB, IP, PPC32::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg)
BuildMI(*MBB, IP, PPC32::SRW, 2, TmpReg2).addReg(SrcReg).addReg(ShiftAmountReg); .addImm(32);
BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg3).addReg(SrcReg+1).addReg(TmpReg1); BuildMI(*MBB, IP, PPC32::SRW, 2, TmpReg2).addReg(SrcReg)
BuildMI(*MBB, IP, PPC32::OR, 2, TmpReg4).addReg(TmpReg2).addReg(TmpReg3); .addReg(ShiftAmountReg);
BuildMI(*MBB, IP, PPC32::ADDI, 2, TmpReg5).addReg(ShiftAmountReg).addImm(-32); BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg3).addReg(SrcReg+1)
BuildMI(*MBB, IP, PPC32::SRW, 2, TmpReg6).addReg(SrcReg+1).addReg(TmpReg5); .addReg(TmpReg1);
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg).addReg(TmpReg4).addReg(TmpReg6); BuildMI(*MBB, IP, PPC32::OR, 2, TmpReg4).addReg(TmpReg2)
BuildMI(*MBB, IP, PPC32::SRW, 2, DestReg+1).addReg(SrcReg+1).addReg(ShiftAmountReg); .addReg(TmpReg3);
BuildMI(*MBB, IP, PPC32::ADDI, 2, TmpReg5).addReg(ShiftAmountReg)
.addImm(-32);
BuildMI(*MBB, IP, PPC32::SRW, 2, TmpReg6).addReg(SrcReg+1)
.addReg(TmpReg5);
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg).addReg(TmpReg4)
.addReg(TmpReg6);
BuildMI(*MBB, IP, PPC32::SRW, 2, DestReg+1).addReg(SrcReg+1)
.addReg(ShiftAmountReg);
} }
} }
} }
@ -2069,21 +2146,25 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
unsigned Amount = CUI->getValue(); unsigned Amount = CUI->getValue();
if (isLeftShift) { if (isLeftShift) {
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addImm(Amount).addImm(0).addImm(31-Amount); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg)
.addImm(Amount).addImm(0).addImm(31-Amount);
} else { } else {
if (isSigned) { if (isSigned) {
BuildMI(*MBB, IP, PPC32::SRAWI,2,DestReg).addReg(SrcReg).addImm(Amount); BuildMI(*MBB, IP, PPC32::SRAWI,2,DestReg).addReg(SrcReg).addImm(Amount);
} else { } else {
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addImm(32-Amount).addImm(Amount).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg)
.addImm(32-Amount).addImm(Amount).addImm(31);
} }
} }
} else { // The shift amount is non-constant. } else { // The shift amount is non-constant.
unsigned ShiftAmountReg = getReg (ShiftAmount, MBB, IP); unsigned ShiftAmountReg = getReg (ShiftAmount, MBB, IP);
if (isLeftShift) { if (isLeftShift) {
BuildMI(*MBB, IP, PPC32::SLW, 2, DestReg).addReg(SrcReg).addReg(ShiftAmountReg); BuildMI(*MBB, IP, PPC32::SLW, 2, DestReg).addReg(SrcReg)
.addReg(ShiftAmountReg);
} else { } else {
BuildMI(*MBB, IP, isSigned ? PPC32::SRAW : PPC32::SRW, 2, DestReg).addReg(SrcReg).addReg(ShiftAmountReg); BuildMI(*MBB, IP, isSigned ? PPC32::SRAW : PPC32::SRW, 2, DestReg)
.addReg(SrcReg).addReg(ShiftAmountReg);
} }
} }
} }
@ -2092,7 +2173,9 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
/// visitLoadInst - Implement LLVM load instructions /// visitLoadInst - Implement LLVM load instructions
/// ///
void ISel::visitLoadInst(LoadInst &I) { void ISel::visitLoadInst(LoadInst &I) {
static const unsigned Opcodes[] = { PPC32::LBZ, PPC32::LHZ, PPC32::LWZ, PPC32::LFS }; static const unsigned Opcodes[] = {
PPC32::LBZ, PPC32::LHZ, PPC32::LWZ, PPC32::LFS
};
unsigned Class = getClassB(I.getType()); unsigned Class = getClassB(I.getType());
unsigned Opcode = Opcodes[Class]; unsigned Opcode = Opcodes[Class];
if (I.getType() == Type::DoubleTy) Opcode = PPC32::LFD; if (I.getType() == Type::DoubleTy) Opcode = PPC32::LFD;
@ -2242,7 +2325,8 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
} }
} else if (SrcClass == cLong) { } else if (SrcClass == cLong) {
BuildMI(*BB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
BuildMI(*BB, IP, PPC32::OR, 2, DestReg+1).addReg(SrcReg+1).addReg(SrcReg+1); BuildMI(*BB, IP, PPC32::OR, 2, DestReg+1).addReg(SrcReg+1)
.addReg(SrcReg+1);
} else { } else {
assert(0 && "Cannot handle this type of cast instruction!"); assert(0 && "Cannot handle this type of cast instruction!");
abort(); abort();
@ -2261,9 +2345,11 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
if (SrcClass < cInt) { if (SrcClass < cInt) {
if (isUnsigned) { if (isUnsigned) {
unsigned shift = (SrcClass == cByte) ? 24 : 16; unsigned shift = (SrcClass == cByte) ? 24 : 16;
BuildMI(*BB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addZImm(0).addImm(shift).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addZImm(0)
.addImm(shift).addImm(31);
} else { } else {
BuildMI(*BB, IP, (SrcClass == cByte) ? PPC32::EXTSB : PPC32::EXTSH, 1, DestReg).addReg(SrcReg); BuildMI(*BB, IP, (SrcClass == cByte) ? PPC32::EXTSB : PPC32::EXTSH,
1, DestReg).addReg(SrcReg);
} }
} else { } else {
BuildMI(*BB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
@ -2290,9 +2376,11 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
bool isUnsigned = SrcTy->isUnsigned() || SrcTy == Type::BoolTy; bool isUnsigned = SrcTy->isUnsigned() || SrcTy == Type::BoolTy;
if (isUnsigned) { if (isUnsigned) {
unsigned shift = (SrcClass == cByte) ? 24 : 16; unsigned shift = (SrcClass == cByte) ? 24 : 16;
BuildMI(*BB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addZImm(0).addImm(shift).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addZImm(0)
.addImm(shift).addImm(31);
} else { } else {
BuildMI(*BB, IP, (SrcClass == cByte) ? PPC32::EXTSB : PPC32::EXTSH, 1, DestReg).addReg(SrcReg); BuildMI(*BB, IP, (SrcClass == cByte) ? PPC32::EXTSB : PPC32::EXTSH, 1,
DestReg).addReg(SrcReg);
} }
return; return;
} }
@ -2304,7 +2392,8 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
if (SrcClass == cLong) { if (SrcClass == cLong) {
std::vector<ValueRecord> Args; std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(SrcReg, SrcTy)); Args.push_back(ValueRecord(SrcReg, SrcTy));
MachineInstr *TheCall = BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("__floatdidf", true); MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("__floatdidf", true);
doCall(ValueRecord(DestReg, DestTy), TheCall, Args); doCall(ValueRecord(DestReg, DestTy), TheCall, Args);
return; return;
} }
@ -2316,13 +2405,15 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
BuildMI(*BB, IP, PPC32::EXTSB, 1, TmpReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::EXTSB, 1, TmpReg).addReg(SrcReg);
break; break;
case Type::UByteTyID: case Type::UByteTyID:
BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg).addReg(SrcReg).addZImm(0).addImm(24).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg).addReg(SrcReg).addZImm(0)
.addImm(24).addImm(31);
break; break;
case Type::ShortTyID: case Type::ShortTyID:
BuildMI(*BB, IP, PPC32::EXTSB, 1, TmpReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::EXTSB, 1, TmpReg).addReg(SrcReg);
break; break;
case Type::UShortTyID: case Type::UShortTyID:
BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg).addReg(SrcReg).addZImm(0).addImm(16).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg).addReg(SrcReg).addZImm(0)
.addImm(16).addImm(31);
break; break;
case Type::IntTyID: case Type::IntTyID:
BuildMI(*BB, IP, PPC32::OR, 2, TmpReg).addReg(SrcReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::OR, 2, TmpReg).addReg(SrcReg).addReg(SrcReg);
@ -2349,25 +2440,38 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
unsigned TempF = makeAnotherReg(Type::DoubleTy); unsigned TempF = makeAnotherReg(Type::DoubleTy);
if (!SrcTy->isSigned()) { if (!SrcTy->isSigned()) {
BuildMI(*BB, IP, PPC32::ADDIS, 2, constantHi).addReg(PPC32::R0).addImm(0x4330); BuildMI(*BB, IP, PPC32::ADDIS, 2, constantHi).addReg(PPC32::R0)
.addImm(0x4330);
BuildMI(*BB, IP, PPC32::ADDI, 2, constantLo).addReg(PPC32::R0).addImm(0); BuildMI(*BB, IP, PPC32::ADDI, 2, constantLo).addReg(PPC32::R0).addImm(0);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi), ConstantFrameIndex); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi),
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantLo), ConstantFrameIndex, 4); ConstantFrameIndex);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantLo),
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(SrcReg), ValueFrameIdx, 4); ConstantFrameIndex, 4);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, ConstF), ConstantFrameIndex); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi),
ValueFrameIdx);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(SrcReg),
ValueFrameIdx, 4);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, ConstF),
ConstantFrameIndex);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, TempF), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, TempF), ValueFrameIdx);
BuildMI(*BB, IP, PPC32::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF); BuildMI(*BB, IP, PPC32::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF);
} else { } else {
unsigned TempLo = makeAnotherReg(Type::IntTy); unsigned TempLo = makeAnotherReg(Type::IntTy);
BuildMI(*BB, IP, PPC32::ADDIS, 2, constantHi).addReg(PPC32::R0).addImm(0x4330); BuildMI(*BB, IP, PPC32::ADDIS, 2, constantHi).addReg(PPC32::R0)
BuildMI(*BB, IP, PPC32::ADDIS, 2, constantLo).addReg(PPC32::R0).addImm(0x8000); .addImm(0x4330);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi), ConstantFrameIndex); BuildMI(*BB, IP, PPC32::ADDIS, 2, constantLo).addReg(PPC32::R0)
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantLo), ConstantFrameIndex, 4); .addImm(0x8000);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi),
ConstantFrameIndex);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantLo),
ConstantFrameIndex, 4);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi),
ValueFrameIdx);
BuildMI(*BB, IP, PPC32::XORIS, 2, TempLo).addReg(SrcReg).addImm(0x8000); BuildMI(*BB, IP, PPC32::XORIS, 2, TempLo).addReg(SrcReg).addImm(0x8000);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(TempLo), ValueFrameIdx, 4); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(TempLo),
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, ConstF), ConstantFrameIndex); ValueFrameIdx, 4);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, ConstF),
ConstantFrameIndex);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, TempF), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, TempF), ValueFrameIdx);
BuildMI(*BB, IP, PPC32::FSUB, 2, DestReg).addReg(TempF ).addReg(ConstF); BuildMI(*BB, IP, PPC32::FSUB, 2, DestReg).addReg(TempF ).addReg(ConstF);
} }
@ -2381,7 +2485,8 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
if (DestClass == cLong) { if (DestClass == cLong) {
std::vector<ValueRecord> Args; std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(SrcReg, SrcTy)); Args.push_back(ValueRecord(SrcReg, SrcTy));
MachineInstr *TheCall = BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("__fixdfdi", true); MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("__fixdfdi", true);
doCall(ValueRecord(DestReg, DestTy), TheCall, Args); doCall(ValueRecord(DestReg, DestTy), TheCall, Args);
return; return;
} }
@ -2394,8 +2499,10 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
//if (DestTy->isSigned()) { //if (DestTy->isSigned()) {
unsigned TempReg = makeAnotherReg(Type::DoubleTy); unsigned TempReg = makeAnotherReg(Type::DoubleTy);
BuildMI(*BB, IP, PPC32::FCTIWZ, 1, TempReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::FCTIWZ, 1, TempReg).addReg(SrcReg);
addFrameReference(BuildMI(*BB, IP, PPC32::STFD, 3).addReg(TempReg), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::STFD, 3)
addFrameReference(BuildMI(*BB, IP, PPC32::LWZ, 2, DestReg), ValueFrameIdx+4); .addReg(TempReg), ValueFrameIdx);
addFrameReference(BuildMI(*BB, IP, PPC32::LWZ, 2, DestReg),
ValueFrameIdx+4);
//} else { //} else {
//} //}
@ -2465,7 +2572,8 @@ void ISel::visitVAArgInst(VAArgInst &I) {
/// ///
void ISel::visitGetElementPtrInst(GetElementPtrInst &I) { void ISel::visitGetElementPtrInst(GetElementPtrInst &I) {
unsigned outputReg = getReg(I); unsigned outputReg = getReg(I);
emitGEPOperation(BB, BB->end(), I.getOperand(0),I.op_begin()+1, I.op_end(), outputReg); emitGEPOperation(BB, BB->end(), I.getOperand(0), I.op_begin()+1, I.op_end(),
outputReg);
} }
void ISel::emitGEPOperation(MachineBasicBlock *MBB, void ISel::emitGEPOperation(MachineBasicBlock *MBB,
@ -2569,7 +2677,8 @@ void ISel::visitAllocaInst(AllocaInst &I) {
// AlignedSize = and <AddedSize>, ~15 // AlignedSize = and <AddedSize>, ~15
unsigned AlignedSize = makeAnotherReg(Type::UIntTy); unsigned AlignedSize = makeAnotherReg(Type::UIntTy);
BuildMI(BB, PPC32::RLWNM, 4, AlignedSize).addReg(AddedSizeReg).addImm(0).addImm(0).addImm(27); BuildMI(BB, PPC32::RLWNM, 4, AlignedSize).addReg(AddedSizeReg).addImm(0)
.addImm(0).addImm(27);
// Subtract size from stack pointer, thereby allocating some space. // Subtract size from stack pointer, thereby allocating some space.
BuildMI(BB, PPC32::SUB, 2, PPC32::R1).addReg(PPC32::R1).addReg(AlignedSize); BuildMI(BB, PPC32::SUB, 2, PPC32::R1).addReg(PPC32::R1).addReg(AlignedSize);
@ -2601,7 +2710,8 @@ void ISel::visitMallocInst(MallocInst &I) {
std::vector<ValueRecord> Args; std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(Arg, Type::UIntTy)); Args.push_back(ValueRecord(Arg, Type::UIntTy));
MachineInstr *TheCall = BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("malloc", true); MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("malloc", true);
doCall(ValueRecord(getReg(I), I.getType()), TheCall, Args); doCall(ValueRecord(getReg(I), I.getType()), TheCall, Args);
} }
@ -2612,7 +2722,8 @@ void ISel::visitMallocInst(MallocInst &I) {
void ISel::visitFreeInst(FreeInst &I) { void ISel::visitFreeInst(FreeInst &I) {
std::vector<ValueRecord> Args; std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(I.getOperand(0))); Args.push_back(ValueRecord(I.getOperand(0)));
MachineInstr *TheCall = BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("free", true); MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("free", true);
doCall(ValueRecord(0, Type::VoidTy), TheCall, Args); doCall(ValueRecord(0, Type::VoidTy), TheCall, Args);
} }

View File

@ -518,8 +518,10 @@ void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
// Copy zero (null pointer) to the register. // Copy zero (null pointer) to the register.
BuildMI(*MBB, IP, PPC32::ADDI, 2, R).addReg(PPC32::R0).addImm(0); BuildMI(*MBB, IP, PPC32::ADDI, 2, R).addReg(PPC32::R0).addImm(0);
} else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) { } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) {
BuildMI(*MBB, IP, PPC32::ADDIS, 2, R).addReg(PPC32::R0).addGlobalAddress(CPR->getValue()); BuildMI(*MBB, IP, PPC32::ADDIS, 2, R).addReg(PPC32::R0)
BuildMI(*MBB, IP, PPC32::ORI, 2, R).addReg(PPC32::R0).addGlobalAddress(CPR->getValue()); .addGlobalAddress(CPR->getValue());
BuildMI(*MBB, IP, PPC32::ORI, 2, R).addReg(PPC32::R0)
.addGlobalAddress(CPR->getValue());
} else { } else {
std::cerr << "Offending constant: " << C << "\n"; std::cerr << "Offending constant: " << C << "\n";
assert(0 && "Type not handled yet!"); assert(0 && "Type not handled yet!");
@ -550,7 +552,8 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) { if (ArgLive) {
FI = MFI->CreateFixedObject(1, ArgOffset); FI = MFI->CreateFixedObject(1, ArgOffset);
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx).addReg(PPC32::R0+GPR_idx); BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx)
.addReg(PPC32::R0+GPR_idx);
} else { } else {
addFrameReference(BuildMI(BB, PPC32::LBZ, 2, Reg), FI); addFrameReference(BuildMI(BB, PPC32::LBZ, 2, Reg), FI);
} }
@ -560,7 +563,8 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) { if (ArgLive) {
FI = MFI->CreateFixedObject(2, ArgOffset); FI = MFI->CreateFixedObject(2, ArgOffset);
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx).addReg(PPC32::R0+GPR_idx); BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx)
.addReg(PPC32::R0+GPR_idx);
} else { } else {
addFrameReference(BuildMI(BB, PPC32::LHZ, 2, Reg), FI); addFrameReference(BuildMI(BB, PPC32::LHZ, 2, Reg), FI);
} }
@ -570,7 +574,8 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) { if (ArgLive) {
FI = MFI->CreateFixedObject(4, ArgOffset); FI = MFI->CreateFixedObject(4, ArgOffset);
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx).addReg(PPC32::R0+GPR_idx); BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx)
.addReg(PPC32::R0+GPR_idx);
} else { } else {
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI); addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI);
} }
@ -580,8 +585,10 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) { if (ArgLive) {
FI = MFI->CreateFixedObject(8, ArgOffset); FI = MFI->CreateFixedObject(8, ArgOffset);
if (GPR_remaining > 1) { if (GPR_remaining > 1) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx).addReg(PPC32::R0+GPR_idx); BuildMI(BB, PPC32::OR, 2, Reg).addReg(PPC32::R0+GPR_idx)
BuildMI(BB, PPC32::OR, 2, Reg+1).addReg(PPC32::R0+GPR_idx+1).addReg(PPC32::R0+GPR_idx+1); .addReg(PPC32::R0+GPR_idx);
BuildMI(BB, PPC32::OR, 2, Reg+1).addReg(PPC32::R0+GPR_idx+1)
.addReg(PPC32::R0+GPR_idx+1);
} else { } else {
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI); addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI);
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg+1), FI, 4); addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg+1), FI, 4);
@ -794,10 +801,12 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
// Compare immediate or promote to reg? // Compare immediate or promote to reg?
if (Op1v <= 32767) { if (Op1v <= 32767) {
BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMPI : PPC32::CMPLI, 3, PPC32::CR0).addImm(0).addReg(Op0r).addImm(Op1v); BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMPI : PPC32::CMPLI, 3,
PPC32::CR0).addImm(0).addReg(Op0r).addImm(Op1v);
} else { } else {
unsigned Op1r = getReg(Op1, MBB, IP); unsigned Op1r = getReg(Op1, MBB, IP);
BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMP : PPC32::CMPL, 3, PPC32::CR0).addImm(0).addReg(Op0r).addReg(Op1r); BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMP : PPC32::CMPL, 3,
PPC32::CR0).addImm(0).addReg(Op0r).addReg(Op1r);
} }
return OpNum; return OpNum;
} else { } else {
@ -810,14 +819,16 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
unsigned LoLow = makeAnotherReg(Type::IntTy); unsigned LoLow = makeAnotherReg(Type::IntTy);
unsigned LoTmp = makeAnotherReg(Type::IntTy); unsigned LoTmp = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::XORI, 2, LoLow).addReg(Op0r).addImm(LowCst); BuildMI(*MBB, IP, PPC32::XORI, 2, LoLow).addReg(Op0r).addImm(LowCst);
BuildMI(*MBB, IP, PPC32::XORIS, 2, LoTmp).addReg(LoLow).addImm(LowCst >> 16); BuildMI(*MBB, IP, PPC32::XORIS, 2, LoTmp).addReg(LoLow)
.addImm(LowCst >> 16);
} }
unsigned HiTmp = Op0r+1; unsigned HiTmp = Op0r+1;
if (HiCst != 0) { if (HiCst != 0) {
unsigned HiLow = makeAnotherReg(Type::IntTy); unsigned HiLow = makeAnotherReg(Type::IntTy);
unsigned HiTmp = makeAnotherReg(Type::IntTy); unsigned HiTmp = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::XORI, 2, HiLow).addReg(Op0r+1).addImm(HiCst); BuildMI(*MBB, IP, PPC32::XORI, 2, HiLow).addReg(Op0r+1).addImm(HiCst);
BuildMI(*MBB, IP, PPC32::XORIS, 2, HiTmp).addReg(HiLow).addImm(HiCst >> 16); BuildMI(*MBB, IP, PPC32::XORIS, 2, HiTmp).addReg(HiLow)
.addImm(HiCst >> 16);
} }
unsigned FinalTmp = makeAnotherReg(Type::IntTy); unsigned FinalTmp = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::ORo, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp); BuildMI(*MBB, IP, PPC32::ORo, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp);
@ -845,7 +856,8 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
case cByte: case cByte:
case cShort: case cShort:
case cInt: case cInt:
BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMP : PPC32::CMPL, 2, PPC32::CR0).addReg(Op0r).addReg(Op1r); BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMP : PPC32::CMPL, 2,
PPC32::CR0).addReg(Op0r).addReg(Op1r);
break; break;
case cFP: case cFP:
emitUCOM(MBB, IP, Op0r, Op1r); emitUCOM(MBB, IP, Op0r, Op1r);
@ -887,7 +899,8 @@ void ISel::visitSetCondInst(SetCondInst &I) {
unsigned DestReg = getReg(I); unsigned DestReg = getReg(I);
MachineBasicBlock::iterator MII = BB->end(); MachineBasicBlock::iterator MII = BB->end();
emitSetCCOperation(BB, MII, I.getOperand(0), I.getOperand(1), I.getOpcode(),DestReg); emitSetCCOperation(BB, MII, I.getOperand(0), I.getOperand(1), I.getOpcode(),
DestReg);
} }
/// emitSetCCOperation - Common code shared between visitSetCondInst and /// emitSetCCOperation - Common code shared between visitSetCondInst and
@ -909,7 +922,8 @@ void ISel::emitSetCCOperation(MachineBasicBlock *MBB,
void ISel::visitSelectInst(SelectInst &SI) { void ISel::visitSelectInst(SelectInst &SI) {
unsigned DestReg = getReg(SI); unsigned DestReg = getReg(SI);
MachineBasicBlock::iterator MII = BB->end(); MachineBasicBlock::iterator MII = BB->end();
emitSelectOperation(BB, MII, SI.getCondition(), SI.getTrueValue(),SI.getFalseValue(), DestReg); emitSelectOperation(BB, MII, SI.getCondition(), SI.getTrueValue(),
SI.getFalseValue(), DestReg);
} }
/// emitSelect - Common code shared between visitSelectInst and the constant /// emitSelect - Common code shared between visitSelectInst and the constant
@ -933,7 +947,8 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB,
} }
if (SelectClass == cLong) if (SelectClass == cLong)
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(TrueReg+1).addReg(TrueReg+1); BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(TrueReg+1)
.addReg(TrueReg+1);
return; return;
} }
@ -946,7 +961,8 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB,
unsigned Temp2 = makeAnotherReg(Type::IntTy); unsigned Temp2 = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::CNTLZW, 1, numZeros).addReg(CondReg); BuildMI(*MBB, IP, PPC32::CNTLZW, 1, numZeros).addReg(CondReg);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, falseHi).addReg(numZeros).addImm(26).addImm(0).addImm(0); BuildMI(*MBB, IP, PPC32::RLWINM, 4, falseHi).addReg(numZeros).addImm(26)
.addImm(0).addImm(0);
BuildMI(*MBB, IP, PPC32::SRAWI, 2, falseAll).addReg(falseHi).addImm(31); BuildMI(*MBB, IP, PPC32::SRAWI, 2, falseAll).addReg(falseHi).addImm(31);
BuildMI(*MBB, IP, PPC32::NOR, 2, trueAll).addReg(falseAll).addReg(falseAll); BuildMI(*MBB, IP, PPC32::NOR, 2, trueAll).addReg(falseAll).addReg(falseAll);
BuildMI(*MBB, IP, PPC32::AND, 2, Temp1).addReg(TrueReg).addReg(trueAll); BuildMI(*MBB, IP, PPC32::AND, 2, Temp1).addReg(TrueReg).addReg(trueAll);
@ -980,7 +996,7 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
Ty = Type::IntTy; Ty = Type::IntTy;
} }
// If this is a simple constant, just emit a load directly to avoid the copy. // If this is a simple constant, just emit a load directly to avoid the copy
if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) { if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
int TheVal = CI->getRawValue() & 0xFFFFFFFF; int TheVal = CI->getRawValue() & 0xFFFFFFFF;
@ -988,8 +1004,10 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
BuildMI(BB, PPC32::ADDI, 2, targetReg).addReg(PPC32::R0).addImm(TheVal); BuildMI(BB, PPC32::ADDI, 2, targetReg).addReg(PPC32::R0).addImm(TheVal);
} else { } else {
unsigned TmpReg = makeAnotherReg(Type::IntTy); unsigned TmpReg = makeAnotherReg(Type::IntTy);
BuildMI(BB, PPC32::ADDIS, 2, TmpReg).addReg(PPC32::R0).addImm(TheVal >> 16); BuildMI(BB, PPC32::ADDIS, 2, TmpReg).addReg(PPC32::R0)
BuildMI(BB, PPC32::ORI, 2, targetReg).addReg(TmpReg).addImm(TheVal & 0xFFFF); .addImm(TheVal >> 16);
BuildMI(BB, PPC32::ORI, 2, targetReg).addReg(TmpReg)
.addImm(TheVal & 0xFFFF);
} }
return; return;
} }
@ -1002,14 +1020,16 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
case cByte: case cByte:
// Extend value into target register (8->32) // Extend value into target register (8->32)
if (isUnsigned) if (isUnsigned)
BuildMI(BB, PPC32::RLWINM, 4, targetReg).addReg(Reg).addZImm(0).addZImm(24).addZImm(31); BuildMI(BB, PPC32::RLWINM, 4, targetReg).addReg(Reg).addZImm(0)
.addZImm(24).addZImm(31);
else else
BuildMI(BB, PPC32::EXTSB, 1, targetReg).addReg(Reg); BuildMI(BB, PPC32::EXTSB, 1, targetReg).addReg(Reg);
break; break;
case cShort: case cShort:
// Extend value into target register (16->32) // Extend value into target register (16->32)
if (isUnsigned) if (isUnsigned)
BuildMI(BB, PPC32::RLWINM, 4, targetReg).addReg(Reg).addZImm(0).addZImm(16).addZImm(31); BuildMI(BB, PPC32::RLWINM, 4, targetReg).addReg(Reg).addZImm(0)
.addZImm(16).addZImm(31);
else else
BuildMI(BB, PPC32::EXTSH, 1, targetReg).addReg(Reg); BuildMI(BB, PPC32::EXTSH, 1, targetReg).addReg(Reg);
break; break;
@ -1022,7 +1042,8 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
} }
} }
// just emit blr. /// visitReturnInst - implemented with BLR
///
void ISel::visitReturnInst(ReturnInst &I) { void ISel::visitReturnInst(ReturnInst &I) {
Value *RetVal = I.getOperand(0); Value *RetVal = I.getOperand(0);
@ -1081,12 +1102,15 @@ void ISel::visitBranchInst(BranchInst &BI) {
// Nope, cannot fold setcc into this branch. Emit a branch on a condition // Nope, cannot fold setcc into this branch. Emit a branch on a condition
// computed some other way... // computed some other way...
unsigned condReg = getReg(BI.getCondition()); unsigned condReg = getReg(BI.getCondition());
BuildMI(BB, PPC32::CMPLI, 3, PPC32::CR0).addImm(0).addReg(condReg).addImm(0); BuildMI(BB, PPC32::CMPLI, 3, PPC32::CR0).addImm(0).addReg(condReg)
.addImm(0);
if (BI.getSuccessor(1) == NextBB) { if (BI.getSuccessor(1) == NextBB) {
if (BI.getSuccessor(0) != NextBB) if (BI.getSuccessor(0) != NextBB)
BuildMI(BB, PPC32::BC, 3).addImm(4).addImm(2).addMBB(MBBMap[BI.getSuccessor(0)]); BuildMI(BB, PPC32::BC, 3).addImm(4).addImm(2)
.addMBB(MBBMap[BI.getSuccessor(0)]);
} else { } else {
BuildMI(BB, PPC32::BC, 3).addImm(12).addImm(2).addMBB(MBBMap[BI.getSuccessor(1)]); BuildMI(BB, PPC32::BC, 3).addImm(12).addImm(2)
.addMBB(MBBMap[BI.getSuccessor(1)]);
if (BI.getSuccessor(0) != NextBB) if (BI.getSuccessor(0) != NextBB)
BuildMI(BB, PPC32::B, 1).addMBB(MBBMap[BI.getSuccessor(0)]); BuildMI(BB, PPC32::B, 1).addMBB(MBBMap[BI.getSuccessor(0)]);
@ -1117,13 +1141,15 @@ void ISel::visitBranchInst(BranchInst &BI) {
unsigned BIval = BITab[0]; unsigned BIval = BITab[0];
if (BI.getSuccessor(0) != NextBB) { if (BI.getSuccessor(0) != NextBB) {
BuildMI(BB, PPC32::BC, 3).addImm(BO_true).addImm(BIval).addMBB(MBBMap[BI.getSuccessor(0)]); BuildMI(BB, PPC32::BC, 3).addImm(BO_true).addImm(BIval)
.addMBB(MBBMap[BI.getSuccessor(0)]);
if (BI.getSuccessor(1) != NextBB) if (BI.getSuccessor(1) != NextBB)
BuildMI(BB, PPC32::B, 1).addMBB(MBBMap[BI.getSuccessor(1)]); BuildMI(BB, PPC32::B, 1).addMBB(MBBMap[BI.getSuccessor(1)]);
} else { } else {
// Change to the inverse condition... // Change to the inverse condition...
if (BI.getSuccessor(1) != NextBB) { if (BI.getSuccessor(1) != NextBB) {
BuildMI(BB, PPC32::BC, 3).addImm(BO_false).addImm(BIval).addMBB(MBBMap[BI.getSuccessor(1)]); BuildMI(BB, PPC32::BC, 3).addImm(BO_false).addImm(BIval)
.addMBB(MBBMap[BI.getSuccessor(1)]);
} }
} }
} }
@ -1174,9 +1200,11 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
// Reg or stack? // Reg or stack?
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg).addReg(ArgReg); BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg)
.addReg(ArgReg);
} else { } else {
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset)
.addReg(PPC32::R1);
} }
break; break;
case cInt: case cInt:
@ -1184,9 +1212,11 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
// Reg or stack? // Reg or stack?
if (GPR_remaining > 0) { if (GPR_remaining > 0) {
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg).addReg(ArgReg); BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg)
.addReg(ArgReg);
} else { } else {
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset)
.addReg(PPC32::R1);
} }
break; break;
case cLong: case cLong:
@ -1194,11 +1224,15 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
// Reg or stack? // Reg or stack?
if (GPR_remaining > 1) { if (GPR_remaining > 1) {
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg).addReg(ArgReg); BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx).addReg(ArgReg)
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx + 1).addReg(ArgReg+1).addReg(ArgReg+1); .addReg(ArgReg);
BuildMI(BB, PPC32::OR, 2, PPC32::R0 + GPR_idx + 1).addReg(ArgReg+1)
.addReg(ArgReg+1);
} else { } else {
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset)
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg+1).addImm(ArgOffset+4).addReg(PPC32::R1); .addReg(PPC32::R1);
BuildMI(BB, PPC32::STW, 3).addReg(ArgReg+1).addImm(ArgOffset+4)
.addReg(PPC32::R1);
} }
ArgOffset += 4; // 8 byte entry, not 4. ArgOffset += 4; // 8 byte entry, not 4.
@ -1216,7 +1250,8 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
FPR_remaining--; FPR_remaining--;
FPR_idx++; FPR_idx++;
} else { } else {
BuildMI(BB, PPC32::STFS, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STFS, 3).addReg(ArgReg).addImm(ArgOffset)
.addReg(PPC32::R1);
} }
} else { } else {
assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!"); assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!");
@ -1226,7 +1261,8 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
FPR_remaining--; FPR_remaining--;
FPR_idx++; FPR_idx++;
} else { } else {
BuildMI(BB, PPC32::STFD, 3).addReg(ArgReg).addImm(ArgOffset).addReg(PPC32::R1); BuildMI(BB, PPC32::STFD, 3).addReg(ArgReg).addImm(ArgOffset)
.addReg(PPC32::R1);
} }
ArgOffset += 4; // 8 byte entry, not 4. ArgOffset += 4; // 8 byte entry, not 4.
@ -1559,7 +1595,8 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
unsigned TmpReg = makeAnotherReg(Type::IntTy); unsigned TmpReg = makeAnotherReg(Type::IntTy);
emitUCOM(MBB, IP, Op0Reg, Op1Reg); emitUCOM(MBB, IP, Op0Reg, Op1Reg);
BuildMI(*MBB, IP, PPC32::MFCR, TmpReg); BuildMI(*MBB, IP, PPC32::MFCR, TmpReg);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(TmpReg).addImm(4).addImm(31).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(TmpReg).addImm(4)
.addImm(31).addImm(31);
return; return;
} }
} }
@ -1575,7 +1612,8 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
unsigned overflow = makeAnotherReg(Type::IntTy); unsigned overflow = makeAnotherReg(Type::IntTy);
unsigned T = makeAnotherReg(Type::IntTy); unsigned T = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::CNTLZW, 1, zeroes).addReg(op1Reg); BuildMI(*MBB, IP, PPC32::CNTLZW, 1, zeroes).addReg(op1Reg);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, overflow).addReg(zeroes).addImm(27).addImm(5).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, overflow).addReg(zeroes).addImm(27)
.addImm(5).addImm(31);
BuildMI(*MBB, IP, PPC32::ADD, 2, T).addReg(op1Reg+1).addReg(overflow); BuildMI(*MBB, IP, PPC32::ADD, 2, T).addReg(op1Reg+1).addReg(overflow);
BuildMI(*MBB, IP, PPC32::NEG, 1, DestReg+1).addReg(T); BuildMI(*MBB, IP, PPC32::NEG, 1, DestReg+1).addReg(T);
} }
@ -1590,7 +1628,8 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
if (OperatorClass == 4 && Op1C->isAllOnesValue()) { if (OperatorClass == 4 && Op1C->isAllOnesValue()) {
BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg).addReg(Op0r).addReg(Op0r); BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg).addReg(Op0r).addReg(Op0r);
if (Class == cLong) // Invert the top part too if (Class == cLong) // Invert the top part too
BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg+1).addReg(Op0r+1).addReg(Op0r+1); BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg+1).addReg(Op0r+1)
.addReg(Op0r+1);
return; return;
} }
@ -1632,8 +1671,10 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
// TODO: We could handle lots of other special cases here, such as AND'ing // TODO: We could handle lots of other special cases here, such as AND'ing
// with 0xFFFFFFFF00000000 -> noop, etc. // with 0xFFFFFFFF00000000 -> noop, etc.
BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r).addImm(Op1r); BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r)
BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1).addImm(Op1r+1); .addImm(Op1r);
BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
.addImm(Op1r+1);
return; return;
} }
@ -1644,8 +1685,10 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
unsigned Opcode = OpcodeTab[OperatorClass]; unsigned Opcode = OpcodeTab[OperatorClass];
BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r); BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r);
} else { } else {
BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r).addImm(Op1r); BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r)
BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1).addImm(Op1r+1); .addImm(Op1r);
BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
.addImm(Op1r+1);
} }
return; return;
} }
@ -1660,7 +1703,8 @@ void ISel::doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI,
unsigned Class = getClass(DestTy); unsigned Class = getClass(DestTy);
switch (Class) { switch (Class) {
case cLong: case cLong:
BuildMI(*MBB, MBBI, PPC32::MULHW, 2, DestReg+1).addReg(op0Reg+1).addReg(op1Reg+1); BuildMI(*MBB, MBBI, PPC32::MULHW, 2, DestReg+1).addReg(op0Reg+1)
.addReg(op1Reg+1);
case cInt: case cInt:
case cShort: case cShort:
case cByte: case cByte:
@ -1686,6 +1730,7 @@ static unsigned ExactLog2(unsigned Val) {
/// doMultiplyConst - This function is specialized to efficiently codegen an 8, /// doMultiplyConst - This function is specialized to efficiently codegen an 8,
/// 16, or 32-bit integer multiply by a constant. /// 16, or 32-bit integer multiply by a constant.
///
void ISel::doMultiplyConst(MachineBasicBlock *MBB, void ISel::doMultiplyConst(MachineBasicBlock *MBB,
MachineBasicBlock::iterator IP, MachineBasicBlock::iterator IP,
unsigned DestReg, const Type *DestTy, unsigned DestReg, const Type *DestTy,
@ -1711,7 +1756,8 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB,
case cByte: case cByte:
case cShort: case cShort:
case cInt: case cInt:
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(op0Reg).addImm(Shift-1).addImm(0).addImm(31-Shift-1); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(op0Reg)
.addImm(Shift-1).addImm(0).addImm(31-Shift-1);
return; return;
} }
} }
@ -1719,7 +1765,8 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB,
// Most general case, emit a normal multiply... // Most general case, emit a normal multiply...
unsigned TmpReg1 = makeAnotherReg(Type::IntTy); unsigned TmpReg1 = makeAnotherReg(Type::IntTy);
unsigned TmpReg2 = makeAnotherReg(Type::IntTy); unsigned TmpReg2 = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::ADDIS, 2, TmpReg1).addReg(PPC32::R0).addImm(ConstRHS >> 16); BuildMI(*MBB, IP, PPC32::ADDIS, 2, TmpReg1).addReg(PPC32::R0)
.addImm(ConstRHS >> 16);
BuildMI(*MBB, IP, PPC32::ORI, 2, TmpReg2).addReg(TmpReg1).addImm(ConstRHS); BuildMI(*MBB, IP, PPC32::ORI, 2, TmpReg2).addReg(TmpReg1).addImm(ConstRHS);
// Emit a MUL to multiply the register holding the index by // Emit a MUL to multiply the register holding the index by
@ -1783,10 +1830,12 @@ void ISel::emitMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
unsigned TmpRegL = makeAnotherReg(Type::UIntTy); unsigned TmpRegL = makeAnotherReg(Type::UIntTy);
unsigned Op1RegL = makeAnotherReg(Type::UIntTy); unsigned Op1RegL = makeAnotherReg(Type::UIntTy);
OverflowReg = makeAnotherReg(Type::UIntTy); OverflowReg = makeAnotherReg(Type::UIntTy);
BuildMI(BB, IP, PPC32::ADDIS, 2, TmpRegL).addReg(PPC32::R0).addImm(CLow >> 16); BuildMI(BB, IP, PPC32::ADDIS, 2, TmpRegL).addReg(PPC32::R0)
.addImm(CLow >> 16);
BuildMI(BB, IP, PPC32::ORI, 2, Op1RegL).addReg(TmpRegL).addImm(CLow); BuildMI(BB, IP, PPC32::ORI, 2, Op1RegL).addReg(TmpRegL).addImm(CLow);
BuildMI(BB, IP, PPC32::MULLW, 2, DestReg).addReg(Op0Reg).addReg(Op1RegL); BuildMI(BB, IP, PPC32::MULLW, 2, DestReg).addReg(Op0Reg).addReg(Op1RegL);
BuildMI(BB, IP, PPC32::MULHW, 2, OverflowReg).addReg(Op0Reg).addReg(Op1RegL); BuildMI(BB, IP, PPC32::MULHW, 2, OverflowReg).addReg(Op0Reg)
.addReg(Op1RegL);
} }
unsigned AHBLReg = makeAnotherReg(Type::UIntTy); unsigned AHBLReg = makeAnotherReg(Type::UIntTy);
@ -1802,7 +1851,8 @@ void ISel::emitMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
} }
if (CHi == 0) { if (CHi == 0) {
BuildMI(BB, IP, PPC32::OR, 2, DestReg+1).addReg(AHBLplusOverflowReg).addReg(AHBLplusOverflowReg); BuildMI(BB, IP, PPC32::OR, 2, DestReg+1).addReg(AHBLplusOverflowReg)
.addReg(AHBLplusOverflowReg);
} else { } else {
unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH
doMultiplyConst(&BB, IP, ALBHReg, Type::UIntTy, Op0Reg, CHi); doMultiplyConst(&BB, IP, ALBHReg, Type::UIntTy, Op0Reg, CHi);
@ -1848,7 +1898,8 @@ void ISel::visitDivRem(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
MachineBasicBlock::iterator IP = BB->end(); MachineBasicBlock::iterator IP = BB->end();
emitDivRemOperation(BB, IP, Op0, Op1, I.getOpcode() == Instruction::Div, ResultReg); emitDivRemOperation(BB, IP, Op0, Op1, I.getOpcode() == Instruction::Div,
ResultReg);
} }
void ISel::emitDivRemOperation(MachineBasicBlock *BB, void ISel::emitDivRemOperation(MachineBasicBlock *BB,
@ -1926,7 +1977,8 @@ void ISel::emitDivRemOperation(MachineBasicBlock *BB,
BuildMI(*BB, IP, PPC32::OR, 2, TmpReg).addReg(Op0Reg).addReg(Op0Reg); BuildMI(*BB, IP, PPC32::OR, 2, TmpReg).addReg(Op0Reg).addReg(Op0Reg);
unsigned TmpReg2 = makeAnotherReg(Op0->getType()); unsigned TmpReg2 = makeAnotherReg(Op0->getType());
BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg2).addReg(TmpReg).addImm(Log).addImm(32-Log).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg2).addReg(TmpReg).addImm(Log)
.addImm(32-Log).addImm(31);
unsigned TmpReg3 = makeAnotherReg(Op0->getType()); unsigned TmpReg3 = makeAnotherReg(Op0->getType());
BuildMI(*BB, IP, PPC32::ADD, 2, TmpReg3).addReg(Op0Reg).addReg(TmpReg2); BuildMI(*BB, IP, PPC32::ADD, 2, TmpReg3).addReg(Op0Reg).addReg(TmpReg2);
@ -1978,6 +2030,7 @@ void ISel::visitShiftInst(ShiftInst &I) {
/// emitShiftOperation - Common code shared between visitShiftInst and /// emitShiftOperation - Common code shared between visitShiftInst and
/// constant expression support. /// constant expression support.
///
void ISel::emitShiftOperation(MachineBasicBlock *MBB, void ISel::emitShiftOperation(MachineBasicBlock *MBB,
MachineBasicBlock::iterator IP, MachineBasicBlock::iterator IP,
Value *Op, Value *ShiftAmount, bool isLeftShift, Value *Op, Value *ShiftAmount, bool isLeftShift,
@ -1996,32 +2049,43 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
if (Amount < 32) { if (Amount < 32) {
if (isLeftShift) { if (isLeftShift) {
// FIXME: RLWIMI is a use-and-def of DestReg+1, but that violates SSA // FIXME: RLWIMI is a use-and-def of DestReg+1, but that violates SSA
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg+1).addImm(Amount).addImm(0).addImm(31-Amount); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg+1)
BuildMI(*MBB, IP, PPC32::RLWIMI, 5).addReg(DestReg+1).addReg(SrcReg).addImm(Amount).addImm(32-Amount).addImm(31); .addImm(Amount).addImm(0).addImm(31-Amount);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addImm(Amount).addImm(0).addImm(31-Amount); BuildMI(*MBB, IP, PPC32::RLWIMI, 5).addReg(DestReg+1).addReg(SrcReg)
.addImm(Amount).addImm(32-Amount).addImm(31);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg)
.addImm(Amount).addImm(0).addImm(31-Amount);
} else { } else {
// FIXME: RLWIMI is a use-and-def of DestReg, but that violates SSA // FIXME: RLWIMI is a use-and-def of DestReg, but that violates SSA
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addImm(32-Amount).addImm(Amount).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg)
BuildMI(*MBB, IP, PPC32::RLWIMI, 5).addReg(DestReg).addReg(SrcReg+1).addImm(32-Amount).addImm(0).addImm(Amount-1); .addImm(32-Amount).addImm(Amount).addImm(31);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg+1).addImm(32-Amount).addImm(Amount).addImm(31); BuildMI(*MBB, IP, PPC32::RLWIMI, 5).addReg(DestReg).addReg(SrcReg+1)
.addImm(32-Amount).addImm(0).addImm(Amount-1);
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg+1)
.addImm(32-Amount).addImm(Amount).addImm(31);
} }
} else { // Shifting more than 32 bits } else { // Shifting more than 32 bits
Amount -= 32; Amount -= 32;
if (isLeftShift) { if (isLeftShift) {
if (Amount != 0) { if (Amount != 0) {
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg).addImm(Amount).addImm(0).addImm(31-Amount); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg+1).addReg(SrcReg)
.addImm(Amount).addImm(0).addImm(31-Amount);
} else { } else {
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(SrcReg).addReg(SrcReg); BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(SrcReg)
.addReg(SrcReg);
} }
BuildMI(*MBB, IP, PPC32::ADDI, 2,DestReg).addReg(PPC32::R0).addImm(0); BuildMI(*MBB, IP, PPC32::ADDI, 2,DestReg).addReg(PPC32::R0).addImm(0);
} else { } else {
if (Amount != 0) { if (Amount != 0) {
if (isSigned) if (isSigned)
BuildMI(*MBB, IP, PPC32::SRAWI, 2, DestReg).addReg(SrcReg+1).addImm(Amount); BuildMI(*MBB, IP, PPC32::SRAWI, 2, DestReg).addReg(SrcReg+1)
.addImm(Amount);
else else
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg+1).addImm(32-Amount).addImm(Amount).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg+1)
.addImm(32-Amount).addImm(Amount).addImm(31);
} else { } else {
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg+1).addReg(SrcReg+1); BuildMI(*MBB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg+1)
.addReg(SrcReg+1);
} }
BuildMI(*MBB, IP,PPC32::ADDI,2,DestReg+1).addReg(PPC32::R0).addImm(0); BuildMI(*MBB, IP,PPC32::ADDI,2,DestReg+1).addReg(PPC32::R0).addImm(0);
} }
@ -2036,27 +2100,40 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
unsigned ShiftAmountReg = getReg (ShiftAmount, MBB, IP); unsigned ShiftAmountReg = getReg (ShiftAmount, MBB, IP);
if (isLeftShift) { if (isLeftShift) {
BuildMI(*MBB, IP, PPC32::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg).addImm(32); BuildMI(*MBB, IP, PPC32::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg)
BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg2).addReg(SrcReg+1).addReg(ShiftAmountReg); .addImm(32);
BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg2).addReg(SrcReg+1)
.addReg(ShiftAmountReg);
BuildMI(*MBB, IP, PPC32::SRW, 2,TmpReg3).addReg(SrcReg).addReg(TmpReg1); BuildMI(*MBB, IP, PPC32::SRW, 2,TmpReg3).addReg(SrcReg).addReg(TmpReg1);
BuildMI(*MBB, IP, PPC32::OR, 2,TmpReg4).addReg(TmpReg2).addReg(TmpReg3); BuildMI(*MBB, IP, PPC32::OR, 2,TmpReg4).addReg(TmpReg2).addReg(TmpReg3);
BuildMI(*MBB, IP, PPC32::ADDI, 2, TmpReg5).addReg(ShiftAmountReg).addImm(-32); BuildMI(*MBB, IP, PPC32::ADDI, 2, TmpReg5).addReg(ShiftAmountReg)
.addImm(-32);
BuildMI(*MBB, IP, PPC32::SLW, 2,TmpReg6).addReg(SrcReg).addReg(TmpReg5); BuildMI(*MBB, IP, PPC32::SLW, 2,TmpReg6).addReg(SrcReg).addReg(TmpReg5);
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(TmpReg4).addReg(TmpReg6); BuildMI(*MBB, IP, PPC32::OR, 2, DestReg+1).addReg(TmpReg4)
BuildMI(*MBB, IP, PPC32::SLW, 2, DestReg).addReg(SrcReg).addReg(ShiftAmountReg); .addReg(TmpReg6);
BuildMI(*MBB, IP, PPC32::SLW, 2, DestReg).addReg(SrcReg)
.addReg(ShiftAmountReg);
} else { } else {
if (isSigned) { if (isSigned) {
// FIXME: Unimplmented // FIXME: Unimplmented
// Page C-3 of the PowerPC 32bit Programming Environments Manual // Page C-3 of the PowerPC 32bit Programming Environments Manual
} else { } else {
BuildMI(*MBB, IP, PPC32::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg).addImm(32); BuildMI(*MBB, IP, PPC32::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg)
BuildMI(*MBB, IP, PPC32::SRW, 2, TmpReg2).addReg(SrcReg).addReg(ShiftAmountReg); .addImm(32);
BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg3).addReg(SrcReg+1).addReg(TmpReg1); BuildMI(*MBB, IP, PPC32::SRW, 2, TmpReg2).addReg(SrcReg)
BuildMI(*MBB, IP, PPC32::OR, 2, TmpReg4).addReg(TmpReg2).addReg(TmpReg3); .addReg(ShiftAmountReg);
BuildMI(*MBB, IP, PPC32::ADDI, 2, TmpReg5).addReg(ShiftAmountReg).addImm(-32); BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg3).addReg(SrcReg+1)
BuildMI(*MBB, IP, PPC32::SRW, 2, TmpReg6).addReg(SrcReg+1).addReg(TmpReg5); .addReg(TmpReg1);
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg).addReg(TmpReg4).addReg(TmpReg6); BuildMI(*MBB, IP, PPC32::OR, 2, TmpReg4).addReg(TmpReg2)
BuildMI(*MBB, IP, PPC32::SRW, 2, DestReg+1).addReg(SrcReg+1).addReg(ShiftAmountReg); .addReg(TmpReg3);
BuildMI(*MBB, IP, PPC32::ADDI, 2, TmpReg5).addReg(ShiftAmountReg)
.addImm(-32);
BuildMI(*MBB, IP, PPC32::SRW, 2, TmpReg6).addReg(SrcReg+1)
.addReg(TmpReg5);
BuildMI(*MBB, IP, PPC32::OR, 2, DestReg).addReg(TmpReg4)
.addReg(TmpReg6);
BuildMI(*MBB, IP, PPC32::SRW, 2, DestReg+1).addReg(SrcReg+1)
.addReg(ShiftAmountReg);
} }
} }
} }
@ -2069,21 +2146,25 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
unsigned Amount = CUI->getValue(); unsigned Amount = CUI->getValue();
if (isLeftShift) { if (isLeftShift) {
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addImm(Amount).addImm(0).addImm(31-Amount); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg)
.addImm(Amount).addImm(0).addImm(31-Amount);
} else { } else {
if (isSigned) { if (isSigned) {
BuildMI(*MBB, IP, PPC32::SRAWI,2,DestReg).addReg(SrcReg).addImm(Amount); BuildMI(*MBB, IP, PPC32::SRAWI,2,DestReg).addReg(SrcReg).addImm(Amount);
} else { } else {
BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addImm(32-Amount).addImm(Amount).addImm(31); BuildMI(*MBB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg)
.addImm(32-Amount).addImm(Amount).addImm(31);
} }
} }
} else { // The shift amount is non-constant. } else { // The shift amount is non-constant.
unsigned ShiftAmountReg = getReg (ShiftAmount, MBB, IP); unsigned ShiftAmountReg = getReg (ShiftAmount, MBB, IP);
if (isLeftShift) { if (isLeftShift) {
BuildMI(*MBB, IP, PPC32::SLW, 2, DestReg).addReg(SrcReg).addReg(ShiftAmountReg); BuildMI(*MBB, IP, PPC32::SLW, 2, DestReg).addReg(SrcReg)
.addReg(ShiftAmountReg);
} else { } else {
BuildMI(*MBB, IP, isSigned ? PPC32::SRAW : PPC32::SRW, 2, DestReg).addReg(SrcReg).addReg(ShiftAmountReg); BuildMI(*MBB, IP, isSigned ? PPC32::SRAW : PPC32::SRW, 2, DestReg)
.addReg(SrcReg).addReg(ShiftAmountReg);
} }
} }
} }
@ -2092,7 +2173,9 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
/// visitLoadInst - Implement LLVM load instructions /// visitLoadInst - Implement LLVM load instructions
/// ///
void ISel::visitLoadInst(LoadInst &I) { void ISel::visitLoadInst(LoadInst &I) {
static const unsigned Opcodes[] = { PPC32::LBZ, PPC32::LHZ, PPC32::LWZ, PPC32::LFS }; static const unsigned Opcodes[] = {
PPC32::LBZ, PPC32::LHZ, PPC32::LWZ, PPC32::LFS
};
unsigned Class = getClassB(I.getType()); unsigned Class = getClassB(I.getType());
unsigned Opcode = Opcodes[Class]; unsigned Opcode = Opcodes[Class];
if (I.getType() == Type::DoubleTy) Opcode = PPC32::LFD; if (I.getType() == Type::DoubleTy) Opcode = PPC32::LFD;
@ -2242,7 +2325,8 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
} }
} else if (SrcClass == cLong) { } else if (SrcClass == cLong) {
BuildMI(*BB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
BuildMI(*BB, IP, PPC32::OR, 2, DestReg+1).addReg(SrcReg+1).addReg(SrcReg+1); BuildMI(*BB, IP, PPC32::OR, 2, DestReg+1).addReg(SrcReg+1)
.addReg(SrcReg+1);
} else { } else {
assert(0 && "Cannot handle this type of cast instruction!"); assert(0 && "Cannot handle this type of cast instruction!");
abort(); abort();
@ -2261,9 +2345,11 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
if (SrcClass < cInt) { if (SrcClass < cInt) {
if (isUnsigned) { if (isUnsigned) {
unsigned shift = (SrcClass == cByte) ? 24 : 16; unsigned shift = (SrcClass == cByte) ? 24 : 16;
BuildMI(*BB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addZImm(0).addImm(shift).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addZImm(0)
.addImm(shift).addImm(31);
} else { } else {
BuildMI(*BB, IP, (SrcClass == cByte) ? PPC32::EXTSB : PPC32::EXTSH, 1, DestReg).addReg(SrcReg); BuildMI(*BB, IP, (SrcClass == cByte) ? PPC32::EXTSB : PPC32::EXTSH,
1, DestReg).addReg(SrcReg);
} }
} else { } else {
BuildMI(*BB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
@ -2290,9 +2376,11 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
bool isUnsigned = SrcTy->isUnsigned() || SrcTy == Type::BoolTy; bool isUnsigned = SrcTy->isUnsigned() || SrcTy == Type::BoolTy;
if (isUnsigned) { if (isUnsigned) {
unsigned shift = (SrcClass == cByte) ? 24 : 16; unsigned shift = (SrcClass == cByte) ? 24 : 16;
BuildMI(*BB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addZImm(0).addImm(shift).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, DestReg).addReg(SrcReg).addZImm(0)
.addImm(shift).addImm(31);
} else { } else {
BuildMI(*BB, IP, (SrcClass == cByte) ? PPC32::EXTSB : PPC32::EXTSH, 1, DestReg).addReg(SrcReg); BuildMI(*BB, IP, (SrcClass == cByte) ? PPC32::EXTSB : PPC32::EXTSH, 1,
DestReg).addReg(SrcReg);
} }
return; return;
} }
@ -2304,7 +2392,8 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
if (SrcClass == cLong) { if (SrcClass == cLong) {
std::vector<ValueRecord> Args; std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(SrcReg, SrcTy)); Args.push_back(ValueRecord(SrcReg, SrcTy));
MachineInstr *TheCall = BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("__floatdidf", true); MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("__floatdidf", true);
doCall(ValueRecord(DestReg, DestTy), TheCall, Args); doCall(ValueRecord(DestReg, DestTy), TheCall, Args);
return; return;
} }
@ -2316,13 +2405,15 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
BuildMI(*BB, IP, PPC32::EXTSB, 1, TmpReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::EXTSB, 1, TmpReg).addReg(SrcReg);
break; break;
case Type::UByteTyID: case Type::UByteTyID:
BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg).addReg(SrcReg).addZImm(0).addImm(24).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg).addReg(SrcReg).addZImm(0)
.addImm(24).addImm(31);
break; break;
case Type::ShortTyID: case Type::ShortTyID:
BuildMI(*BB, IP, PPC32::EXTSB, 1, TmpReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::EXTSB, 1, TmpReg).addReg(SrcReg);
break; break;
case Type::UShortTyID: case Type::UShortTyID:
BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg).addReg(SrcReg).addZImm(0).addImm(16).addImm(31); BuildMI(*BB, IP, PPC32::RLWINM, 4, TmpReg).addReg(SrcReg).addZImm(0)
.addImm(16).addImm(31);
break; break;
case Type::IntTyID: case Type::IntTyID:
BuildMI(*BB, IP, PPC32::OR, 2, TmpReg).addReg(SrcReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::OR, 2, TmpReg).addReg(SrcReg).addReg(SrcReg);
@ -2349,25 +2440,38 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
unsigned TempF = makeAnotherReg(Type::DoubleTy); unsigned TempF = makeAnotherReg(Type::DoubleTy);
if (!SrcTy->isSigned()) { if (!SrcTy->isSigned()) {
BuildMI(*BB, IP, PPC32::ADDIS, 2, constantHi).addReg(PPC32::R0).addImm(0x4330); BuildMI(*BB, IP, PPC32::ADDIS, 2, constantHi).addReg(PPC32::R0)
.addImm(0x4330);
BuildMI(*BB, IP, PPC32::ADDI, 2, constantLo).addReg(PPC32::R0).addImm(0); BuildMI(*BB, IP, PPC32::ADDI, 2, constantLo).addReg(PPC32::R0).addImm(0);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi), ConstantFrameIndex); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi),
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantLo), ConstantFrameIndex, 4); ConstantFrameIndex);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantLo),
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(SrcReg), ValueFrameIdx, 4); ConstantFrameIndex, 4);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, ConstF), ConstantFrameIndex); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi),
ValueFrameIdx);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(SrcReg),
ValueFrameIdx, 4);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, ConstF),
ConstantFrameIndex);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, TempF), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, TempF), ValueFrameIdx);
BuildMI(*BB, IP, PPC32::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF); BuildMI(*BB, IP, PPC32::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF);
} else { } else {
unsigned TempLo = makeAnotherReg(Type::IntTy); unsigned TempLo = makeAnotherReg(Type::IntTy);
BuildMI(*BB, IP, PPC32::ADDIS, 2, constantHi).addReg(PPC32::R0).addImm(0x4330); BuildMI(*BB, IP, PPC32::ADDIS, 2, constantHi).addReg(PPC32::R0)
BuildMI(*BB, IP, PPC32::ADDIS, 2, constantLo).addReg(PPC32::R0).addImm(0x8000); .addImm(0x4330);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi), ConstantFrameIndex); BuildMI(*BB, IP, PPC32::ADDIS, 2, constantLo).addReg(PPC32::R0)
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantLo), ConstantFrameIndex, 4); .addImm(0x8000);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi),
ConstantFrameIndex);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantLo),
ConstantFrameIndex, 4);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(constantHi),
ValueFrameIdx);
BuildMI(*BB, IP, PPC32::XORIS, 2, TempLo).addReg(SrcReg).addImm(0x8000); BuildMI(*BB, IP, PPC32::XORIS, 2, TempLo).addReg(SrcReg).addImm(0x8000);
addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(TempLo), ValueFrameIdx, 4); addFrameReference(BuildMI(*BB, IP, PPC32::STW, 3).addReg(TempLo),
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, ConstF), ConstantFrameIndex); ValueFrameIdx, 4);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, ConstF),
ConstantFrameIndex);
addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, TempF), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::LFD, 2, TempF), ValueFrameIdx);
BuildMI(*BB, IP, PPC32::FSUB, 2, DestReg).addReg(TempF ).addReg(ConstF); BuildMI(*BB, IP, PPC32::FSUB, 2, DestReg).addReg(TempF ).addReg(ConstF);
} }
@ -2381,7 +2485,8 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
if (DestClass == cLong) { if (DestClass == cLong) {
std::vector<ValueRecord> Args; std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(SrcReg, SrcTy)); Args.push_back(ValueRecord(SrcReg, SrcTy));
MachineInstr *TheCall = BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("__fixdfdi", true); MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("__fixdfdi", true);
doCall(ValueRecord(DestReg, DestTy), TheCall, Args); doCall(ValueRecord(DestReg, DestTy), TheCall, Args);
return; return;
} }
@ -2394,8 +2499,10 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
//if (DestTy->isSigned()) { //if (DestTy->isSigned()) {
unsigned TempReg = makeAnotherReg(Type::DoubleTy); unsigned TempReg = makeAnotherReg(Type::DoubleTy);
BuildMI(*BB, IP, PPC32::FCTIWZ, 1, TempReg).addReg(SrcReg); BuildMI(*BB, IP, PPC32::FCTIWZ, 1, TempReg).addReg(SrcReg);
addFrameReference(BuildMI(*BB, IP, PPC32::STFD, 3).addReg(TempReg), ValueFrameIdx); addFrameReference(BuildMI(*BB, IP, PPC32::STFD, 3)
addFrameReference(BuildMI(*BB, IP, PPC32::LWZ, 2, DestReg), ValueFrameIdx+4); .addReg(TempReg), ValueFrameIdx);
addFrameReference(BuildMI(*BB, IP, PPC32::LWZ, 2, DestReg),
ValueFrameIdx+4);
//} else { //} else {
//} //}
@ -2465,7 +2572,8 @@ void ISel::visitVAArgInst(VAArgInst &I) {
/// ///
void ISel::visitGetElementPtrInst(GetElementPtrInst &I) { void ISel::visitGetElementPtrInst(GetElementPtrInst &I) {
unsigned outputReg = getReg(I); unsigned outputReg = getReg(I);
emitGEPOperation(BB, BB->end(), I.getOperand(0),I.op_begin()+1, I.op_end(), outputReg); emitGEPOperation(BB, BB->end(), I.getOperand(0), I.op_begin()+1, I.op_end(),
outputReg);
} }
void ISel::emitGEPOperation(MachineBasicBlock *MBB, void ISel::emitGEPOperation(MachineBasicBlock *MBB,
@ -2569,7 +2677,8 @@ void ISel::visitAllocaInst(AllocaInst &I) {
// AlignedSize = and <AddedSize>, ~15 // AlignedSize = and <AddedSize>, ~15
unsigned AlignedSize = makeAnotherReg(Type::UIntTy); unsigned AlignedSize = makeAnotherReg(Type::UIntTy);
BuildMI(BB, PPC32::RLWNM, 4, AlignedSize).addReg(AddedSizeReg).addImm(0).addImm(0).addImm(27); BuildMI(BB, PPC32::RLWNM, 4, AlignedSize).addReg(AddedSizeReg).addImm(0)
.addImm(0).addImm(27);
// Subtract size from stack pointer, thereby allocating some space. // Subtract size from stack pointer, thereby allocating some space.
BuildMI(BB, PPC32::SUB, 2, PPC32::R1).addReg(PPC32::R1).addReg(AlignedSize); BuildMI(BB, PPC32::SUB, 2, PPC32::R1).addReg(PPC32::R1).addReg(AlignedSize);
@ -2601,7 +2710,8 @@ void ISel::visitMallocInst(MallocInst &I) {
std::vector<ValueRecord> Args; std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(Arg, Type::UIntTy)); Args.push_back(ValueRecord(Arg, Type::UIntTy));
MachineInstr *TheCall = BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("malloc", true); MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("malloc", true);
doCall(ValueRecord(getReg(I), I.getType()), TheCall, Args); doCall(ValueRecord(getReg(I), I.getType()), TheCall, Args);
} }
@ -2612,7 +2722,8 @@ void ISel::visitMallocInst(MallocInst &I) {
void ISel::visitFreeInst(FreeInst &I) { void ISel::visitFreeInst(FreeInst &I) {
std::vector<ValueRecord> Args; std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(I.getOperand(0))); Args.push_back(ValueRecord(I.getOperand(0)));
MachineInstr *TheCall = BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("free", true); MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("free", true);
doCall(ValueRecord(0, Type::VoidTy), TheCall, Args); doCall(ValueRecord(0, Type::VoidTy), TheCall, Args);
} }