Use BuildMI more

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5299 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2003-01-15 19:23:34 +00:00
parent 1531b63421
commit 54e898e690
2 changed files with 156 additions and 242 deletions

View File

@ -70,11 +70,8 @@ CreateSETUWConst(const TargetMachine& target, uint32_t C,
else else
{ // unsigned or small signed value that fits in simm13 field of OR { // unsigned or small signed value that fits in simm13 field of OR
assert(smallNegValue || (C & ~MAXSIMM) == 0); assert(smallNegValue || (C & ~MAXSIMM) == 0);
miOR = new MachineInstr(OR); miOR = BuildMI(OR, 3).addMReg(target.getRegInfo().getZeroRegNum())
miOR->SetMachineOperandReg(0, target.getRegInfo().getZeroRegNum()); .addSImm(sC).addRegDef(dest);
miOR->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
sC);
miOR->SetMachineOperandVal(2,MachineOperand::MO_VirtualRegister,dest);
} }
mvec.push_back(miOR); mvec.push_back(miOR);
} }
@ -180,7 +177,7 @@ CreateSETXLabel(const TargetMachine& target,
MachineInstr* MI; MachineInstr* MI;
MI = BuildMI(SETHI, 2).addReg(val).addRegDef(tmpReg); MI = BuildMI(SETHI, 2).addPCDisp(val).addRegDef(tmpReg);
MI->setOperandHi64(0); MI->setOperandHi64(0);
mvec.push_back(MI); mvec.push_back(MI);
@ -501,11 +498,10 @@ UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target,
CreateZeroExtensionInstructions(target, F, val, storeVal, 8*srcSize, CreateZeroExtensionInstructions(target, F, val, storeVal, 8*srcSize,
mvec, mcfi); mvec, mcfi);
} }
MachineInstr* store=new MachineInstr(ChooseStoreInstruction(storeType));
store->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, storeVal); unsigned FPReg = target.getRegInfo().getFramePointer();
store->SetMachineOperandReg(1, target.getRegInfo().getFramePointer()); mvec.push_back(BuildMI(ChooseStoreInstruction(storeType), 3)
store->SetMachineOperandConst(2,MachineOperand::MO_SignExtendedImmed,offset); .addReg(storeVal).addMReg(FPReg).addSImm(offset));
mvec.push_back(store);
// Load instruction loads [%fp+offset] to `dest'. // Load instruction loads [%fp+offset] to `dest'.
// The type of the load opCode is the floating point type that matches the // The type of the load opCode is the floating point type that matches the
@ -513,11 +509,8 @@ UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target,
// On SparcV9: float for int or smaller, double for long. // On SparcV9: float for int or smaller, double for long.
// //
const Type* loadType = (srcSize <= 4)? Type::FloatTy : Type::DoubleTy; const Type* loadType = (srcSize <= 4)? Type::FloatTy : Type::DoubleTy;
MachineInstr* load = new MachineInstr(ChooseLoadInstruction(loadType)); mvec.push_back(BuildMI(ChooseLoadInstruction(loadType), 3)
load->SetMachineOperandReg(0, target.getRegInfo().getFramePointer()); .addMReg(FPReg).addSImm(offset).addRegDef(dest));
load->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,offset);
load->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, dest);
mvec.push_back(load);
} }
// Similarly, create an instruction sequence to copy an FP register // Similarly, create an instruction sequence to copy an FP register
@ -543,14 +536,13 @@ UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target,
int offset = MachineFunction::get(F).getInfo()->allocateLocalVar(val); int offset = MachineFunction::get(F).getInfo()->allocateLocalVar(val);
unsigned FPReg = target.getRegInfo().getFramePointer();
// Store instruction stores `val' to [%fp+offset]. // Store instruction stores `val' to [%fp+offset].
// The store opCode is based only the source value being copied. // The store opCode is based only the source value being copied.
// //
MachineInstr* store=new MachineInstr(ChooseStoreInstruction(opTy)); mvec.push_back(BuildMI(ChooseStoreInstruction(opTy), 3)
store->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, val); .addReg(val).addMReg(FPReg).addSImm(offset));
store->SetMachineOperandReg(1, target.getRegInfo().getFramePointer());
store->SetMachineOperandConst(2,MachineOperand::MO_SignExtendedImmed,offset);
mvec.push_back(store);
// Load instruction loads [%fp+offset] to `dest'. // Load instruction loads [%fp+offset] to `dest'.
// The type of the load opCode is the integer type that matches the // The type of the load opCode is the integer type that matches the
@ -560,11 +552,8 @@ UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target,
// ensure correct sign-extension for UByte, UShort or UInt: // ensure correct sign-extension for UByte, UShort or UInt:
// //
const Type* loadTy = (opTy == Type::FloatTy)? Type::IntTy : Type::LongTy; const Type* loadTy = (opTy == Type::FloatTy)? Type::IntTy : Type::LongTy;
MachineInstr* load = new MachineInstr(ChooseLoadInstruction(loadTy)); mvec.push_back(BuildMI(ChooseLoadInstruction(loadTy), 3).addMReg(FPReg)
load->SetMachineOperandReg(0, target.getRegInfo().getFramePointer()); .addSImm(offset).addRegDef(dest));
load->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,offset);
load->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, dest);
mvec.push_back(load);
} }

