aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/SparcV9/SparcV9InstrSelection.cpp
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2002-03-18 03:15:35 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2002-03-18 03:15:35 +0000
commit7482532129d8f181f4d826a7362d500310db32b0 (patch)
treecdfdfd8da3809a8b40eb7b62d9b7901f0f11608e /lib/Target/SparcV9/SparcV9InstrSelection.cpp
parentf1c15ee4d15c3632343fccb723cce6f1d35bb5ba (diff)
downloadexternal_llvm-7482532129d8f181f4d826a7362d500310db32b0.zip
external_llvm-7482532129d8f181f4d826a7362d500310db32b0.tar.gz
external_llvm-7482532129d8f181f4d826a7362d500310db32b0.tar.bz2
Add support for code generation for array references.
Also, use distinct names for the three types of SetMachineOperand to avoid painful overloading problems and errors. Bug fix in converting-int-to-float. Other minor stuff. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1896 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SparcV9/SparcV9InstrSelection.cpp')
-rw-r--r--lib/Target/SparcV9/SparcV9InstrSelection.cpp1088
1 files changed, 607 insertions, 481 deletions
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
index 0599359..e3764ec 100644
--- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
@@ -12,6 +12,7 @@
#include "SparcInternals.h"
#include "SparcInstrSelectionSupport.h"
+#include "SparcRegClassInfo.h"
#include "llvm/CodeGen/InstrSelectionSupport.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/InstrForest.h"
@@ -32,10 +33,10 @@ using std::vector;
//************************* Forward Declarations ***************************/
-static void SetMemOperands_Internal (MachineInstr* minstr,
+static void SetMemOperands_Internal (vector<MachineInstr*>& mvec,
+ vector<MachineInstr*>::iterator mvecI,
const InstructionNode* vmInstrNode,
Value* ptrVal,
- Value* arrayOffsetVal,
const std::vector<Value*>& idxVec,
const TargetMachine& target);
@@ -259,12 +260,12 @@ ChooseConvertToFloatInstr(const InstructionNode* instrNode,
break;
case ToDoubleTy:
- // Use FXTOD for all integer-to-double conversions. This has to be
- // consistent with the code in CreateCodeToCopyIntToFloat() since
- // that will be used to load the integer into an FP register.
- //
- if (opType == Type::SByteTy || opType == Type::ShortTy ||
- opType == Type::IntTy || opType == Type::LongTy)
+ // This is usually used in conjunction with CreateCodeToCopyIntToFloat().
+ // Both functions should treat the integer as a 32-bit value for types
+ // of 4 bytes or less, and as a 64-bit value otherwise.
+ if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
+ opCode = FITOD;
+ else if (opType == Type::LongTy)
opCode = FXTOD;
else if (opType == Type::FloatTy)
opCode = FSTOD;
@@ -356,10 +357,10 @@ CreateMovFloatInstruction(const InstructionNode* instrNode,
{
MachineInstr* minstr = new MachineInstr((resultType == Type::FloatTy)
? FMOVS : FMOVD);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- instrNode->getValue());
+ minstr->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ instrNode->leftChild()->getValue());
+ minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ instrNode->getValue());
return minstr;
}
@@ -490,46 +491,38 @@ ChooseMulInstructionByType(const Type* resultType)
}
-static inline MachineOpCode
-ChooseMulInstruction(const InstructionNode* instrNode,
- bool checkCasts)
-{
- if (checkCasts && BothFloatToDouble(instrNode))
- return FSMULD;
-
- // else use the regular multiply instructions
- return ChooseMulInstructionByType(instrNode->getInstruction()->getType());
-}
-
static inline MachineInstr*
-CreateIntNegInstruction(TargetMachine& target,
+CreateIntNegInstruction(const TargetMachine& target,
Value* vreg)
{
MachineInstr* minstr = new MachineInstr(SUB);
- minstr->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
- minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, vreg);
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, vreg);
+ minstr->SetMachineOperandReg(0, target.getRegInfo().getZeroRegNum());
+ minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, vreg);
+ minstr->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, vreg);
return minstr;
}
-static inline MachineInstr*
-CreateMulConstInstruction(TargetMachine &target,
- const InstructionNode* instrNode,
- MachineInstr*& getMinstr2)
+// Does not create any instructions if we cannot exploit constant to
+// create a cheaper instruction
+static inline void
+CreateMulConstInstruction(const TargetMachine &target,
+ Value* lval, Value* rval, Value* destVal,
+ vector<MachineInstr*>& mvec)
{
- MachineInstr* minstr = NULL; // return NULL if we cannot exploit constant
- getMinstr2 = NULL; // to create a cheaper instruction
-
- Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
- assert(isa<Constant>(constOp));
+ MachineInstr* minstr1 = NULL;
+ MachineInstr* minstr2 = NULL;
+
+ Value* constOp = rval;
+ if (! isa<Constant>(constOp))
+ return;
// Cases worth optimizing are:
// (1) Multiply by 0 or 1 for any type: replace with copy (ADD or FMOV)
// (2) Multiply by 2^x for integer types: replace with Shift
//
- const Type* resultType = instrNode->getInstruction()->getType();
+ const Type* resultType = destVal->getType();
if (resultType->isIntegral() || resultType->isPointerType())
{
@@ -547,30 +540,29 @@ CreateMulConstInstruction(TargetMachine &target,
if (C == 0 || C == 1)
{
- minstr = new MachineInstr(ADD);
+ minstr1 = new MachineInstr(ADD);
if (C == 0)
- minstr->SetMachineOperand(0,
+ minstr1->SetMachineOperandReg(0,
target.getRegInfo().getZeroRegNum());
else
- minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1,target.getRegInfo().getZeroRegNum());
+ minstr1->SetMachineOperandVal(0,MachineOperand::MO_VirtualRegister,
+ lval);
+ minstr1->SetMachineOperandReg(1,target.getRegInfo().getZeroRegNum());
}
else if (IsPowerOf2(C, pow))
{
- minstr = new MachineInstr((resultType == Type::LongTy)
+ minstr1 = new MachineInstr((resultType == Type::LongTy)
? SLLX : SLL);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
- pow);
+ minstr1->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ lval);
+ minstr1->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
+ pow);
}
- if (minstr && needNeg)
+ if (minstr1 && needNeg)
{ // insert <reg = SUB 0, reg> after the instr to flip the sign
- getMinstr2 = CreateIntNegInstruction(target,
- instrNode->getValue());
+ minstr2 = CreateIntNegInstruction(target, destVal);
}
}
}
@@ -588,19 +580,47 @@ CreateMulConstInstruction(TargetMachine &target,
? (resultType == Type::FloatTy? FNEGS : FNEGD)
: (resultType == Type::FloatTy? FMOVS : FMOVD);
- minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0,
- MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
+ minstr1 = new MachineInstr(opCode);
+ minstr1->SetMachineOperandVal(0,
+ MachineOperand::MO_VirtualRegister,
+ lval);
}
}
}
- if (minstr != NULL)
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- instrNode->getValue());
+ if (minstr1 != NULL)
+ minstr1->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ destVal);
- return minstr;
+ if (minstr1)
+ mvec.push_back(minstr1);
+ if (minstr2)
+ mvec.push_back(minstr2);
+}
+
+
+// Return NULL if we cannot exploit constant to create a cheaper instruction
+static inline void
+CreateMulInstruction(const TargetMachine &target,
+ Value* lval, Value* rval, Value* destVal,
+ vector<MachineInstr*>& mvec,
+ MachineOpCode forceMulOp = INVALID_MACHINE_OPCODE)
+{
+ unsigned int L = mvec.size();
+ CreateMulConstInstruction(target, lval, rval, destVal, mvec);
+ if (mvec.size() == L)
+ { // no instructions were added so create MUL reg, reg, reg.
+ // Use FSMULD if both operands are actually floats cast to doubles.
+ // Otherwise, use the default opcode for the appropriate type.
+ MachineOpCode mulOp = ((forceMulOp != INVALID_MACHINE_OPCODE)
+ ? forceMulOp
+ : ChooseMulInstructionByType(destVal->getType()));
+ MachineInstr* M = new MachineInstr(mulOp);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, lval);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, rval);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, destVal);
+ mvec.push_back(M);
+ }
}
@@ -630,16 +650,18 @@ ChooseDivInstruction(TargetMachine &target,
}
-static inline MachineInstr*
+// Return NULL if we cannot exploit constant to create a cheaper instruction
+static inline void
CreateDivConstInstruction(TargetMachine &target,
const InstructionNode* instrNode,
- MachineInstr*& getMinstr2)
+ vector<MachineInstr*>& mvec)
{
- MachineInstr* minstr = NULL;
- getMinstr2 = NULL;
+ MachineInstr* minstr1 = NULL;
+ MachineInstr* minstr2 = NULL;
Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
- assert(isa<Constant>(constOp));
+ if (! isa<Constant>(constOp))
+ return;
// Cases worth optimizing are:
// (1) Divide by 1 for any type: replace with copy (ADD or FMOV)
@@ -663,26 +685,26 @@ CreateDivConstInstruction(TargetMachine &target,
if (C == 1)
{
- minstr = new MachineInstr(ADD);
- minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
+ minstr1 = new MachineInstr(ADD);
+ minstr1->SetMachineOperandVal(0,MachineOperand::MO_VirtualRegister,
instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1,target.getRegInfo().getZeroRegNum());
+ minstr1->SetMachineOperandReg(1,target.getRegInfo().getZeroRegNum());
}
else if (IsPowerOf2(C, pow))
{
MachineOpCode opCode= ((resultType->isSigned())
? (resultType==Type::LongTy)? SRAX : SRA
: (resultType==Type::LongTy)? SRLX : SRL);
- minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ minstr1 = new MachineInstr(opCode);
+ minstr1->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
+ minstr1->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
pow);
}
- if (minstr && needNeg)
+ if (minstr1 && needNeg)
{ // insert <reg = SUB 0, reg> after the instr to flip the sign
- getMinstr2 = CreateIntNegInstruction(target,
+ minstr2 = CreateIntNegInstruction(target,
instrNode->getValue());
}
}
@@ -701,21 +723,116 @@ CreateDivConstInstruction(TargetMachine &target,
? (resultType == Type::FloatTy? FNEGS : FNEGD)
: (resultType == Type::FloatTy? FMOVS : FMOVD);
- minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ minstr1 = new MachineInstr(opCode);
+ minstr1->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
instrNode->leftChild()->getValue());
}
}
}
- if (minstr != NULL)
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- instrNode->getValue());
+ if (minstr1 != NULL)
+ minstr1->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ instrNode->getValue());
- return minstr;
+ if (minstr1)
+ mvec.push_back(minstr1);
+ if (minstr2)
+ mvec.push_back(minstr2);
+}
+
+
+static void
+CreateCodeForVariableSizeAlloca(const TargetMachine& target,
+ Instruction* result,
+ unsigned int tsize,
+ Value* numElementsVal,
+ vector<MachineInstr*>& getMvec)
+{
+ MachineInstr* M;
+
+ // Create a Value to hold the (constant) element size
+ Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
+
+ // Get the constant offset from SP for dynamically allocated storage
+ // and create a temporary Value to hold it.
+ assert(result && result->getParent() && "Result value is not part of a method?");
+ Method* method = result->getParent()->getParent();
+ MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
+ bool growUp;
+ ConstantSInt* dynamicAreaOffset =
+ ConstantSInt::get(Type::IntTy,
+ target.getFrameInfo().getDynamicAreaOffset(mcInfo,growUp));
+ assert(! growUp && "Has SPARC v9 stack frame convention changed?");
+
+ // Create a temporary value to hold the result of MUL
+ TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal);
+ MachineCodeForInstruction::get(result).addTemp(tmpProd);
+
+ // Instruction 1: mul numElements, typeSize -> tmpProd
+ M = new MachineInstr(MULX);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, numElementsVal);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tsizeVal);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, tmpProd);
+ getMvec.push_back(M);
+
+ // Instruction 2: sub %sp, tmpProd -> %sp
+ M = new MachineInstr(SUB);
+ M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpProd);
+ M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
+ getMvec.push_back(M);
+
+ // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
+ M = new MachineInstr(ADD);
+ M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, dynamicAreaOffset);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, result);
+ getMvec.push_back(M);
+}
+
+
+static void
+CreateCodeForFixedSizeAlloca(const TargetMachine& target,
+ Instruction* result,
+ unsigned int tsize,
+ unsigned int numElements,
+ vector<MachineInstr*>& getMvec)
+{
+ assert(result && result->getParent() && "Result value is not part of a method?");
+ Method* method = result->getParent()->getParent();
+ MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
+
+ // Check if the offset would small enough to use as an immediate in load/stores
+ // (check LDX because all load/stores have the same-size immediate field).
+ // If not, put the variable in the dynamically sized area of the frame.
+ int offsetFromFP = mcInfo.computeOffsetforLocalVar(target, result,
+ tsize * numElements);
+ if (! target.getInstrInfo().constantFitsInImmedField(LDX, offsetFromFP))
+ {
+ CreateCodeForVariableSizeAlloca(target, result, tsize,
+ ConstantSInt::get(Type::IntTy,numElements),
+ getMvec);
+ return;
+ }
+
+ // else offset fits in immediate field so go ahead and allocate it.
+ offsetFromFP = mcInfo.allocateLocalVar(target, result, tsize * numElements);
+
+ // Create a temporary Value to hold the constant offset.
+ // This is needed because it may not fit in the immediate field.
+ ConstantSInt* offsetVal = ConstantSInt::get(Type::IntTy, offsetFromFP);
+
+ // Instruction 1: add %fp, offsetFromFP -> result
+ MachineInstr* M = new MachineInstr(ADD);
+ M->SetMachineOperandReg(0, target.getRegInfo().getFramePointer());
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, offsetVal);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, result);
+
+ getMvec.push_back(M);
}
+
//------------------------------------------------------------------------
// Function SetOperandsForMemInstr
//
@@ -733,7 +850,8 @@ CreateDivConstInstruction(TargetMachine &target,
//------------------------------------------------------------------------
static void
-SetOperandsForMemInstr(MachineInstr* minstr,
+SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
+ vector<MachineInstr*>::iterator mvecI,
const InstructionNode* vmInstrNode,
const TargetMachine& target)
{
@@ -744,8 +862,7 @@ SetOperandsForMemInstr(MachineInstr* minstr,
// and then call the common function SetMemOperands_Internal().
//
vector<Value*> idxVec;
- Value* ptrVal;
- Value* arrayOffsetVal = NULL;
+ Value* ptrVal = memInst->getPointerOperand();
// Test if a GetElemPtr instruction is being folded into this mem instrn.
// If so, it will be in the left child for Load and GetElemPtr,
@@ -755,49 +872,39 @@ SetOperandsForMemInstr(MachineInstr* minstr,
? vmInstrNode->rightChild()
: vmInstrNode->leftChild());
- if (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
- ptrChild->getOpLabel() == GetElemPtrIdx)
+ // We can only fold a chain of GetElemPtr instructions for structure references
+ //
+ if (isa<StructType>(cast<PointerType>(ptrVal->getType())->getElementType())
+ && (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
+ ptrChild->getOpLabel() == GetElemPtrIdx))
{
// There is a GetElemPtr instruction and there may be a chain of
// more than one. Use the pointer value of the last one in the chain.
// Fold the index vectors from the entire chain and from the mem
// instruction into one single index vector.
- // Finally, we never fold for an array instruction so make that NULL.
-
- ptrVal = FoldGetElemChain((InstructionNode*) ptrChild, idxVec);
- idxVec.insert(idxVec.end(), memInst->idx_begin(), memInst->idx_end());
- assert(!((PointerType*)ptrVal->getType())->getElementType()->isArrayType()
- && "GetElemPtr cannot be folded into array refs in selection");
- }
- else
- {
- // There is no GetElemPtr instruction.
- // Use the pointer value and the index vector from the Mem instruction.
- // If it is an array reference, check that it has been lowered to
- // at most a single offset, then get the array offset value.
//
- ptrVal = memInst->getPointerOperand();
+ ptrVal = FoldGetElemChain((InstructionNode*) ptrChild, idxVec);
- const Type* opType = cast<PointerType>(ptrVal->getType())->getElementType();
- if (opType->isArrayType())
- {
- assert((memInst->getNumOperands()
- == (unsigned) 1 + memInst->getFirstIndexOperandNumber())
- && "Array refs must be lowered before Instruction Selection");
- arrayOffsetVal = * memInst->idx_begin();
- }
+ assert (! cast<PointerType>(ptrVal->getType())->getElementType()->isArrayType()
+ && "GetElemPtr cannot be folded into array refs in selection");
}
- SetMemOperands_Internal(minstr, vmInstrNode, ptrVal, arrayOffsetVal,
- idxVec, target);
+ // Append the index vector of this instruction (may be none) to the indexes
+ // folded in previous getElementPtr's (may be none)
+ idxVec.insert(idxVec.end(), memInst->idx_begin(), memInst->idx_end());
+
+ SetMemOperands_Internal(mvec, mvecI, vmInstrNode, ptrVal, idxVec, target);
}
+// Generate the correct operands (and additional instructions if needed)
+// for the given pointer and given index vector.
+//
static void
-SetMemOperands_Internal(MachineInstr* minstr,
+SetMemOperands_Internal(vector<MachineInstr*>& mvec,
+ vector<MachineInstr*>::iterator mvecI,
const InstructionNode* vmInstrNode,
Value* ptrVal,
- Value* arrayOffsetVal,
const vector<Value*>& idxVec,
const TargetMachine& target)
{
@@ -808,51 +915,70 @@ SetMemOperands_Internal(MachineInstr* minstr,
Value* valueForRegOffset = NULL;
MachineOperand::MachineOperandType offsetOpType =MachineOperand::MO_VirtualRegister;
- // Check if there is an index vector and if so, if it translates to
- // a small enough constant to fit in the immediate-offset field.
+ // Check if there is an index vector and if so, compute the
+ // right offset for structures and for arrays
//
if (idxVec.size() > 0)
{
- bool isConstantOffset = false;
unsigned offset = 0;
- const PointerType* ptrType = (PointerType*) ptrVal->getType();
+ const PointerType* ptrType = cast<PointerType>(ptrVal->getType());
if (ptrType->getElementType()->isStructType())
{
- // the offset is always constant for structs
- isConstantOffset = true;
-
- // Compute the offset value using the index vector
- offset = target.DataLayout.getIndexedOffset(ptrType, idxVec);
+ // Compute the offset value using the index vector,
+ // and create a virtual register for it.
+ unsigned offset = target.DataLayout.getIndexedOffset(ptrType,idxVec);
+ valueForRegOffset = ConstantSInt::get(Type::IntTy, offset);
}
else
{
- // It must be an array ref. Check if the offset is a constant,
- // and that the indexing has been lowered to a single offset.
- //
- assert(isa<SequentialType>(ptrType->getElementType()));
- assert(arrayOffsetVal != NULL
- && "Expect to be given Value* for array offsets");
+ // It must be an array ref. Check that the indexing has been
+ // lowered to a single offset.
+ assert((memInst->getNumOperands()
+ == (unsigned) 1 + memInst->getFirstIndexOperandNumber())
+ && "Array refs must be lowered before Instruction Selection");
- if (Constant *CPV = dyn_cast<Constant>(arrayOffsetVal))
- {
- isConstantOffset = true; // always constant for structs
- assert(arrayOffsetVal->getType()->isIntegral());
- offset = (CPV->getType()->isSigned()
- ? cast<ConstantSInt>(CPV)->getValue()
- : (int64_t) cast<ConstantUInt>(CPV)->getValue());
- }
- else
+ Value* arrayOffsetVal = * memInst->idx_begin();
+
+ // Generate a MUL instruction to compute address from index
+ // The call to getTypeSize() will fail if size is not constant
+ vector<MachineInstr*> mulVec;
+ Instruction* addr = new TmpInstruction(Type::UIntTy, memInst);
+ MachineCodeForInstruction::get(memInst).addTemp(addr);
+ unsigned int eltSize =
+ target.DataLayout.getTypeSize(ptrType->getElementType());
+ assert(eltSize > 0 && "Invalid or non-constant array element size");
+ ConstantUInt* eltVal = ConstantUInt::get(Type::UIntTy, eltSize);
+
+ CreateMulInstruction(target,
+ arrayOffsetVal, /* lval, not likely constant */
+ eltVal, /* rval, likely constant */
+ addr, /* result*/
+ mulVec, INVALID_MACHINE_OPCODE);
+ assert(mulVec.size() > 0 && "No multiply instruction created?");
+ for (vector<MachineInstr*>::const_iterator I = mulVec.begin();
+ I != mulVec.end(); ++I)
{
- valueForRegOffset = arrayOffsetVal;
+ mvecI = mvec.insert(mvecI, *I); // get ptr to inserted value
+ ++mvecI; // get ptr to mem. instr.
}
- }
-
- if (isConstantOffset)
- {
- // create a virtual register for the constant
- valueForRegOffset = ConstantSInt::get(Type::IntTy, offset);
+
+ valueForRegOffset = addr;
+
+ // Check if the offset is a constant,
+ // if (Constant *CPV = dyn_cast<Constant>(arrayOffsetVal))
+ // {
+ // isConstantOffset = true; // always constant for structs
+ // assert(arrayOffsetVal->getType()->isIntegral());
+ // offset = (CPV->getType()->isSigned()
+ // ? cast<ConstantSInt>(CPV)->getValue()
+ // : (int64_t) cast<ConstantUInt>(CPV)->getValue());
+ // }
+ // else
+ // {
+ // valueForRegOffset = arrayOffsetVal;
+ // }
}
}
else
@@ -864,7 +990,8 @@ SetMemOperands_Internal(MachineInstr* minstr,
// Operand 0 is value for STORE, ptr for LOAD or GET_ELEMENT_PTR
// It is the left child in the instruction tree in all cases.
Value* leftVal = vmInstrNode->leftChild()->getValue();
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, leftVal);
+ (*mvecI)->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ leftVal);
// Operand 1 is ptr for STORE, offset for LOAD or GET_ELEMENT_PTR
// Operand 2 is offset for STORE, result reg for LOAD or GET_ELEMENT_PTR
@@ -873,16 +1000,19 @@ SetMemOperands_Internal(MachineInstr* minstr,
if (offsetOpType == MachineOperand::MO_VirtualRegister)
{
assert(valueForRegOffset != NULL);
- minstr->SetMachineOperand(offsetOpNum, offsetOpType, valueForRegOffset);
+ (*mvecI)->SetMachineOperandVal(offsetOpNum, offsetOpType,
+ valueForRegOffset);
}
else
- minstr->SetMachineOperand(offsetOpNum, offsetOpType, smallConstOffset);
+ (*mvecI)->SetMachineOperandConst(offsetOpNum, offsetOpType,
+ smallConstOffset);
if (memInst->getOpcode() == Instruction::Store)
- minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, ptrVal);
+ (*mvecI)->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ ptrVal);
else
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- vmInstrNode->getValue());
+ (*mvecI)->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ vmInstrNode->getValue());
}
@@ -890,6 +1020,9 @@ SetMemOperands_Internal(MachineInstr* minstr,
// Substitute operand `operandNum' of the instruction in node `treeNode'
// in place of the use(s) of that instruction in node `parent'.
// Check both explicit and implicit operands!
+// Also make sure to skip over a parent who:
+// (1) is a list node in the Burg tree, or
+// (2) itself had its results forwarded to its parent
//
static void
ForwardOperand(InstructionNode* treeNode,
@@ -911,31 +1044,50 @@ ForwardOperand(InstructionNode* treeNode,
Instruction* userInstr = parentInstrNode->getInstruction();
MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(userInstr);
- for (unsigned i=0, N=mvec.size(); i < N; i++)
+
+ // The parent's mvec would be empty if it was itself forwarded.
+ // Recursively call ForwardOperand in that case...
+ //
+ if (mvec.size() == 0)
{
- MachineInstr* minstr = mvec[i];
-
- for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i)
+ assert(parent->parent() != NULL &&
+ "Parent could not have been forwarded, yet has no instructions?");
+ ForwardOperand(treeNode, parent->parent(), operandNum);
+ }
+ else
+ {
+ bool fwdSuccessful = false;
+ for (unsigned i=0, N=mvec.size(); i < N; i++)
{
- const MachineOperand& mop = minstr->getOperand(i);
- if (mop.getOperandType() == MachineOperand::MO_VirtualRegister &&
- mop.getVRegValue() == unusedOp)
+ MachineInstr* minstr = mvec[i];
+ for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i)
{
- minstr->SetMachineOperand(i, MachineOperand::MO_VirtualRegister,
- fwdOp);
+ const MachineOperand& mop = minstr->getOperand(i);
+ if (mop.getOperandType() == MachineOperand::MO_VirtualRegister &&
+ mop.getVRegValue() == unusedOp)
+ {
+ minstr->SetMachineOperandVal(i,
+ MachineOperand::MO_VirtualRegister, fwdOp);
+ fwdSuccessful = true;
+ }
}
+
+ for (unsigned i=0,numOps=minstr->getNumImplicitRefs(); i<numOps; ++i)
+ if (minstr->getImplicitRef(i) == unusedOp)
+ {
+ minstr->setImplicitRef(i, fwdOp,
+ minstr->implicitRefIsDefined(i));
+ fwdSuccessful = true;
+ }
}
-
- for (unsigned i=0, numOps=minstr->getNumImplicitRefs(); i < numOps; ++i)
- if (minstr->getImplicitRef(i) == unusedOp)
- minstr->setImplicitRef(i, fwdOp, minstr->implicitRefIsDefined(i));
+ assert(fwdSuccessful && "Value to be forwarded is never used!");
}
}
-
void UltraSparcInstrInfo::
CreateCopyInstructionsByType(const TargetMachine& target,
+ Method* method,
Value* src,
Instruction* dest,
vector<MachineInstr*>& minstrVec) const
@@ -973,23 +1125,23 @@ CreateCopyInstructionsByType(const TargetMachine& target,
{ // `src' is constant and cannot fit in immed field for the ADD
// Insert instructions to "load" the constant into a register
vector<TmpInstruction*> tempVec;
- target.getInstrInfo().CreateCodeToLoadConst(src,dest,minstrVec,tempVec);
+ target.getInstrInfo().CreateCodeToLoadConst(method, src, dest,minstrVec,tempVec);
for (unsigned i=0; i < tempVec.size(); i++)
MachineCodeForInstruction::get(dest).addTemp(tempVec[i]);
}
else
- { // Create the appropriate add instruction.
+ { // Create an add-with-0 instruction of the appropriate type.
// Make `src' the second operand, in case it is a constant
// Use (unsigned long) 0 for a NULL pointer value.
//
- const Type* nullValueType =
+ const Type* zeroValueType =
(resultType->getPrimitiveID() == Type::PointerTyID)? Type::ULongTy
: resultType;
MachineInstr* minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- Constant::getNullConstant(nullValueType));
- minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, src);
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, dest);
+ minstr->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ Constant::getNullConstant(zeroValueType));
+ minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, src);
+ minstr->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,dest);
minstrVec.push_back(minstr);
}
}
@@ -1012,12 +1164,15 @@ GetInstructionsForProlog(BasicBlock* entryBB,
TargetMachine &target,
MachineInstr** mvec)
{
+ MachineInstr* M;
const MachineFrameInfo& frameInfo = target.getFrameInfo();
+ unsigned int N = 0;
// The second operand is the stack size. If it does not fit in the
- // immediate field, we either have to find an unused register in the
- // caller's window or move some elements to the dynamically allocated
- // area of the stack frame (just above save area and method args).
+ // immediate field, we have to use a free register to hold the size.
+ // We will assume that local register `l0' is unused since the SAVE
+ // instruction must be the first instruction in each procedure.
+ //
Method* method = entryBB->getParent();
MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
unsigned int staticStackSize = mcInfo.getStaticStackSize();
@@ -1029,16 +1184,37 @@ GetInstructionsForProlog(BasicBlock* entryBB,
(unsigned) frameInfo.getStackFrameSizeAlignment()))
staticStackSize += frameInfo.getStackFrameSizeAlignment() - padsz;
- assert(target.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize)
- && "Stack size too large for immediate field of SAVE instruction. Need additional work as described in the comment above");
-
- mvec[0] = new MachineInstr(SAVE);
- mvec[0]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
- - (int) staticStackSize);
- mvec[0]->SetMachineOperand(2, target.getRegInfo().getStackPointer());
+ if (target.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize))
+ {
+ M = new MachineInstr(SAVE);
+ M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+ M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
+ - (int) staticStackSize);
+ M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
+ mvec[N++] = M;
+ }
+ else
+ {
+ M = new MachineInstr(SETSW);
+ M->SetMachineOperandReg(0, MachineOperand::MO_SignExtendedImmed,
+ - staticStackSize);
+ M->SetMachineOperandReg(1, MachineOperand::MO_MachineRegister,
+ target.getRegInfo().getUnifiedRegNum(
+ target.getRegInfo().getRegClassIDOfType(Type::IntTy),
+ SparcIntRegOrder::l0));
+ mvec[N++] = M;
+
+ M = new MachineInstr(SAVE);
+ M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+ M->SetMachineOperandReg(1, MachineOperand::MO_MachineRegister,
+ target.getRegInfo().getUnifiedRegNum(
+ target.getRegInfo().getRegClassIDOfType(Type::IntTy),
+ SparcIntRegOrder::l0));
+ M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
+ mvec[N++] = M;
+ }
- return 1;
+ return N;
}
@@ -1048,10 +1224,10 @@ GetInstructionsForEpilog(BasicBlock* anExitBB,
MachineInstr** mvec)
{
mvec[0] = new MachineInstr(RESTORE);
- mvec[0]->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
+ mvec[0]->SetMachineOperandReg(0, target.getRegInfo().getZeroRegNum());
+ mvec[0]->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
(int64_t)0);
- mvec[0]->SetMachineOperand(2, target.getRegInfo().getZeroRegNum());
+ mvec[0]->SetMachineOperandReg(2, target.getRegInfo().getZeroRegNum());
return 1;
}
@@ -1105,20 +1281,21 @@ ThisIsAChainRule(int eruleno)
// patterns chosen by the BURG-generated parser.
//------------------------------------------------------------------------
-unsigned
+void
GetInstructionsByRule(InstructionNode* subtreeRoot,
int ruleForNode,
short* nts,
TargetMachine &target,
- MachineInstr** mvec)
+ vector<MachineInstr*>& mvec)
{
- int numInstr = 1; // initialize for common case
bool checkCast = false; // initialize here to use fall-through
int nextRule;
int forwardOperandNum = -1;
-
- for (unsigned i=0; i < MAX_INSTR_PER_VMINSTR; i++)
- mvec[i] = NULL;
+ unsigned int allocaSize = 0;
+ MachineInstr* M, *M2;
+ unsigned int L;
+
+ mvec.clear();
//
// Let's check for chain rules outside the switch so that we don't have
@@ -1133,7 +1310,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
&& "A chain rule should have only one RHS non-terminal!");
nextRule = burm_rule(subtreeRoot->state, nts[0]);
nts = burm_nts[nextRule];
- numInstr = GetInstructionsByRule(subtreeRoot, nextRule, nts,target,mvec);
+ GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec);
}
else
{
@@ -1153,39 +1330,40 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
Instruction* returnReg = new TmpInstruction(returnInstr);
MachineCodeForInstruction::get(returnInstr).addTemp(returnReg);
- mvec[0] = new MachineInstr(JMPLRET);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ M = new MachineInstr(JMPLRET);
+ M->SetMachineOperandReg(0, MachineOperand::MO_VirtualRegister,
returnReg);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
+ M->SetMachineOperandConst(1,MachineOperand::MO_SignExtendedImmed,
(int64_t)8);
- mvec[0]->SetMachineOperand(2, target.getRegInfo().getZeroRegNum());
+ M->SetMachineOperandReg(2, target.getRegInfo().getZeroRegNum());
if (returnInstr->getReturnValue() != NULL)
- mvec[0]->addImplicitRef(returnInstr->getReturnValue());
+ M->addImplicitRef(returnInstr->getReturnValue());
- unsigned n = numInstr++; // delay slot
- mvec[n] = new MachineInstr(NOP);
+ mvec.push_back(M);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
case 3: // stmt: Store(reg,reg)
case 4: // stmt: Store(reg,ptrreg)
- mvec[0] = new MachineInstr(
- ChooseStoreInstruction(
- subtreeRoot->leftChild()->getValue()->getType()));
- SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(
+ ChooseStoreInstruction(
+ subtreeRoot->leftChild()->getValue()->getType())));
+ SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target);
break;
case 5: // stmt: BrUncond
- mvec[0] = new MachineInstr(BA);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
(Value*)NULL);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(0));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
case 206: // stmt: BrCond(setCCconst)
@@ -1209,25 +1387,26 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// That constant is a zero after all...
// Use the left child of setCC as the first argument!
- mvec[0] = new MachineInstr(ChooseBprInstruction(subtreeRoot));
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ M = new MachineInstr(ChooseBprInstruction(subtreeRoot));
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
subtreeRoot->leftChild()->leftChild()->getValue());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
- brInst->getSuccessor(0));
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+ brInst->getSuccessor(0));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
// false branch
- int n = numInstr++;
- mvec[n] = new MachineInstr(BA);
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- (Value*) NULL);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ (Value*) NULL);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
brInst->getSuccessor(1));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
@@ -1244,30 +1423,30 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
//
BranchInst* brInst = cast<BranchInst>(subtreeRoot->getInstruction());
bool isFPBranch;
- mvec[0] = new MachineInstr(ChooseBccInstruction(subtreeRoot,
- isFPBranch));
+ M = new MachineInstr(ChooseBccInstruction(subtreeRoot, isFPBranch));
Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(),
brInst->getParent()->getParent(),
isFPBranch? Type::FloatTy : Type::IntTy);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister, ccValue);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
- brInst->getSuccessor(0));
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister, ccValue);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+ brInst->getSuccessor(0));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
// false branch
- int n = numInstr++;
- mvec[n] = new MachineInstr(BA);
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- (Value*) NULL);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
- brInst->getSuccessor(1));
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ (Value*) NULL);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+ brInst->getSuccessor(1));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
@@ -1278,14 +1457,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
cast<Constant>(subtreeRoot->leftChild()->getValue());
unsigned dest = cast<ConstantBool>(constVal)->getValue()? 0 : 1;
- mvec[0] = new MachineInstr(BA);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- (Value*) NULL);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ (Value*) NULL);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(dest));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
@@ -1293,31 +1473,31 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ // boolreg => boolean is stored in an existing register.
// Just use the branch-on-integer-register instruction!
//
- mvec[0] = new MachineInstr(BRNZ);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ M = new MachineInstr(BRNZ);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
subtreeRoot->leftChild()->getValue());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP); // delay slot
+ mvec.push_back(new MachineInstr(NOP));
// false branch
- int n = numInstr++;
- mvec[n] = new MachineInstr(BA);
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- (Value*) NULL);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ (Value*) NULL);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
case 9: // stmt: Switch(reg)
assert(0 && "*** SWITCH instruction is not implemented yet.");
- numInstr = 0;
break;
case 10: // reg: VRegList(reg, reg)
@@ -1326,12 +1506,13 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 21: // bool: Not(bool): Both these are implemented as:
case 321: // reg: BNot(reg) : reg = reg XOR-NOT 0
- mvec[0] = new MachineInstr(XNOR);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- subtreeRoot->leftChild()->getValue());
- mvec[0]->SetMachineOperand(1, target.getRegInfo().getZeroRegNum());
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- subtreeRoot->getValue());
+ M = new MachineInstr(XNOR);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ subtreeRoot->leftChild()->getValue());
+ M->SetMachineOperandReg(1, target.getRegInfo().getZeroRegNum());
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ subtreeRoot->getValue());
+ mvec.push_back(M);
break;
case 322: // reg: ToBoolTy(bool):
@@ -1340,8 +1521,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
assert(opType->isIntegral() || opType->isPointerType()
|| opType == Type::BoolTy);
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
break;
}
@@ -1354,8 +1534,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
assert(opType->isIntegral() ||
opType->isPointerType() ||
opType == Type::BoolTy && "Cast is illegal for other types");
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
break;
}
@@ -1369,8 +1548,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|| opType->isPointerType()
|| opType == Type::BoolTy)
{
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
}
else
{
@@ -1412,15 +1590,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
MachineOpCode opCode=ChooseConvertToIntInstr(subtreeRoot, opType);
assert(opCode != INVALID_OPCODE && "Expected to need conversion!");
- mvec[0] = new MachineInstr(opCode);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- leftVal);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- destForCast);
-
- assert(numInstr == 1 && "Should be initialized to 1 at the top");
- for (unsigned i=0; i < minstrVec.size(); ++i)
- mvec[numInstr++] = minstrVec[i];
+ M = new MachineInstr(opCode);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ leftVal);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ destForCast);
+ mvec.push_back(M);
+
+ // Append the copy code, if any, after the conversion instr.
+ mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
}
break;
}
@@ -1438,8 +1616,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
if (subtreeRoot->parent() != NULL &&
MachineCodeForInstruction::get(((InstructionNode*)subtreeRoot->parent())->getInstruction())[0]->getOpCode() == FSMULD)
{
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
}
else
{
@@ -1448,8 +1625,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
MachineOpCode opCode=ChooseConvertToFloatInstr(subtreeRoot,opType);
if (opCode == INVALID_OPCODE) // no conversion needed
{
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
}
else
{
@@ -1482,53 +1658,56 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
leftVal, (TmpInstruction*) srcForCast,
minstrVec, tempVec, target);
- for (unsigned i=0; i < minstrVec.size(); ++i)
- mvec[n++] = minstrVec[i];
-
+ mvec.insert(mvec.end(), minstrVec.begin(),minstrVec.end());
+
for (unsigned i=0; i < tempVec.size(); ++i)
DestMCFI.addTemp(tempVec[i]);
}
else
srcForCast = leftVal;
- MachineInstr* castI = new MachineInstr(opCode);
- castI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- srcForCast);
- castI->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- dest);
- mvec[n++] = castI;
- numInstr = n;
+ M = new MachineInstr(opCode);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ srcForCast);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ dest);
+ mvec.push_back(M);
}
}
break;
case 19: // reg: ToArrayTy(reg):
case 20: // reg: ToPointerTy(reg):
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
break;
case 233: // reg: Add(reg, Constant)
- mvec[0] = CreateAddConstInstruction(subtreeRoot);
- if (mvec[0] != NULL)
- break;
+ M = CreateAddConstInstruction(subtreeRoot);
+ if (M != NULL)
+ {
+ mvec.push_back(M);
+ break;
+ }
// ELSE FALL THROUGH
-
+
case 33: // reg: Add(reg, reg)
- mvec[0] = new MachineInstr(ChooseAddInstruction(subtreeRoot));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ChooseAddInstruction(subtreeRoot)));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 234: // reg: Sub(reg, Constant)
- mvec[0] = CreateSubConstInstruction(subtreeRoot);
- if (mvec[0] != NULL)
- break;
+ M = CreateSubConstInstruction(subtreeRoot);
+ if (M != NULL)
+ {
+ mvec.push_back(M);
+ break;
+ }
// ELSE FALL THROUGH
-
+
case 34: // reg: Sub(reg, reg)
- mvec[0] = new MachineInstr(ChooseSubInstructionByType(
- subtreeRoot->getInstruction()->getType()));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ChooseSubInstructionByType(
+ subtreeRoot->getInstruction()->getType())));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 135: // reg: Mul(todouble, todouble)
@@ -1536,40 +1715,43 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// FALL THROUGH
case 35: // reg: Mul(reg, reg)
- mvec[0] =new MachineInstr(ChooseMulInstruction(subtreeRoot,checkCast));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ {
+ MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
+ ? FSMULD
+ : INVALID_MACHINE_OPCODE);
+ CreateMulInstruction(target,
+ subtreeRoot->leftChild()->getValue(),
+ subtreeRoot->rightChild()->getValue(),
+ subtreeRoot->getInstruction(),
+ mvec, forceOp);
break;
-
+ }
case 335: // reg: Mul(todouble, todoubleConst)
checkCast = true;
// FALL THROUGH
case 235: // reg: Mul(reg, Constant)
- mvec[0] = CreateMulConstInstruction(target, subtreeRoot, mvec[1]);
- if (mvec[0] == NULL)
- {
- mvec[0] = new MachineInstr(ChooseMulInstruction(subtreeRoot,
- checkCast));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
- }
- else
- if (mvec[1] != NULL)
- ++numInstr;
+ {
+ MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
+ ? FSMULD
+ : INVALID_MACHINE_OPCODE);
+ CreateMulInstruction(target,
+ subtreeRoot->leftChild()->getValue(),
+ subtreeRoot->rightChild()->getValue(),
+ subtreeRoot->getInstruction(),
+ mvec, forceOp);
break;
-
+ }
case 236: // reg: Div(reg, Constant)
- mvec[0] = CreateDivConstInstruction(target, subtreeRoot, mvec[1]);
- if (mvec[0] != NULL)
- {
- if (mvec[1] != NULL)
- ++numInstr;
- }
- else
+ L = mvec.size();
+ CreateDivConstInstruction(target, subtreeRoot, mvec);
+ if (mvec.size() > L)
+ break;
// ELSE FALL THROUGH
-
+
case 36: // reg: Div(reg, reg)
- mvec[0] = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ChooseDivInstruction(target, subtreeRoot)));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 37: // reg: Rem(reg, reg)
@@ -1585,23 +1767,24 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
subtreeRoot->rightChild()->getValue());
MachineCodeForInstruction::get(remInstr).addTemp(quot).addTemp(prod);
- mvec[0] = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,quot);
+ M = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
+ Set3OperandsFromInstr(M, subtreeRoot, target);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,quot);
+ mvec.push_back(M);
- int n = numInstr++;
- mvec[n] = new MachineInstr(ChooseMulInstructionByType(
+ M = new MachineInstr(ChooseMulInstructionByType(
subtreeRoot->getInstruction()->getType()));
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,quot);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,quot);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
subtreeRoot->rightChild()->getValue());
- mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,prod);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,prod);
+ mvec.push_back(M);
- n = numInstr++;
- mvec[n] = new MachineInstr(ChooseSubInstructionByType(
+ M = new MachineInstr(ChooseSubInstructionByType(
subtreeRoot->getInstruction()->getType()));
- Set3OperandsFromInstr(mvec[n], subtreeRoot, target);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,prod);
+ Set3OperandsFromInstr(M, subtreeRoot, target);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,prod);
+ mvec.push_back(M);
break;
}
@@ -1610,42 +1793,42 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 238: // bool: And(bool, boolconst)
case 338: // reg : BAnd(reg, reg)
case 538: // reg : BAnd(reg, Constant)
- mvec[0] = new MachineInstr(AND);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(AND));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 138: // bool: And(bool, not)
case 438: // bool: BAnd(bool, not)
- mvec[0] = new MachineInstr(ANDN);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ANDN));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 39: // bool: Or(bool, bool)
case 239: // bool: Or(bool, boolconst)
case 339: // reg : BOr(reg, reg)
case 539: // reg : BOr(reg, Constant)
- mvec[0] = new MachineInstr(ORN);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ORN));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 139: // bool: Or(bool, not)
case 439: // bool: BOr(bool, not)
- mvec[0] = new MachineInstr(ORN);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ORN));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 40: // bool: Xor(bool, bool)
case 240: // bool: Xor(bool, boolconst)
case 340: // reg : BXor(reg, reg)
case 540: // reg : BXor(reg, Constant)
- mvec[0] = new MachineInstr(XOR);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(XOR));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 140: // bool: Xor(bool, not)
case 440: // bool: BXor(bool, not)
- mvec[0] = new MachineInstr(XNOR);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(XNOR));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 41: // boolconst: SetCC(reg, Constant)
@@ -1672,8 +1855,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
(parentOpCode = minstrVec[0]->getOpCode()) >= BRZ &&
parentOpCode <= BRGEZ)
{
- numInstr = 0; // don't forward the operand!
- break;
+ break; // don't forward the operand!
}
}
// ELSE FALL THROUGH
@@ -1733,11 +1915,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// a separate instruction to compute the bool result, so discard
// result of SUBcc instruction anyway.
//
- mvec[0] = new MachineInstr(SUBcc);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target, ! keepSubVal);
-
- mvec[0]->SetMachineOperand(3, MachineOperand::MO_CCRegister,
- tmpForCC, /*def*/true);
+ M = new MachineInstr(SUBcc);
+ Set3OperandsFromInstr(M, subtreeRoot, target, ! keepSubVal);
+ M->SetMachineOperandVal(3, MachineOperand::MO_CCRegister,
+ tmpForCC, /*def*/true);
+ mvec.push_back(M);
if (computeBoolVal)
{ // recompute bool using the integer condition codes
@@ -1748,13 +1930,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
else
{
// FP condition: dest of FCMP should be some FCCn register
- mvec[0] = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
+ M = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
tmpForCC);
- mvec[0]->SetMachineOperand(1,MachineOperand::MO_VirtualRegister,
+ M->SetMachineOperandVal(1,MachineOperand::MO_VirtualRegister,
subtreeRoot->leftChild()->getValue());
- mvec[0]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,
+ M->SetMachineOperandVal(2,MachineOperand::MO_VirtualRegister,
subtreeRoot->rightChild()->getValue());
+ mvec.push_back(M);
if (computeBoolVal)
{// recompute bool using the FP condition codes
@@ -1768,39 +1951,38 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{
if (mustClearReg)
{// Unconditionally set register to 0
- int n = numInstr++;
- mvec[n] = new MachineInstr(SETHI);
- mvec[n]->SetMachineOperand(0,MachineOperand::MO_UnextendedImmed,
- (int64_t)0);
- mvec[n]->SetMachineOperand(1,MachineOperand::MO_VirtualRegister,
- setCCInstr);
+ M = new MachineInstr(SETHI);
+ M->SetMachineOperandConst(0,MachineOperand::MO_UnextendedImmed,
+ (int64_t)0);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ setCCInstr);
+ mvec.push_back(M);
}
// Now conditionally move `valueToMove' (0 or 1) into the register
- int n = numInstr++;
- mvec[n] = new MachineInstr(movOpCode);
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- tmpForCC);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
- valueToMove);
- mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- setCCInstr);
+ M = new MachineInstr(movOpCode);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ tmpForCC);
+ M->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
+ valueToMove);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ setCCInstr);
+ mvec.push_back(M);
}
break;
}
case 43: // boolreg: VReg
case 44: // boolreg: Constant
- numInstr = 0;
break;
case 51: // reg: Load(reg)
case 52: // reg: Load(ptrreg)
case 53: // reg: LoadIdx(reg,reg)
case 54: // reg: LoadIdx(ptrreg,reg)
- mvec[0] = new MachineInstr(ChooseLoadInstruction(
- subtreeRoot->getValue()->getType()));
- SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ChooseLoadInstruction(
+ subtreeRoot->getValue()->getType())));
+ SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target);
break;
case 55: // reg: GetElemPtr(reg)
@@ -1824,100 +2006,43 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
cast<PointerType>(getElemInst->getPointerOperand()->getType());
if (! ptrType->getElementType()->isArrayType())
{// we don't need a separate instr
- numInstr = 0; // don't forward operand!
- break;
+ break; // don't forward operand!
}
}
}
// else in all other cases we need to a separate ADD instruction
- mvec[0] = new MachineInstr(ADD);
- SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ADD));
+ SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target);
break;
case 57: // reg: Alloca: Implement as 1 instruction:
{ // add %fp, offsetFromFP -> result
- Instruction* instr = subtreeRoot->getInstruction();
- const PointerType* instrType = (const PointerType*) instr->getType();
- assert(instrType->isPointerType());
- int tsize = (int)
- target.findOptimalStorageSize(instrType->getElementType());
- assert(tsize != 0 && "Just to check when this can happen");
-
- Method* method = instr->getParent()->getParent();
- MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
- int offsetFromFP = mcInfo.allocateLocalVar(target, instr, (unsigned int) tsize);
-
- // Create a temporary Value to hold the constant offset.
- // This is needed because it may not fit in the immediate field.
- ConstantSInt* offsetVal = ConstantSInt::get(Type::IntTy, offsetFromFP);
-
- // Instruction 1: add %fp, offsetFromFP -> result
- mvec[0] = new MachineInstr(ADD);
- mvec[0]->SetMachineOperand(0, target.getRegInfo().getFramePointer());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- offsetVal);
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- instr);
+ AllocationInst* instr = cast<AllocationInst>(subtreeRoot->getInstruction());
+ unsigned int tsize =target.findOptimalStorageSize(instr->getAllocatedType());
+ assert(tsize != 0);
+ CreateCodeForFixedSizeAlloca(target, instr, tsize, 1, mvec);
break;
}
-
+
case 58: // reg: Alloca(reg): Implement as 3 instructions:
// mul num, typeSz -> tmp
// sub %sp, tmp -> %sp
{ // add %sp, frameSizeBelowDynamicArea -> result
- Instruction* instr = subtreeRoot->getInstruction();
- const PointerType* instrType = (const PointerType*) instr->getType();
- assert(instrType->isPointerType() &&
- instrType->getElementType()->isArrayType());
- const Type* eltType =
- ((ArrayType*) instrType->getElementType())->getElementType();
- int tsize = (int) target.findOptimalStorageSize(eltType);
-
- assert(tsize != 0 && "Just to check when this can happen");
-
- // Create a temporary Value to hold the constant type-size
- ConstantSInt* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
-
- // Create a temporary Value to hold the constant offset from SP
- Method* method = instr->getParent()->getParent();
- bool ignore; // we don't need this
- ConstantSInt* dynamicAreaOffset = ConstantSInt::get(Type::IntTy,
- target.getFrameInfo().getDynamicAreaOffset(MachineCodeForMethod::get(method),
- ignore));
+ AllocationInst* instr = cast<AllocationInst>(subtreeRoot->getInstruction());
+ const Type* eltType = instr->getAllocatedType();
- // Create a temporary value to hold `tmp'
- Instruction* tmpInstr = new TmpInstruction(
- subtreeRoot->leftChild()->getValue(),
- NULL /*could insert tsize here*/);
- MachineCodeForInstruction::get(subtreeRoot->getInstruction()).addTemp(tmpInstr);
-
- // Instruction 1: mul numElements, typeSize -> tmp
- mvec[0] = new MachineInstr(MULX);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- subtreeRoot->leftChild()->getValue());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- tsizeVal);
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- tmpInstr);
-
- // Instruction 2: sub %sp, tmp -> %sp
- numInstr++;
- mvec[1] = new MachineInstr(SUB);
- mvec[1]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
- mvec[1]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- tmpInstr);
- mvec[1]->SetMachineOperand(2, target.getRegInfo().getStackPointer());
-
- // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
- numInstr++;
- mvec[2] = new MachineInstr(ADD);
- mvec[2]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
- mvec[2]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- dynamicAreaOffset);
- mvec[2]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,instr);
+ // If the #elements is a constant, use simpler code for fixed-size allocas
+ int tsize = (int) target.findOptimalStorageSize(eltType);
+ if (isa<Constant>(instr->getArraySize()))
+ // total size is constant: generate code for fixed-size alloca
+ CreateCodeForFixedSizeAlloca(target, instr, tsize,
+ cast<ConstantUInt>(instr->getArraySize())->getValue(), mvec);
+ else // total size is not constant.
+ CreateCodeForVariableSizeAlloca(target, instr, tsize,
+ instr->getArraySize(), mvec);
break;
}
-
+
case 61: // reg: Call
{ // Generate a call-indirect (i.e., jmpl) for now to expose
// the potential need for registers. If an absolute address
@@ -1948,34 +2073,37 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
//
if (callee->getValueType() == Value::MethodVal)
{ // direct function call
- mvec[0] = new MachineInstr(CALL);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp,
- callee);
+ M = new MachineInstr(CALL);
+ M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp,
+ callee);
}
else
{ // indirect function call
- mvec[0] = new MachineInstr(JMPLCALL);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- callee);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
- (int64_t) 0);
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- retAddrReg);
+ M = new MachineInstr(JMPLCALL);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ callee);
+ M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
+ (int64_t) 0);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ retAddrReg);
}
+ mvec.push_back(M);
+
// Add the call operands and return value as implicit refs
for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i)
if (callInstr->getOperand(i) != callee)
- mvec[0]->addImplicitRef(callInstr->getOperand(i));
+ mvec.back()->addImplicitRef(callInstr->getOperand(i));
if (callInstr->getType() != Type::VoidTy)
- mvec[0]->addImplicitRef(callInstr, /*isDef*/ true);
+ mvec.back()->addImplicitRef(callInstr, /*isDef*/ true);
// For the CALL instruction, the ret. addr. reg. is also implicit
if (callee->getValueType() == Value::MethodVal)
- mvec[0]->addImplicitRef(retAddrReg, /*isDef*/ true);
+ mvec.back()->addImplicitRef(retAddrReg, /*isDef*/ true);
- mvec[numInstr++] = new MachineInstr(NOP); // delay slot
+ // delay slot
+ mvec.push_back(new MachineInstr(NOP));
break;
}
@@ -1984,8 +2112,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
assert(opType->isIntegral()
|| opType == Type::BoolTy
|| opType->isPointerType()&& "Shl unsupported for other types");
- mvec[0] = new MachineInstr((opType == Type::LongTy)? SLLX : SLL);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr((opType == Type::LongTy)? SLLX : SLL));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
}
@@ -1994,38 +2122,38 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
assert(opType->isIntegral()
|| opType == Type::BoolTy
|| opType->isPointerType() &&"Shr unsupported for other types");
- mvec[0] = new MachineInstr((opType->isSigned()
- ? ((opType == Type::LongTy)? SRAX : SRA)
- : ((opType == Type::LongTy)? SRLX : SRL)));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr((opType->isSigned()
+ ? ((opType == Type::LongTy)? SRAX : SRA)
+ : ((opType == Type::LongTy)? SRLX : SRL))));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
}
case 64: // reg: Phi(reg,reg)
- numInstr = 0; // don't forward the value
- break;
+ break; // don't forward the value
+
#undef NEED_PHI_MACHINE_INSTRS
#ifdef NEED_PHI_MACHINE_INSTRS
{ // This instruction has variable #operands, so resultPos is 0.
Instruction* phi = subtreeRoot->getInstruction();
- mvec[0] = new MachineInstr(PHI, 1 + phi->getNumOperands());
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ M = new MachineInstr(PHI, 1 + phi->getNumOperands());
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
subtreeRoot->getValue());
for (unsigned i=0, N=phi->getNumOperands(); i < N; i++)
- mvec[0]->SetMachineOperand(i+1, MachineOperand::MO_VirtualRegister,
- phi->getOperand(i));
+ M->SetMachineOperandVal(i+1, MachineOperand::MO_VirtualRegister,
+ phi->getOperand(i));
+ mvec.push_back(M);
break;
}
#endif // NEED_PHI_MACHINE_INSTRS
+
case 71: // reg: VReg
case 72: // reg: Constant
- numInstr = 0; // don't forward the value
- break;
+ break; // don't forward the value
default:
assert(0 && "Unrecognized BURG rule");
- numInstr = 0;
break;
}
}
@@ -2040,16 +2168,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
else
{
vector<MachineInstr*> minstrVec;
- target.getInstrInfo().CreateCopyInstructionsByType(target,
+ target.getInstrInfo().CreateCopyInstructionsByType(target,
+ subtreeRoot->getInstruction()->getParent()->getParent(),
subtreeRoot->getInstruction()->getOperand(forwardOperandNum),
subtreeRoot->getInstruction(), minstrVec);
assert(minstrVec.size() > 0);
- for (unsigned i=0; i < minstrVec.size(); ++i)
- mvec[numInstr++] = minstrVec[i];
+ mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
}
}
-
- return numInstr;
}