aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PowerPCISelSimple.cpp
diff options
context:
space:
mode:
authorMisha Brukman <brukman+llvm@gmail.com>2004-07-21 20:09:08 +0000
committerMisha Brukman <brukman+llvm@gmail.com>2004-07-21 20:09:08 +0000
commit1013ef52285949d851b5c8782e08c5152f9990a9 (patch)
tree3453e8a246c0bdf93e0293d09688ad5455117a68 /lib/Target/PowerPC/PowerPCISelSimple.cpp
parent5eb919405cb98764bf53ab53cc17dfc117c21c41 (diff)
* Fix printing of signed immediate values
* Generation of opcodes that take 16 bit immediates * Rewrote multiply to be correct for 64 bit values * Rewrote all the long handling to be correct for PowerPC * Fix visitSelectInst() to define the upper register of the pair of regs representing a long value Patch contributed by Nate Begeman. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15083 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PowerPCISelSimple.cpp')
-rw-r--r--lib/Target/PowerPC/PowerPCISelSimple.cpp930
1 files changed, 427 insertions, 503 deletions
diff --git a/lib/Target/PowerPC/PowerPCISelSimple.cpp b/lib/Target/PowerPC/PowerPCISelSimple.cpp
index 8c212dcf14..339cbda481 100644
--- a/lib/Target/PowerPC/PowerPCISelSimple.cpp
+++ b/lib/Target/PowerPC/PowerPCISelSimple.cpp
@@ -286,13 +286,15 @@ namespace {
void emitMultiply(MachineBasicBlock *BB, MachineBasicBlock::iterator IP,
Value *Op0, Value *Op1, unsigned TargetReg);
- void doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI,
- unsigned DestReg, const Type *DestTy,
- unsigned Op0Reg, unsigned Op1Reg);
+ void doMultiply(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator IP,
+ unsigned DestReg, Value *Op0, Value *Op1);
+
+ /// doMultiplyConst - This method will multiply the value in Op0Reg by the
+ /// value of the ContantInt *CI
void doMultiplyConst(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator MBBI,
- unsigned DestReg, const Type *DestTy,
- unsigned Op0Reg, unsigned Op1Val);
+ MachineBasicBlock::iterator IP,
+ unsigned DestReg, Value *Op0, ConstantInt *CI);
void emitDivRemOperation(MachineBasicBlock *BB,
MachineBasicBlock::iterator IP,
@@ -337,8 +339,7 @@ namespace {
///
/// Long values are handled somewhat specially. They are always allocated
/// as pairs of 32 bit integer values. The register number returned is the
- /// lower 32 bits of the long value, and the regNum+1 is the upper 32 bits
- /// of the long value.
+ /// high 32 bits of the long value, and the regNum+1 is the low 32 bits.
///
unsigned makeAnotherReg(const Type *Ty) {
assert(dynamic_cast<const PowerPCRegisterInfo*>(TM.getRegisterInfo()) &&
@@ -368,6 +369,10 @@ namespace {
}
unsigned getReg(Value *V, MachineBasicBlock *MBB,
MachineBasicBlock::iterator IPt);
+
+ /// canUseAsImmediateForOpcode - This method returns whether a ConstantInt
+ /// is okay to use as an immediate argument to a certain binary operation
+ bool canUseAsImmediateForOpcode(ConstantInt *CI, unsigned Opcode);
/// getFixedSizedAllocaFI - Return the frame index for a fixed sized alloca
/// that is to be statically allocated with the initial stack frame
@@ -416,6 +421,48 @@ unsigned ISel::getReg(Value *V, MachineBasicBlock *MBB,
return Reg;
}
+/// canUseAsImmediateForOpcode - This method returns whether a ConstantInt
+/// is okay to use as an immediate argument to a certain binary operator.
+///
+/// Operator is one of: 0 for Add, 1 for Sub, 2 for And, 3 for Or, 4 for Xor.
+bool ISel::canUseAsImmediateForOpcode(ConstantInt *CI, unsigned Operator)
+{
+ ConstantSInt *Op1Cs;
+ ConstantUInt *Op1Cu;
+
+ // ADDI, Compare, and non-indexed Load take SIMM
+ bool cond1 = (Op1Cs = dyn_cast<ConstantSInt>(CI))
+ && (Op1Cs->getValue() <= 32767)
+ && (Op1Cs->getValue() >= -32768)
+ && (Operator == 0);
+
+ // SUBI takes -SIMM since it is a mnemonic for ADDI
+ bool cond2 = (Op1Cs = dyn_cast<ConstantSInt>(CI))
+ && (Op1Cs->getValue() <= 32768)
+ && (Op1Cs->getValue() >= -32767)
+ && (Operator == 1);
+
+ // ANDIo, ORI, and XORI take unsigned values
+ bool cond3 = (Op1Cs = dyn_cast<ConstantSInt>(CI))
+ && (Op1Cs->getValue() <= 32767)
+ && (Operator >= 2);
+
+ // ADDI and SUBI take SIMMs, so we have to make sure the UInt would fit
+ bool cond4 = (Op1Cu = dyn_cast<ConstantUInt>(CI))
+ && (Op1Cu->getValue() <= 32767)
+ && (Operator < 2);
+
+ // ANDIo, ORI, and XORI take UIMMs, so they can be larger
+ bool cond5 = (Op1Cu = dyn_cast<ConstantUInt>(CI))
+ && (Op1Cu->getValue() <= 65535)
+ && (Operator >= 2);
+
+ if (cond1 || cond2 || cond3 || cond4 || cond5)
+ return true;
+
+ return false;
+}
+
/// getFixedSizedAllocaFI - Return the frame index for a fixed sized alloca
/// that is to be statically allocated with the initial stack frame
/// adjustment.
@@ -451,26 +498,27 @@ void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
uint64_t Val = cast<ConstantInt>(C)->getRawValue();
if (Val < (1ULL << 16)) {
- BuildMI(*MBB, IP, PPC32::LI, 1, R).addImm(Val & 0xFFFF);
- BuildMI(*MBB, IP, PPC32::LI, 1, R+1).addImm(0);
+ BuildMI(*MBB, IP, PPC32::LI, 1, R).addSImm(0);
+ BuildMI(*MBB, IP, PPC32::LI, 1, R+1).addSImm(Val & 0xFFFF);
} else if (Val < (1ULL << 32)) {
unsigned Temp = makeAnotherReg(Type::IntTy);
- BuildMI(*MBB, IP, PPC32::LIS, 1, Temp).addImm((Val >> 16) & 0xFFFF);
- BuildMI(*MBB, IP, PPC32::ORI, 2, R).addReg(Temp).addImm(Val & 0xFFFF);
- BuildMI(*MBB, IP, PPC32::LI, 1, R+1).addImm(0);
+ BuildMI(*MBB, IP, PPC32::LI, 1, R).addSImm(0);
+ BuildMI(*MBB, IP, PPC32::LIS, 1, Temp).addSImm((Val >> 16) & 0xFFFF);
+ BuildMI(*MBB, IP, PPC32::ORI, 2, R+1).addReg(Temp).addImm(Val & 0xFFFF);
} else if (Val < (1ULL << 48)) {
unsigned Temp = makeAnotherReg(Type::IntTy);
- BuildMI(*MBB, IP, PPC32::LIS, 1, Temp).addImm((Val >> 16) & 0xFFFF);
- BuildMI(*MBB, IP, PPC32::ORI, 2, R).addReg(Temp).addImm(Val & 0xFFFF);
- BuildMI(*MBB, IP, PPC32::LI, 1, R+1).addImm((Val >> 32) & 0xFFFF);
+ BuildMI(*MBB, IP, PPC32::LI, 1, R).addSImm((Val >> 32) & 0xFFFF);
+ BuildMI(*MBB, IP, PPC32::LIS, 1, Temp).addSImm((Val >> 16) & 0xFFFF);
+ BuildMI(*MBB, IP, PPC32::ORI, 2, R+1).addReg(Temp).addImm(Val & 0xFFFF);
} else {
unsigned TempLo = makeAnotherReg(Type::IntTy);
unsigned TempHi = makeAnotherReg(Type::IntTy);
- BuildMI(*MBB, IP, PPC32::LIS, 1, TempLo).addImm((Val >> 16) & 0xFFFF);
- BuildMI(*MBB, IP, PPC32::ORI, 2, R).addReg(TempLo).addImm(Val & 0xFFFF);
- BuildMI(*MBB, IP, PPC32::LIS, 1, TempHi).addImm((Val >> 48) & 0xFFFF);
- BuildMI(*MBB, IP, PPC32::ORI, 2, R+1).addReg(TempHi)
+ BuildMI(*MBB, IP, PPC32::LIS, 1, TempHi).addSImm((Val >> 48) & 0xFFFF);
+ BuildMI(*MBB, IP, PPC32::ORI, 2, R).addReg(TempHi)
.addImm((Val >> 32) & 0xFFFF);
+ BuildMI(*MBB, IP, PPC32::LIS, 1, TempLo).addSImm((Val >> 16) & 0xFFFF);
+ BuildMI(*MBB, IP, PPC32::ORI, 2, R+1).addReg(TempLo)
+ .addImm(Val & 0xFFFF);
}
return;
}
@@ -478,19 +526,19 @@ void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
assert(Class <= cInt && "Type not handled yet!");
if (C->getType() == Type::BoolTy) {
- BuildMI(*MBB, IP, PPC32::LI, 1, R).addImm(C == ConstantBool::True);
+ BuildMI(*MBB, IP, PPC32::LI, 1, R).addSImm(C == ConstantBool::True);
} else if (Class == cByte || Class == cShort) {
ConstantInt *CI = cast<ConstantInt>(C);
- BuildMI(*MBB, IP, PPC32::LI, 1, R).addImm(CI->getRawValue());
+ BuildMI(*MBB, IP, PPC32::LI, 1, R).addSImm(CI->getRawValue());
} else {
ConstantInt *CI = cast<ConstantInt>(C);
int TheVal = CI->getRawValue() & 0xFFFFFFFF;
if (TheVal < 32768 && TheVal >= -32768) {
- BuildMI(*MBB, IP, PPC32::LI, 1, R).addImm(CI->getRawValue());
+ BuildMI(*MBB, IP, PPC32::LI, 1, R).addSImm(CI->getRawValue());
} else {
unsigned TmpReg = makeAnotherReg(Type::IntTy);
BuildMI(*MBB, IP, PPC32::LIS, 1, TmpReg)
- .addImm(CI->getRawValue() >> 16);
+ .addSImm(CI->getRawValue() >> 16);
BuildMI(*MBB, IP, PPC32::ORI, 2, R).addReg(TmpReg)
.addImm(CI->getRawValue() & 0xFFFF);
}
@@ -516,10 +564,10 @@ void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
.addConstantPoolIndex(CPI);
unsigned LoadOpcode = (Ty == Type::FloatTy) ? PPC32::LFS : PPC32::LFD;
- BuildMI(*MBB, IP, LoadOpcode, 2, R).addImm(0).addReg(Reg2);
+ BuildMI(*MBB, IP, LoadOpcode, 2, R).addSImm(0).addReg(Reg2);
} else if (isa<ConstantPointerNull>(C)) {
// Copy zero (null pointer) to the register.
- BuildMI(*MBB, IP, PPC32::LI, 1, R).addImm(0);
+ BuildMI(*MBB, IP, PPC32::LI, 1, R).addSImm(0);
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) {
// GV is located at PC + distance
unsigned CurPC = makeAnotherReg(Type::IntTy);
@@ -617,9 +665,10 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg+1), FI, 4);
}
}
- ArgOffset += 4; // longs require 4 additional bytes
+ // longs require 4 additional bytes and use 2 GPRs
+ ArgOffset += 4;
if (GPR_remaining > 1) {
- GPR_remaining--; // uses up 2 GPRs
+ GPR_remaining--;
GPR_idx++;
}
break;
@@ -781,8 +830,7 @@ void ISel::SelectPHINodes() {
// it into the conditional branch or select instruction which is the only user
// of the cc instruction. This is the case if the conditional branch is the
// only user of the setcc, and if the setcc is in the same basic block as the
-// conditional branch. We also don't handle long arguments below, so we reject
-// them here as well.
+// conditional branch.
//
static SetCondInst *canFoldSetCCIntoBranchOrSelect(Value *V) {
if (SetCondInst *SCI = dyn_cast<SetCondInst>(V))
@@ -850,25 +898,29 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
const Type *CompTy = Op0->getType();
unsigned Class = getClassB(CompTy);
unsigned Op0r = getReg(Op0, MBB, IP);
+
+ // Use crand for lt, gt and crandc for le, ge
+ unsigned CROpcode = (OpNum == 2 || OpNum == 4) ? PPC32::CRAND : PPC32::CRANDC;
+ // ? cr1[lt] : cr1[gt]
+ unsigned CR1field = (OpNum == 2 || OpNum == 3) ? 4 : 5;
+ // ? cr0[lt] : cr0[gt]
+ unsigned CR0field = (OpNum == 2 || OpNum == 5) ? 0 : 1;
// Special case handling of: cmp R, i
if (isa<ConstantPointerNull>(Op1)) {
- BuildMI(*MBB, IP, PPC32::CMPI, 2, PPC32::CR0).addReg(Op0r).addImm(0);
+ BuildMI(*MBB, IP, PPC32::CMPI, 2, PPC32::CR0).addReg(Op0r).addSImm(0);
} else if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
if (Class == cByte || Class == cShort || Class == cInt) {
- unsigned Op1v = CI->getRawValue();
+ unsigned Op1v = CI->getRawValue() & 0xFFFF;
+ unsigned Opcode = CompTy->isSigned() ? PPC32::CMPW : PPC32::CMPLW;
+ unsigned OpcodeImm = CompTy->isSigned() ? PPC32::CMPWI : PPC32::CMPLWI;
- // Mask off any upper bits of the constant, if there are any...
- Op1v &= (1ULL << (8 << Class)) - 1;
-
- // Compare immediate or promote to reg?
- if (Op1v <= 32767) {
- BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMPI : PPC32::CMPLI, 3,
- PPC32::CR0).addImm(0).addReg(Op0r).addImm(Op1v);
+ // Treat compare like ADDI for the purposes of immediate suitability
+ if (canUseAsImmediateForOpcode(CI, 0)) {
+ BuildMI(*MBB, IP, OpcodeImm, 2, PPC32::CR0).addReg(Op0r).addSImm(Op1v);
} else {
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, Opcode, 2, PPC32::CR0).addReg(Op0r).addReg(Op1r);
}
return OpNum;
} else {
@@ -876,63 +928,48 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
unsigned LowCst = CI->getRawValue();
unsigned HiCst = CI->getRawValue() >> 32;
if (OpNum < 2) { // seteq, setne
- unsigned LoTmp = Op0r;
- if (LowCst != 0) {
- unsigned LoLow = makeAnotherReg(Type::IntTy);
- unsigned LoTmp = makeAnotherReg(Type::IntTy);
- BuildMI(*MBB, IP, PPC32::XORI, 2, LoLow).addReg(Op0r).addImm(LowCst);
- BuildMI(*MBB, IP, PPC32::XORIS, 2, LoTmp).addReg(LoLow)
- .addImm(LowCst >> 16);
- }
- unsigned HiTmp = Op0r+1;
- if (HiCst != 0) {
- unsigned HiLow = makeAnotherReg(Type::IntTy);
- unsigned HiTmp = makeAnotherReg(Type::IntTy);
- BuildMI(*MBB, IP, PPC32::XORI, 2, HiLow).addReg(Op0r+1).addImm(HiCst);
- BuildMI(*MBB, IP, PPC32::XORIS, 2, HiTmp).addReg(HiLow)
- .addImm(HiCst >> 16);
- }
+ unsigned LoLow = makeAnotherReg(Type::IntTy);
+ unsigned LoTmp = makeAnotherReg(Type::IntTy);
+ unsigned HiLow = makeAnotherReg(Type::IntTy);
+ unsigned HiTmp = makeAnotherReg(Type::IntTy);
unsigned FinalTmp = makeAnotherReg(Type::IntTy);
+
+ BuildMI(*MBB, IP, PPC32::XORI, 2, LoLow).addReg(Op0r+1)
+ .addImm(LowCst & 0xFFFF);
+ BuildMI(*MBB, IP, PPC32::XORIS, 2, LoTmp).addReg(LoLow)
+ .addImm(LowCst >> 16);
+ BuildMI(*MBB, IP, PPC32::XORI, 2, HiLow).addReg(Op0r)
+ .addImm(HiCst & 0xFFFF);
+ BuildMI(*MBB, IP, PPC32::XORIS, 2, HiTmp).addReg(HiLow)
+ .addImm(HiCst >> 16);
BuildMI(*MBB, IP, PPC32::ORo, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp);
return OpNum;
} else {
unsigned ConstReg = makeAnotherReg(CompTy);
- unsigned CondReg = makeAnotherReg(Type::IntTy);
- unsigned TmpReg1 = makeAnotherReg(Type::IntTy);
- unsigned TmpReg2 = makeAnotherReg(Type::IntTy);
copyConstantToRegister(MBB, IP, CI, ConstReg);
- // FIXME: this is inefficient, but avoids branches
-
- // compare hi word -> cr0
- // compare lo word -> cr1
- BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMPI : PPC32::CMPLI, 3,
- PPC32::CR0).addImm(0).addReg(Op0r+1).addReg(ConstReg+1);
- BuildMI(*MBB, IP, PPC32::CMPLI, 3, PPC32::CR1).addImm(0).addReg(Op0r)
+ // cr0 = r3 ccOpcode r5 or (r3 == r5 AND r4 ccOpcode r6)
+ BuildMI(*MBB, IP, PPC32::CMPW, 2, PPC32::CR0).addReg(Op0r)
.addReg(ConstReg);
- BuildMI(*MBB, IP, PPC32::MFCR, 0, CondReg);
- // shift amount = 4 * CR0[EQ]
- BuildMI(*MBB, IP, PPC32::RLWINM, 4, TmpReg1).addReg(CondReg).addImm(5)
- .addImm(29).addImm(29);
- // shift cr1 into cr0 position if op0.hi and const.hi were equal
- BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg2).addReg(CondReg)
- .addReg(TmpReg1);
- // cr0 == ( op0.hi != const.hi ) ? cr0 : cr1
- BuildMI(*MBB, IP, PPC32::MTCRF, 2).addImm(1).addReg(TmpReg2);
-
+ BuildMI(*MBB, IP, PPC32::CMPW, 2, PPC32::CR1).addReg(Op0r+1)
+ .addReg(ConstReg+1);
+ BuildMI(*MBB, IP, PPC32::CRAND, 3).addImm(2).addImm(2).addImm(CR1field);
+ BuildMI(*MBB, IP, PPC32::CROR, 3).addImm(CR0field).addImm(CR0field)
+ .addImm(2);
return OpNum;
}
}
}
unsigned Op1r = getReg(Op1, MBB, IP);
+ unsigned Opcode = CompTy->isSigned() ? PPC32::CMPW : PPC32::CMPLW;
+
switch (Class) {
default: assert(0 && "Unknown type class!");
case cByte:
case cShort:
case cInt:
- BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMP : PPC32::CMPL, 2,
- PPC32::CR0).addReg(Op0r).addReg(Op1r);
+ BuildMI(*MBB, IP, Opcode, 2, PPC32::CR0).addReg(Op0r).addReg(Op1r);
break;
case cFP32:
@@ -945,33 +982,22 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
unsigned LoTmp = makeAnotherReg(Type::IntTy);
unsigned HiTmp = makeAnotherReg(Type::IntTy);
unsigned FinalTmp = makeAnotherReg(Type::IntTy);
- BuildMI(*MBB, IP, PPC32::XOR, 2, LoTmp).addReg(Op0r).addReg(Op1r);
- BuildMI(*MBB, IP, PPC32::XOR, 2, HiTmp).addReg(Op0r+1).addReg(Op1r+1);
+ BuildMI(*MBB, IP, PPC32::XOR, 2, HiTmp).addReg(Op0r).addReg(Op1r);
+ BuildMI(*MBB, IP, PPC32::XOR, 2, LoTmp).addReg(Op0r+1).addReg(Op1r+1);
BuildMI(*MBB, IP, PPC32::ORo, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp);
break; // Allow the sete or setne to be generated from flags set by OR
} else {
- unsigned CondReg = makeAnotherReg(Type::IntTy);
unsigned TmpReg1 = makeAnotherReg(Type::IntTy);
unsigned TmpReg2 = makeAnotherReg(Type::IntTy);
-
- // FIXME: this is inefficient, but avoids branches
-
- // compare hi word -> cr0
- // compare lo word -> cr1
- BuildMI(*MBB, IP, CompTy->isSigned() ? PPC32::CMPI : PPC32::CMPLI, 3,
- PPC32::CR0).addImm(0).addReg(Op0r+1).addReg(Op1r+1);
- BuildMI(*MBB, IP, PPC32::CMPLI, 3, PPC32::CR1).addImm(0).addReg(Op0r)
+
+ // cr0 = r3 ccOpcode r5 or (r3 == r5 AND r4 ccOpcode r6)
+ BuildMI(*MBB, IP, PPC32::CMPW, 2, PPC32::CR0).addReg(Op0r)
.addReg(Op1r);
- BuildMI(*MBB, IP, PPC32::MFCR, 0, CondReg);
- // shift amount = 4 * CR0[EQ]
- BuildMI(*MBB, IP, PPC32::RLWINM, 4, TmpReg1).addReg(CondReg).addImm(5)
- .addImm(29).addImm(29);
- // shift cr1 into cr0 position if op0.hi and op1.hi were equal
- BuildMI(*MBB, IP, PPC32::SLW, 2, TmpReg2).addReg(CondReg)
- .addReg(TmpReg1);
- // cr0 == ( op0.hi != op1.hi ) ? cr0 : cr1
- BuildMI(*MBB, IP, PPC32::MTCRF, 2).addImm(1).addReg(TmpReg2);
-
+ BuildMI(*MBB, IP, PPC32::CMPW, 2, PPC32::CR1).addReg(Op1r)
+ .addReg(Op1r+1);
+ BuildMI(*MBB, IP, PPC32::CRAND, 3).addImm(2).addImm(2).addImm(CR1field);
+ BuildMI(*MBB, IP, PPC32::CROR, 3).addImm(CR0field).addImm(CR0field)
+ .addImm(2);
return OpNum;
}
}
@@ -1012,37 +1038,31 @@ void ISel::visitSetCondInst(SetCondInst &I) {
MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
F->getBasicBlockList().insert(It, copy0MBB);
BuildMI(BB, PPC32::B, 1).addMBB(copy0MBB);
- // Update machine-CFG edges
- BB->addSuccessor(copy1MBB);
- BB->addSuccessor(copy0MBB);
-
- // copy0MBB:
- // %FalseValue = li 0
- // b sinkMBB
- BB = copy0MBB;
- unsigned FalseValue = makeAnotherReg(I.getType());
- BuildMI(BB, PPC32::LI, 1, FalseValue).addImm(0);
MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
F->getBasicBlockList().insert(It, sinkMBB);
- BuildMI(BB, PPC32::B, 1).addMBB(sinkMBB);
// Update machine-CFG edges
- BB->addSuccessor(sinkMBB);
-
- DEBUG(std::cerr << "thisMBB is at " << (void*)thisMBB << "\n");
- DEBUG(std::cerr << "copy1MBB is at " << (void*)copy1MBB << "\n");
- DEBUG(std::cerr << "copy0MBB is at " << (void*)copy0MBB << "\n");
- DEBUG(std::cerr << "sinkMBB is at " << (void*)sinkMBB << "\n");
+ BB->addSuccessor(copy1MBB);
+ BB->addSuccessor(copy0MBB);
// copy1MBB:
// %TrueValue = li 1
// b sinkMBB
BB = copy1MBB;
unsigned TrueValue = makeAnotherReg (I.getType ());
- BuildMI(BB, PPC32::LI, 1, TrueValue).addImm(1);
+ BuildMI(BB, PPC32::LI, 1, TrueValue).addSImm(1);
BuildMI(BB, PPC32::B, 1).addMBB(sinkMBB);
// Update machine-CFG edges
BB->addSuccessor(sinkMBB);
+ // copy0MBB:
+ // %FalseValue = li 0
+ // fallthrough
+ BB = copy0MBB;
+ unsigned FalseValue = makeAnotherReg(I.getType());
+ BuildMI(BB, PPC32::LI, 1, FalseValue).addSImm(0);
+ // Update machine-CFG edges
+ BB->addSuccessor(sinkMBB);
+
// sinkMBB:
// %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, copy1MBB ]
// ...
@@ -1081,7 +1101,7 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB,
} else {
unsigned CondReg = getReg(Cond, MBB, IP);
- BuildMI(*MBB, IP, PPC32::CMPI, 2, PPC32::CR0).addReg(CondReg).addImm(0);
+ BuildMI(*MBB, IP, PPC32::CMPI, 2, PPC32::CR0).addReg(CondReg).addSImm(0);
Opcode = getPPCOpcodeForSetCCNumber(Instruction::SetNE);
}
@@ -1105,23 +1125,11 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB,
MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
F->getBasicBlockList().insert(It, copy0MBB);
BuildMI(BB, PPC32::B, 1).addMBB(copy0MBB);
- // Update machine-CFG edges
- BB->addSuccessor(copy1MBB);
- BB->addSuccessor(copy0MBB);
-
- // FIXME: spill code is being generated after the branch and before copy1MBB
- // this is bad, since it will never be run
-
- // copy0MBB:
- // %FalseValue = ...
- // b sinkMBB
- BB = copy0MBB;
- unsigned FalseValue = getReg(FalseVal, BB, BB->begin());
MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
F->getBasicBlockList().insert(It, sinkMBB);
- BuildMI(BB, PPC32::B, 1).addMBB(sinkMBB);
// Update machine-CFG edges
- BB->addSuccessor(sinkMBB);
+ BB->addSuccessor(copy1MBB);
+ BB->addSuccessor(copy0MBB);
// copy1MBB:
// %TrueValue = ...
@@ -1132,6 +1140,14 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB,
// Update machine-CFG edges
BB->addSuccessor(sinkMBB);
+ // copy0MBB:
+ // %FalseValue = ...
+ // fallthrough
+ BB = copy0MBB;
+ unsigned FalseValue = getReg(FalseVal, BB, BB->begin());
+ // Update machine-CFG edges
+ BB->addSuccessor(sinkMBB);
+
// sinkMBB:
// %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, copy1MBB ]
// ...
@@ -1162,10 +1178,10 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
int TheVal = CI->getRawValue() & 0xFFFFFFFF;
if (TheVal < 32768 && TheVal >= -32768) {
- BuildMI(BB, PPC32::LI, 1, targetReg).addImm(TheVal);
+ BuildMI(BB, PPC32::LI, 1, targetReg).addSImm(TheVal);
} else {
unsigned TmpReg = makeAnotherReg(Type::IntTy);
- BuildMI(BB, PPC32::LIS, 1, TmpReg).addImm(TheVal >> 16);
+ BuildMI(BB, PPC32::LIS, 1, TmpReg).addSImm(TheVal >> 16);
BuildMI(BB, PPC32::ORI, 2, targetReg).addReg(TmpReg)
.addImm(TheVal & 0xFFFF);
}
@@ -1301,20 +1317,6 @@ void ISel::visitBranchInst(BranchInst &BI) {
}
}
-static Constant* minUConstantForValue(uint64_t val) {
- if (val <= 1)
- return ConstantBool::get(val);
- else if (ConstantUInt::isValueValidForType(Type::UShortTy, val))
- return ConstantUInt::get(Type::UShortTy, val);
- else if (ConstantUInt::isValueValidForType(Type::UIntTy, val))
- return ConstantUInt::get(Type::UIntTy, val);
- else if (ConstantUInt::isValueValidForType(Type::ULongTy, val))
- return ConstantUInt::get(Type::ULongTy, val);
-
- std::cerr << "Value: " << val << " not accepted for any integral type!\n";
- abort();
-}
-
/// doCall - This emits an abstract call instruction, setting up the arguments
/// and the return value as appropriate. For the actual function call itself,
/// it inserts the specified CallMI instruction into the stream.
@@ -1342,7 +1344,7 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
}
// Adjust the stack pointer for the new arguments...
- BuildMI(BB, PPC32::ADJCALLSTACKDOWN, 1).addImm(NumBytes);
+ BuildMI(BB, PPC32::ADJCALLSTACKDOWN, 1).addSImm(NumBytes);
// Arguments go on the stack in reverse order, as specified by the ABI.
// Offset to the paramater area on the stack is 24.
@@ -1374,7 +1376,7 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
.addReg(ArgReg);
CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
} else {
- BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset)
+ BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addSImm(ArgOffset)
.addReg(PPC32::R1);
}
break;
@@ -1387,7 +1389,7 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
.addReg(ArgReg);
CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
} else {
- BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset)
+ BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addSImm(ArgOffset)
.addReg(PPC32::R1);
}
break;
@@ -1397,16 +1399,16 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
// Reg or stack? Note that PPC calling conventions state that long args
// are passed rN = hi, rN+1 = lo, opposite of LLVM.
if (GPR_remaining > 1) {
- BuildMI(BB, PPC32::OR, 2, GPR[GPR_idx]).addReg(ArgReg+1)
- .addReg(ArgReg+1);
- BuildMI(BB, PPC32::OR, 2, GPR[GPR_idx+1]).addReg(ArgReg)
+ BuildMI(BB, PPC32::OR, 2, GPR[GPR_idx]).addReg(ArgReg)
.addReg(ArgReg);
+ BuildMI(BB, PPC32::OR, 2, GPR[GPR_idx+1]).addReg(ArgReg+1)
+ .addReg(ArgReg+1);
CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
CallMI->addRegOperand(GPR[GPR_idx+1], MachineOperand::Use);
} else {
- BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addImm(ArgOffset)
+ BuildMI(BB, PPC32::STW, 3).addReg(ArgReg).addSImm(ArgOffset)
.addReg(PPC32::R1);
- BuildMI(BB, PPC32::STW, 3).addReg(ArgReg+1).addImm(ArgOffset+4)
+ BuildMI(BB, PPC32::STW, 3).addReg(ArgReg+1).addSImm(ArgOffset+4)
.addReg(PPC32::R1);
}
@@ -1426,16 +1428,16 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
// If this is a vararg function, and there are GPRs left, also
// pass the float in an int. Otherwise, put it on the stack.
if (isVarArg) {
- BuildMI(BB, PPC32::STFS, 3).addReg(ArgReg).addImm(ArgOffset)
+ BuildMI(BB, PPC32::STFS, 3).addReg(ArgReg).addSImm(ArgOffset)
.addReg(PPC32::R1);
if (GPR_remaining > 0) {
BuildMI(BB, PPC32::LWZ, 2, GPR[GPR_idx])
- .addImm(ArgOffset).addReg(ArgReg);
+ .addSImm(ArgOffset).addReg(ArgReg);
CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
}
}
} else {
- BuildMI(BB, PPC32::STFS, 3).addReg(ArgReg).addImm(ArgOffset)
+ BuildMI(BB, PPC32::STFS, 3).addReg(ArgReg).addSImm(ArgOffset)
.addReg(PPC32::R1);
}
break;
@@ -1449,20 +1451,20 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
FPR_idx++;
// For vararg functions, must pass doubles via int regs as well
if (isVarArg) {
- BuildMI(BB, PPC32::STFD, 3).addReg(ArgReg).addImm(ArgOffset)
+ BuildMI(BB, PPC32::STFD, 3).addReg(ArgReg).addSImm(ArgOffset)
.addReg(PPC32::R1);
if (GPR_remaining > 1) {
- BuildMI(BB, PPC32::LWZ, 2, GPR[GPR_idx]).addImm(ArgOffset)
+ BuildMI(BB, PPC32::LWZ, 2, GPR[GPR_idx]).addSImm(ArgOffset)
.addReg(PPC32::R1);
BuildMI(BB, PPC32::LWZ, 2, GPR[GPR_idx+1])
- .addImm(ArgOffset+4).addReg(PPC32::R1);
+ .addSImm(ArgOffset+4).addReg(PPC32::R1);
CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
CallMI->addRegOperand(GPR[GPR_idx+1], MachineOperand::Use);
}
}
} else {
- BuildMI(BB, PPC32::STFD, 3).addReg(ArgReg).addImm(ArgOffset)
+ BuildMI(BB, PPC32::STFD, 3).addReg(ArgReg).addSImm(ArgOffset)
.addReg(PPC32::R1);
}
// Doubles use 8 bytes, and 2 GPRs worth of param space
@@ -1478,11 +1480,11 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
GPR_idx++;
}
} else {
- BuildMI(BB, PPC32::ADJCALLSTACKDOWN, 1).addImm(0);
+ BuildMI(BB, PPC32::ADJCALLSTACKDOWN, 1).addSImm(0);
}
BB->push_back(CallMI);
- BuildMI(BB, PPC32::ADJCALLSTACKUP, 1).addImm(NumBytes);
+ BuildMI(BB, PPC32::ADJCALLSTACKUP, 1).addSImm(NumBytes);
// If there is a return value, scavenge the result from the location the call
// leaves it in...
@@ -1501,8 +1503,8 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
BuildMI(BB, PPC32::FMR, 1, Ret.Reg).addReg(PPC32::F1);
break;
case cLong: // Long values are in r3 hi:r4 lo
- BuildMI(BB, PPC32::OR, 2, Ret.Reg+1).addReg(PPC32::R3).addReg(PPC32::R3);
- BuildMI(BB, PPC32::OR, 2, Ret.Reg).addReg(PPC32::R4).addReg(PPC32::R4);
+ BuildMI(BB, PPC32::OR, 2, Ret.Reg).addReg(PPC32::R3).addReg(PPC32::R3);
+ BuildMI(BB, PPC32::OR, 2, Ret.Reg+1).addReg(PPC32::R4).addReg(PPC32::R4);
break;
default: assert(0 && "Unknown class!");
}
@@ -1639,11 +1641,11 @@ void ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
MachineFrameInfo *MFI = F->getFrameInfo();
unsigned NumBytes = MFI->getStackSize();
- BuildMI(BB, PPC32::LWZ, 2, TmpReg1).addImm(NumBytes+8)
+ BuildMI(BB, PPC32::LWZ, 2, TmpReg1).addSImm(NumBytes+8)
.addReg(PPC32::R1);
} else {
// Values other than zero are not implemented yet.
- BuildMI(BB, PPC32::LI, 1, TmpReg1).addImm(0);
+ BuildMI(BB, PPC32::LI, 1, TmpReg1).addSImm(0);
}
return;
@@ -1653,7 +1655,7 @@ void ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
BuildMI(BB, PPC32::OR, 2, TmpReg1).addReg(PPC32::R1).addReg(PPC32::R1);
} else {
// Values other than zero are not implemented yet.
- BuildMI(BB, PPC32::LI, 1, TmpReg1).addImm(0);
+ BuildMI(BB, PPC32::LI, 1, TmpReg1).addSImm(0);
}
return;
@@ -1771,6 +1773,10 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
static const unsigned OpcodeTab[] = {
PPC32::ADD, PPC32::SUB, PPC32::AND, PPC32::OR, PPC32::XOR
};
+ static const unsigned ImmOpcodeTab[] = {
+ PPC32::ADDI, PPC32::SUBI, PPC32::ANDIo, PPC32::ORI, PPC32::XORI
+ };
+
// Otherwise, code generate the full operation with a constant.
static const unsigned BottomTab[] = {
PPC32::ADDC, PPC32::SUBC, PPC32::AND, PPC32::OR, PPC32::XOR
@@ -1802,23 +1808,19 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
}
// sub 0, X -> neg X
- if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0))
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0)) {
if (OperatorClass == 1 && CI->isNullValue()) {
- unsigned op1Reg = getReg(Op1, MBB, IP);
- BuildMI(*MBB, IP, PPC32::NEG, 1, DestReg).addReg(op1Reg);
-
+ unsigned Op1r = getReg(Op1, MBB, IP);
+
if (Class == cLong) {
- unsigned zeroes = makeAnotherReg(Type::IntTy);
- unsigned overflow = makeAnotherReg(Type::IntTy);
- unsigned T = makeAnotherReg(Type::IntTy);
- 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::ADD, 2, T).addReg(op1Reg+1).addReg(overflow);
- BuildMI(*MBB, IP, PPC32::NEG, 1, DestReg+1).addReg(T);
+ BuildMI(*MBB, IP, PPC32::SUBFIC, 2, DestReg+1).addReg(Op1r+1).addSImm(0);
+ BuildMI(*MBB, IP, PPC32::SUBFZE, 1, DestReg).addReg(Op1r);
+ } else {
+ BuildMI(*MBB, IP, PPC32::NEG, 1, DestReg).addReg(Op1r);
}
return;
}
+ }
// Special case: op Reg, <const int>
if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
@@ -1827,54 +1829,37 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
// xor X, -1 -> not X
if (OperatorClass == 4 && Op1C->isAllOnesValue()) {
BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg).addReg(Op0r).addReg(Op0r);
- if (Class == cLong) // Invert the top part too
+ if (Class == cLong) // Invert the low part too
BuildMI(*MBB, IP, PPC32::NOR, 2, DestReg+1).addReg(Op0r+1)
.addReg(Op0r+1);
return;
}
-
- unsigned Opcode = OpcodeTab[OperatorClass];
- unsigned Op1r = getReg(Op1, MBB, IP);
-
- if (Class != cLong) {
- BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r);
- return;
- }
-
- // If the constant is zero in the low 32-bits, just copy the low part
- // across and apply the normal 32-bit operation to the high parts. There
- // will be no carry or borrow into the top.
- if (cast<ConstantInt>(Op1C)->getRawValue() == 0) {
- if (OperatorClass != 2) // All but and...
- BuildMI(*MBB, IP, PPC32::OR, 2, DestReg).addReg(Op0r).addReg(Op0r);
- else
- BuildMI(*MBB, IP, PPC32::LI, 1, DestReg).addImm(0);
- BuildMI(*MBB, IP, Opcode, 2, DestReg+1).addReg(Op0r+1).addReg(Op1r+1);
- return;
- }
-
- // If this is a long value and the high or low bits have a special
- // property, emit some special cases.
- unsigned Op1h = cast<ConstantInt>(Op1C)->getRawValue() >> 32LL;
- // If this is a logical operation and the top 32-bits are zero, just
- // operate on the lower 32.
- if (Op1h == 0 && OperatorClass > 1) {
- BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r);
- if (OperatorClass != 2) // All but and
- BuildMI(*MBB, IP, PPC32::OR, 2,DestReg+1).addReg(Op0r+1).addReg(Op0r+1);
- else
- BuildMI(*MBB, IP, PPC32::LI, 1,DestReg+1).addImm(0);
+ // FIXME: We're not handling ANDI right now since it could trash the CR
+ if (Class != cLong) {
+ if (canUseAsImmediateForOpcode(Op1C, OperatorClass)) {
+ int immediate = Op1C->getRawValue() & 0xFFFF;
+
+ if (OperatorClass < 2)
+ BuildMI(*MBB, IP, ImmOpcodeTab[OperatorClass], 2, DestReg).addReg(Op0r)
+ .addSImm(immediate);
+ else
+ BuildMI(*MBB, IP, ImmOpcodeTab[OperatorClass], 2, DestReg).addReg(Op0r)
+ .addZImm(immediate);
+ } else {
+ unsigned Op1r = getReg(Op1, MBB, IP);
+ BuildMI(*MBB, IP, OpcodeTab[OperatorClass], 2, DestReg).addReg(Op0r)
+ .addReg(Op1r);
+ }
return;
}
-
- // TODO: We could handle lots of other special cases here, such as AND'ing
- // with 0xFFFFFFFF00000000 -> noop, etc.
-
- BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r)
- .addReg(Op1r);
- BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
+
+ unsigned Op1r = getReg(Op1, MBB, IP);
+
+ BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
.addReg(Op1r+1);
+ BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg).addReg(Op0r)
+ .addReg(Op1r);
return;
}
@@ -1885,36 +1870,14 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
unsigned Opcode = OpcodeTab[OperatorClass];
BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r);
} else {
- BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg).addReg(Op0r)
- .addReg(Op1r);
- BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
+ BuildMI(*MBB, IP, BottomTab[OperatorClass], 2, DestReg+1).addReg(Op0r+1)
.addReg(Op1r+1);
+ BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg).addReg(Op0r)
+ .addReg(Op1r);
}
return;
}
-/// doMultiply - Emit appropriate instructions to multiply together the
-/// registers op0Reg and op1Reg, and put the result in DestReg. The type of the
-/// result should be given as DestTy.
-///
-void ISel::doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI,
- unsigned DestReg, const Type *DestTy,
- unsigned op0Reg, unsigned op1Reg) {
- unsigned Class = getClass(DestTy);
- switch (Class) {
- case cLong:
- BuildMI(*MBB, MBBI, PPC32::MULHW, 2, DestReg+1).addReg(op0Reg+1)
- .addReg(op1Reg+1);
- case cInt:
- case cShort:
- case cByte:
- BuildMI(*MBB, MBBI, PPC32::MULLW, 2, DestReg).addReg(op0Reg).addReg(op1Reg);
- return;
- default:
- assert(0 && "doMultiply cannot operate on unknown type!");
- }
-}
-
// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It
// returns zero when the input is not exactly a power of two.
static unsigned ExactLog2(unsigned Val) {
@@ -1924,50 +1887,108 @@ static unsigned ExactLog2(unsigned Val) {
Val >>= 1;
++Count;
}
- return Count+1;
+ return Count;
}
-
-/// doMultiplyConst - This function is specialized to efficiently codegen an 8,
-/// 16, or 32-bit integer multiply by a constant.
+/// doMultiply - Emit appropriate instructions to multiply together the
+/// Values Op0 and Op1, and put the result in DestReg.
///
+void ISel::doMultiply(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator IP,
+ unsigned DestReg, Value *Op0, Value *Op1) {
+ unsigned Class0 = getClass(Op0->getType());
+ unsigned Class1 = getClass(Op1->getType());
+
+ unsigned Op0r = getReg(Op0, MBB, IP);
+ unsigned Op1r = getReg(Op1, MBB, IP);
+
+ // 64 x 64 -> 64
+ if (Class0 == cLong && Class1 == cLong) {
+ unsigned Tmp1 = makeAnotherReg(Type::IntTy);
+ unsigned Tmp2 = makeAnotherReg(Type::IntTy);
+ unsigned Tmp3 = makeAnotherReg(Type::IntTy);
+ unsigned Tmp4 = makeAnotherReg(Type::IntTy);
+ BuildMI(*MBB, IP, PPC32::MULHWU, 2, Tmp1).addReg(Op0r+1).addReg(Op1r+1);
+ BuildMI(*MBB, IP, PPC32::MULLW, 2, DestReg+1).addReg(Op0r+1).addReg(Op1r+1);
+ BuildMI(*MBB, IP, PPC32::MULLW, 2, Tmp2).addReg(Op0r+1).addReg(Op1r);
+ BuildMI(*MBB, IP, PPC32::ADD, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
+ BuildMI(*MBB, IP, PPC32::MULLW, 2, Tmp4).addReg(Op0r).addReg(Op1r+1);
+ BuildMI(*MBB, IP, PPC32::ADD, 2, DestReg).addReg(Tmp3).addReg(Tmp4);
+ return;
+ }
+
+ // 64 x 32 or less, pro