View File

@ -26,6 +26,16 @@
#include <math.h> #include <math.h>
using std::vector; using std::vector;
static inline void Add3OperandInstr(unsigned Opcode, InstructionNode* Node,
vector<MachineInstr*>& mvec) {
mvec.push_back(BuildMI(Opcode, 3).addReg(Node->leftChild()->getValue())
.addReg(Node->rightChild()->getValue())
.addRegDef(Node->getValue()));
}
//************************ Internal Functions ******************************/ //************************ Internal Functions ******************************/
@ -716,25 +726,26 @@ ChooseDivInstruction(TargetMachine &target,
} }
// Return NULL if we cannot exploit constant to create a cheaper instruction // Return if we cannot exploit constant to create a cheaper instruction
static inline void static inline void
CreateDivConstInstruction(TargetMachine &target, CreateDivConstInstruction(TargetMachine &target,
const InstructionNode* instrNode, const InstructionNode* instrNode,
vector<MachineInstr*>& mvec) vector<MachineInstr*>& mvec)
{ {
MachineInstr* minstr1 = NULL; Value* LHS = instrNode->leftChild()->getValue();
MachineInstr* minstr2 = NULL;
Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue(); Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
if (! isa<Constant>(constOp)) if (!isa<Constant>(constOp))
return; return;
Value* DestVal = instrNode->getValue();
unsigned ZeroReg = target.getRegInfo().getZeroRegNum();
// Cases worth optimizing are: // Cases worth optimizing are:
// (1) Divide by 1 for any type: replace with copy (ADD or FMOV) // (1) Divide by 1 for any type: replace with copy (ADD or FMOV)
// (2) Divide by 2^x for integer types: replace with SR[L or A]{X} // (2) Divide by 2^x for integer types: replace with SR[L or A]{X}
// //
const Type* resultType = instrNode->getInstruction()->getType(); const Type* resultType = instrNode->getInstruction()->getType();
if (resultType->isInteger()) if (resultType->isInteger())
{ {
unsigned pow; unsigned pow;
@ -743,39 +754,25 @@ CreateDivConstInstruction(TargetMachine &target,
if (isValidConst) if (isValidConst)
{ {
bool needNeg = false; bool needNeg = false;
if (C < 0) if (C < 0) {
{ needNeg = true;
needNeg = true; C = -C;
C = -C; }
}
if (C == 1) if (C == 1) {
{ mvec.push_back(BuildMI(ADD, 3).addReg(LHS).addMReg(ZeroReg)
minstr1 = new MachineInstr(ADD); .addRegDef(DestVal));
minstr1->SetMachineOperandVal(0, } else if (isPowerOf2(C, pow)) {
MachineOperand::MO_VirtualRegister, unsigned opCode= ((resultType->isSigned())
instrNode->leftChild()->getValue()); ? (resultType==Type::LongTy) ? SRAX : SRA
minstr1->SetMachineOperandReg(1, : (resultType==Type::LongTy) ? SRLX : SRL);
target.getRegInfo().getZeroRegNum()); mvec.push_back(BuildMI(opCode, 3).addReg(LHS).addZImm(pow)
} .addRegDef(DestVal));
else if (isPowerOf2(C, pow)) }
{
MachineOpCode opCode= ((resultType->isSigned())
? (resultType==Type::LongTy)? SRAX : SRA
: (resultType==Type::LongTy)? SRLX : SRL);
minstr1 = new MachineInstr(opCode);
minstr1->SetMachineOperandVal(0,
MachineOperand::MO_VirtualRegister,
instrNode->leftChild()->getValue());
minstr1->SetMachineOperandConst(1,
MachineOperand::MO_UnextendedImmed,
pow);
}
if (minstr1 && needNeg) if (needNeg && (C == 1 || isPowerOf2(C, pow)))
{ // insert <reg = SUB 0, reg> after the instr to flip the sign { // insert <reg = SUB 0, reg> after the instr to flip the sign
minstr2 = CreateIntNegInstruction(target, mvec.push_back(CreateIntNegInstruction(target, DestVal));
instrNode->getValue());
} }
} }
} }
@ -786,28 +783,14 @@ CreateDivConstInstruction(TargetMachine &target,
double dval = FPC->getValue(); double dval = FPC->getValue();
if (fabs(dval) == 1) if (fabs(dval) == 1)
{ {
bool needNeg = (dval < 0); unsigned opCode =
(dval < 0) ? (resultType == Type::FloatTy? FNEGS : FNEGD)
: (resultType == Type::FloatTy? FMOVS : FMOVD);
MachineOpCode opCode = needNeg mvec.push_back(BuildMI(opCode, 2).addReg(LHS).addRegDef(DestVal));
? (resultType == Type::FloatTy? FNEGS : FNEGD)
: (resultType == Type::FloatTy? FMOVS : FMOVD);
minstr1 = new MachineInstr(opCode);
minstr1->SetMachineOperandVal(0,
MachineOperand::MO_VirtualRegister,
instrNode->leftChild()->getValue());
} }
} }
} }
if (minstr1 != NULL)
minstr1->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
instrNode->getValue());
if (minstr1)
mvec.push_back(minstr1);
if (minstr2)
mvec.push_back(minstr2);
} }
@ -870,20 +853,15 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target,
target.getFrameInfo().getDynamicAreaOffset(mcInfo,growUp)); target.getFrameInfo().getDynamicAreaOffset(mcInfo,growUp));
assert(! growUp && "Has SPARC v9 stack frame convention changed?"); assert(! growUp && "Has SPARC v9 stack frame convention changed?");
unsigned SPReg = target.getRegInfo().getStackPointer();
// Instruction 2: sub %sp, totalSizeVal -> %sp // Instruction 2: sub %sp, totalSizeVal -> %sp
M = new MachineInstr(SUB); getMvec.push_back(BuildMI(SUB, 3).addMReg(SPReg).addReg(totalSizeVal)
M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer()); .addMReg(SPReg,MOTy::Def));
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, totalSizeVal);
M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
getMvec.push_back(M);
// Instruction 3: add %sp, frameSizeBelowDynamicArea -> result // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
M = new MachineInstr(ADD); getMvec.push_back(BuildMI(ADD, 3).addMReg(SPReg).addReg(dynamicAreaOffset)
M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer()); .addRegDef(result));
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
dynamicAreaOffset);
M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, result);
getMvec.push_back(M);
} }
@ -923,12 +901,9 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target,
ConstantSInt* offsetVal = ConstantSInt::get(Type::IntTy, offsetFromFP); ConstantSInt* offsetVal = ConstantSInt::get(Type::IntTy, offsetFromFP);
// Instruction 1: add %fp, offsetFromFP -> result // Instruction 1: add %fp, offsetFromFP -> result
MachineInstr* M = new MachineInstr(ADD); unsigned FPReg = target.getRegInfo().getFramePointer();
M->SetMachineOperandReg(0, target.getRegInfo().getFramePointer()); getMvec.push_back(BuildMI(ADD, 3).addMReg(FPReg).addReg(offsetVal)
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, offsetVal); .addRegDef(result));
M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, result);
getMvec.push_back(M);
} }
@ -949,13 +924,12 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target,
//------------------------------------------------------------------------ //------------------------------------------------------------------------
static void static void
SetOperandsForMemInstr(vector<MachineInstr*>& mvec, SetOperandsForMemInstr(unsigned Opcode,
vector<MachineInstr*>& mvec,
InstructionNode* vmInstrNode, InstructionNode* vmInstrNode,
const TargetMachine& target) const TargetMachine& target)
{ {
Instruction* memInst = vmInstrNode->getInstruction(); Instruction* memInst = vmInstrNode->getInstruction();
vector<MachineInstr*>::iterator mvecI = mvec.end() - 1;
// Index vector, ptr value, and flag if all indices are const. // Index vector, ptr value, and flag if all indices are const.
vector<Value*> idxVec; vector<Value*> idxVec;
bool allConstantIndices; bool allConstantIndices;
@ -1020,12 +994,8 @@ SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
mulVec, MachineCodeForInstruction::get(memInst), mulVec, MachineCodeForInstruction::get(memInst),
INVALID_MACHINE_OPCODE); INVALID_MACHINE_OPCODE);
// Insert mulVec[] before *mvecI in mvec[] and update mvecI
// to point to the same instruction it pointed to before.
assert(mulVec.size() > 0 && "No multiply code created?"); assert(mulVec.size() > 0 && "No multiply code created?");
vector<MachineInstr*>::iterator oldMvecI = mvecI; mvec.insert(mvec.end(), mulVec.begin(), mulVec.end());
for (unsigned i=0, N=mulVec.size(); i < N; ++i)
mvecI = mvec.insert(mvecI, mulVec[i]) + 1; // pts to mem instr
valueForRegOffset = addr; valueForRegOffset = addr;
} }
@ -1042,33 +1012,23 @@ SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
// Operand 0 is ptr, operand 1 is offset, operand 2 is result. // Operand 0 is ptr, operand 1 is offset, operand 2 is result.
// //
unsigned offsetOpNum, ptrOpNum; unsigned offsetOpNum, ptrOpNum;
if (memInst->getOpcode() == Instruction::Store) MachineInstr *MI;
{ if (memInst->getOpcode() == Instruction::Store) {
(*mvecI)->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, if (offsetOpType == MachineOperand::MO_VirtualRegister)
vmInstrNode->leftChild()->getValue()); MI = BuildMI(Opcode, 3).addReg(vmInstrNode->leftChild()->getValue())
ptrOpNum = 1; .addReg(ptrVal).addReg(valueForRegOffset);
offsetOpNum = 2; else
} MI = BuildMI(Opcode, 3).addReg(vmInstrNode->leftChild()->getValue())
else .addReg(ptrVal).addSImm(smallConstOffset);
{ } else {
ptrOpNum = 0; if (offsetOpType == MachineOperand::MO_VirtualRegister)
offsetOpNum = 1; MI = BuildMI(Opcode, 3).addReg(ptrVal).addReg(valueForRegOffset)
(*mvecI)->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, .addRegDef(memInst);
memInst); else
} MI = BuildMI(Opcode, 3).addReg(ptrVal).addSImm(smallConstOffset)
.addRegDef(memInst);
(*mvecI)->SetMachineOperandVal(ptrOpNum, MachineOperand::MO_VirtualRegister, }
ptrVal); mvec.push_back(MI);
if (offsetOpType == MachineOperand::MO_VirtualRegister)
{
assert(valueForRegOffset != NULL);
(*mvecI)->SetMachineOperandVal(offsetOpNum, offsetOpType,
valueForRegOffset);
}
else
(*mvecI)->SetMachineOperandConst(offsetOpNum, offsetOpType,
smallConstOffset);
} }
@ -1265,21 +1225,20 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 3: // stmt: Store(reg,reg) case 3: // stmt: Store(reg,reg)
case 4: // stmt: Store(reg,ptrreg) case 4: // stmt: Store(reg,ptrreg)
mvec.push_back(new MachineInstr( SetOperandsForMemInstr(ChooseStoreInstruction(
ChooseStoreInstruction( subtreeRoot->leftChild()->getValue()->getType()),
subtreeRoot->leftChild()->getValue()->getType()))); mvec, subtreeRoot, target);
SetOperandsForMemInstr(mvec, subtreeRoot, target);
break; break;
case 5: // stmt: BrUncond case 5: // stmt: BrUncond
M = new MachineInstr(BA); {
M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp, BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction());
cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(0)); mvec.push_back(BuildMI(BA, 1).addPCDisp(BI->getSuccessor(0)));
mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(new MachineInstr(NOP)); mvec.push_back(BuildMI(NOP, 0));
break; break;
}
case 206: // stmt: BrCond(setCCconst) case 206: // stmt: BrCond(setCCconst)
{ // setCCconst => boolean was computed with `%b = setCC type reg1 const' { // setCCconst => boolean was computed with `%b = setCC type reg1 const'
@ -1308,25 +1267,19 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
BranchInst* brInst=cast<BranchInst>(subtreeRoot->getInstruction()); BranchInst* brInst=cast<BranchInst>(subtreeRoot->getInstruction());
M = new MachineInstr(ChooseBprInstruction(subtreeRoot)); M = BuildMI(ChooseBprInstruction(subtreeRoot), 2)
M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, .addReg(setCCNode->leftChild()->getValue())
setCCNode->leftChild()->getValue()); .addPCDisp(brInst->getSuccessor(0));
M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
brInst->getSuccessor(0));
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(new MachineInstr(NOP)); mvec.push_back(BuildMI(NOP, 0));
// false branch // false branch
M = new MachineInstr(BA); mvec.push_back(BuildMI(BA, 1).addPCDisp(brInst->getSuccessor(1)));
M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp,
brInst->getSuccessor(1));
mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(new MachineInstr(NOP)); mvec.push_back(BuildMI(NOP, 0));
break; break;
} }
// ELSE FALL THROUGH // ELSE FALL THROUGH
@ -1340,28 +1293,22 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// //
BranchInst* brInst = cast<BranchInst>(subtreeRoot->getInstruction()); BranchInst* brInst = cast<BranchInst>(subtreeRoot->getInstruction());
bool isFPBranch; bool isFPBranch;
M = new MachineInstr(ChooseBccInstruction(subtreeRoot, isFPBranch)); unsigned Opcode = ChooseBccInstruction(subtreeRoot, isFPBranch);
Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(), Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(),
brInst->getParent()->getParent(), brInst->getParent()->getParent(),
isFPBranch? Type::FloatTy : Type::IntTy); isFPBranch? Type::FloatTy : Type::IntTy);
M = BuildMI(Opcode, 2).addCCReg(ccValue)
M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister, ccValue); .addPCDisp(brInst->getSuccessor(0));
M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
brInst->getSuccessor(0));
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(new MachineInstr(NOP)); mvec.push_back(BuildMI(NOP, 0));
// false branch // false branch
M = new MachineInstr(BA); mvec.push_back(BuildMI(BA, 1).addPCDisp(brInst->getSuccessor(1)));
M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp,
brInst->getSuccessor(1));
mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(new MachineInstr(NOP)); mvec.push_back(BuildMI(NOP, 0));
break; break;
} }
@ -1372,13 +1319,12 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
cast<Constant>(subtreeRoot->leftChild()->getValue()); cast<Constant>(subtreeRoot->leftChild()->getValue());
unsigned dest = cast<ConstantBool>(constVal)->getValue()? 0 : 1; unsigned dest = cast<ConstantBool>(constVal)->getValue()? 0 : 1;
M = new MachineInstr(BA); M = BuildMI(BA, 1).addPCDisp(
M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp,
cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(dest)); cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(dest));
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(new MachineInstr(NOP)); mvec.push_back(BuildMI(NOP, 0));
break; break;
} }
@ -1386,24 +1332,19 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ // boolreg => boolean is stored in an existing register. { // boolreg => boolean is stored in an existing register.
// Just use the branch-on-integer-register instruction! // Just use the branch-on-integer-register instruction!
// //
M = new MachineInstr(BRNZ); BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction());
M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, M = BuildMI(BRNZ, 2).addReg(subtreeRoot->leftChild()->getValue())
subtreeRoot->leftChild()->getValue()); .addPCDisp(BI->getSuccessor(0));
M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(0));
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(new MachineInstr(NOP)); mvec.push_back(BuildMI(NOP, 0));
// false branch // false branch
M = new MachineInstr(BA); mvec.push_back(BuildMI(BA, 1).addPCDisp(BI->getSuccessor(1)));
M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp,
cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(1));
mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(new MachineInstr(NOP)); mvec.push_back(BuildMI(NOP, 0));
break; break;
} }
@ -1589,11 +1530,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
else else
srcForCast = leftVal; srcForCast = leftVal;
M = new MachineInstr(opCode); M = BuildMI(opCode, 2).addReg(srcForCast).addRegDef(dest);
M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
srcForCast);
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
dest);
mvec.push_back(M); mvec.push_back(M);
} }
} }
@ -1616,8 +1553,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 33: // reg: Add(reg, reg) case 33: // reg: Add(reg, reg)
maskUnsignedResult = true; maskUnsignedResult = true;
mvec.push_back(new MachineInstr(ChooseAddInstruction(subtreeRoot))); Add3OperandInstr(ChooseAddInstruction(subtreeRoot), subtreeRoot, mvec);
Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break; break;
case 234: // reg: Sub(reg, Constant) case 234: // reg: Sub(reg, Constant)
@ -1632,9 +1568,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 34: // reg: Sub(reg, reg) case 34: // reg: Sub(reg, reg)
maskUnsignedResult = true; maskUnsignedResult = true;
mvec.push_back(new MachineInstr(ChooseSubInstructionByType( Add3OperandInstr(ChooseSubInstructionByType(
subtreeRoot->getInstruction()->getType()))); subtreeRoot->getInstruction()->getType()),
Set3OperandsFromInstr(mvec.back(), subtreeRoot, target); subtreeRoot, mvec);
break; break;
case 135: // reg: Mul(todouble, todouble) case 135: // reg: Mul(todouble, todouble)
@ -1684,9 +1620,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 36: // reg: Div(reg, reg) case 36: // reg: Div(reg, reg)
maskUnsignedResult = true; maskUnsignedResult = true;
mvec.push_back(new MachineInstr(ChooseDivInstruction(target, Add3OperandInstr(ChooseDivInstruction(target, subtreeRoot),
subtreeRoot))); subtreeRoot, mvec);
Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break; break;
case 37: // reg: Rem(reg, reg) case 37: // reg: Rem(reg, reg)
@ -1703,9 +1638,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
subtreeRoot->rightChild()->getValue()); subtreeRoot->rightChild()->getValue());
MachineCodeForInstruction::get(remInstr).addTemp(quot).addTemp(prod); MachineCodeForInstruction::get(remInstr).addTemp(quot).addTemp(prod);
M = new MachineInstr(ChooseDivInstruction(target, subtreeRoot)); M = BuildMI(ChooseDivInstruction(target, subtreeRoot), 3)
Set3OperandsFromInstr(M, subtreeRoot, target); .addReg(subtreeRoot->leftChild()->getValue())
M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,quot); .addReg(subtreeRoot->rightChild()->getValue())
.addRegDef(quot);
mvec.push_back(M); mvec.push_back(M);
unsigned MulOpcode = unsigned MulOpcode =
@ -1715,12 +1651,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
MOTy::Def); MOTy::Def);
mvec.push_back(M); mvec.push_back(M);
M = new MachineInstr(ChooseSubInstructionByType( unsigned Opcode = ChooseSubInstructionByType(
subtreeRoot->getInstruction()->getType())); subtreeRoot->getInstruction()->getType());
Set3OperandsFromInstr(M, subtreeRoot, target); M = BuildMI(Opcode, 3).addReg(subtreeRoot->leftChild()->getValue())
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,prod); .addReg(prod).addRegDef(subtreeRoot->getValue());
mvec.push_back(M); mvec.push_back(M);
break; break;
} }
@ -1728,8 +1663,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 238: // bool: And(bool, boolconst) case 238: // bool: And(bool, boolconst)
case 338: // reg : BAnd(reg, reg) case 338: // reg : BAnd(reg, reg)
case 538: // reg : BAnd(reg, Constant) case 538: // reg : BAnd(reg, Constant)
mvec.push_back(new MachineInstr(AND)); Add3OperandInstr(AND, subtreeRoot, mvec);
Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break; break;
case 138: // bool: And(bool, not) case 138: // bool: And(bool, not)
@ -1751,8 +1685,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 239: // bool: Or(bool, boolconst) case 239: // bool: Or(bool, boolconst)
case 339: // reg : BOr(reg, reg) case 339: // reg : BOr(reg, reg)
case 539: // reg : BOr(reg, Constant) case 539: // reg : BOr(reg, Constant)
mvec.push_back(new MachineInstr(OR)); Add3OperandInstr(OR, subtreeRoot, mvec);
Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break; break;
case 139: // bool: Or(bool, not) case 139: // bool: Or(bool, not)
@ -1774,8 +1707,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 240: // bool: Xor(bool, boolconst) case 240: // bool: Xor(bool, boolconst)
case 340: // reg : BXor(reg, reg) case 340: // reg : BXor(reg, reg)
case 540: // reg : BXor(reg, Constant) case 540: // reg : BXor(reg, Constant)
mvec.push_back(new MachineInstr(XOR)); Add3OperandInstr(XOR, subtreeRoot, mvec);
Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break; break;
case 140: // bool: Xor(bool, not) case 140: // bool: Xor(bool, not)
@ -1854,10 +1786,17 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// a separate instruction to compute the bool result, so discard // a separate instruction to compute the bool result, so discard
// result of SUBcc instruction anyway. // result of SUBcc instruction anyway.
// //
M = new MachineInstr(SUBcc); if (keepSubVal) {
Set3OperandsFromInstr(M, subtreeRoot, target, ! keepSubVal); M = BuildMI(SUBcc, 4).addReg(subtreeRoot->leftChild()->getValue())
M->SetMachineOperandVal(3, MachineOperand::MO_CCRegister, .addReg(subtreeRoot->rightChild()->getValue())
tmpForCC, /*def*/true); .addRegDef(subtreeRoot->getValue())
.addCCReg(tmpForCC, MOTy::Def);
} else {
M = BuildMI(SUBcc, 4).addReg(subtreeRoot->leftChild()->getValue())
.addReg(subtreeRoot->rightChild()->getValue())
.addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def)
.addCCReg(tmpForCC, MOTy::Def);
}
mvec.push_back(M); mvec.push_back(M);
if (computeBoolVal) if (computeBoolVal)
@ -1869,13 +1808,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
else else
{ {
// FP condition: dest of FCMP should be some FCCn register // FP condition: dest of FCMP should be some FCCn register
M = new MachineInstr(ChooseFcmpInstruction(subtreeRoot)); M = BuildMI(ChooseFcmpInstruction(subtreeRoot), 3)
M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister, .addCCReg(tmpForCC, MOTy::Def)
tmpForCC); .addReg(subtreeRoot->leftChild()->getValue())
M->SetMachineOperandVal(1,MachineOperand::MO_VirtualRegister, .addRegDef(subtreeRoot->rightChild()->getValue());
subtreeRoot->leftChild()->getValue());
M->SetMachineOperandVal(2,MachineOperand::MO_VirtualRegister,
subtreeRoot->rightChild()->getValue());
mvec.push_back(M); mvec.push_back(M);
if (computeBoolVal) if (computeBoolVal)
@ -1890,25 +1826,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ {
if (mustClearReg) if (mustClearReg)
{// Unconditionally set register to 0 {// Unconditionally set register to 0
M = new MachineInstr(SETHI); M = BuildMI(SETHI, 2).addZImm(0).addRegDef(setCCInstr);
M->SetMachineOperandConst(0,MachineOperand::MO_UnextendedImmed,
(int64_t)0);
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
setCCInstr);
mvec.push_back(M); mvec.push_back(M);
} }
// Now conditionally move `valueToMove' (0 or 1) into the register // Now conditionally move `valueToMove' (0 or 1) into the register
// Mark the register as a use (as well as a def) because the old // Mark the register as a use (as well as a def) because the old
// value should be retained if the condition is false. // value should be retained if the condition is false.
M = new MachineInstr(movOpCode); M = BuildMI(movOpCode, 3).addCCReg(tmpForCC).addZImm(valueToMove)
M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister, .addReg(setCCInstr, MOTy::UseAndDef);
tmpForCC);
M->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
valueToMove);
M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
setCCInstr, /*isDef*/ true,
/*isDefAndUse*/ true);
mvec.push_back(M); mvec.push_back(M);
} }
break; break;
@ -1916,17 +1842,16 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 51: // reg: Load(reg) case 51: // reg: Load(reg)
case 52: // reg: Load(ptrreg) case 52: // reg: Load(ptrreg)
mvec.push_back(new MachineInstr(ChooseLoadInstruction( SetOperandsForMemInstr(ChooseLoadInstruction(
subtreeRoot->getValue()->getType()))); subtreeRoot->getValue()->getType()),
SetOperandsForMemInstr(mvec, subtreeRoot, target); mvec, subtreeRoot, target);
break; break;
case 55: // reg: GetElemPtr(reg) case 55: // reg: GetElemPtr(reg)
case 56: // reg: GetElemPtrIdx(reg,reg) case 56: // reg: GetElemPtrIdx(reg,reg)
// If the GetElemPtr was folded into the user (parent), it will be // If the GetElemPtr was folded into the user (parent), it will be
// caught above. For other cases, we have to compute the address. // caught above. For other cases, we have to compute the address.
mvec.push_back(new MachineInstr(ADD)); SetOperandsForMemInstr(ADD, mvec, subtreeRoot, target);
SetOperandsForMemInstr(mvec, subtreeRoot, target);
break; break;
case 57: // reg: Alloca: Implement as 1 instruction: case 57: // reg: Alloca: Implement as 1 instruction:
@ -2069,7 +1994,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
mvec.back()->addImplicitRef(retAddrReg, /*isDef*/ true); mvec.back()->addImplicitRef(retAddrReg, /*isDef*/ true);
// delay slot // delay slot
mvec.push_back(new MachineInstr(NOP)); mvec.push_back(BuildMI(NOP, 0));
break; break;
} }
@ -2094,10 +2019,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ const Type* opType = subtreeRoot->leftChild()->getValue()->getType(); { const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
assert((opType->isInteger() || isa<PointerType>(opType)) && assert((opType->isInteger() || isa<PointerType>(opType)) &&
"Shr unsupported for other types"); "Shr unsupported for other types");
mvec.push_back(new MachineInstr((opType->isSigned() Add3OperandInstr(opType->isSigned()
? ((opType == Type::LongTy)? SRAX : SRA) ? (opType == Type::LongTy ? SRAX : SRA)
: ((opType == Type::LongTy)? SRLX : SRL)))); : (opType == Type::LongTy ? SRLX : SRL),
Set3OperandsFromInstr(mvec.back(), subtreeRoot, target); subtreeRoot, mvec);
break; break;
} }