aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2001-10-01 00:12:53 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2001-10-01 00:12:53 +0000
commit4cecdd206ec0f2f9f24bb4149b31a383f90d7802 (patch)
treef7c3d570e57994c9dd42c18591ecead598d4179f
parent71939033dee310ad85d3ef10691b6588e4cd4fe5 (diff)
Several fixes:
(1) Avoid hard-coding some register numbers. (2) Fix some incorrect branch opcodes. (3) Don't try to move int register to float register! (4) If an operand being forwarded is a constant and it doesn't fit into the immed field of the copy machine instruction, then generate a load-constant instead of a copy. (5) Use (unsigned long) 0 for copying a pointer via "add 0, ptr -> ptr2". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@683 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/SparcV9/SparcV9InstrSelection.cpp2523
1 files changed, 1301 insertions, 1222 deletions
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
index ca46798100..e7cdbc0389 100644
--- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
@@ -4,6 +4,7 @@
// SparcInstrSelection.cpp
//
// Purpose:
+// BURS instruction selection for SPARC V9 architecture.
//
// History:
// 7/02/01 - Vikram Adve - Created
@@ -27,8 +28,8 @@
// to be used later
struct BranchPattern {
- bool flipCondition; // should the sense of the test be reversed
- BasicBlock* targetBB; // which basic block to branch to
+ bool flipCondition; // should the sense of the test be reversed
+ BasicBlock* targetBB; // which basic block to branch to
MachineInstr* extraBranch; // if neither branch is fall-through, then this
// BA must be inserted after the cond'l one
};
@@ -36,68 +37,12 @@ struct BranchPattern {
//************************* Forward Declarations ***************************/
-static MachineOpCode ChooseBprInstruction (const InstructionNode* instrNode);
-
-static MachineOpCode ChooseBccInstruction (const InstructionNode* instrNode,
- bool& isFPBranch);
-
-static MachineOpCode ChooseBpccInstruction (const InstructionNode* instrNode,
- const BinaryOperator* setCCInst);
-
-static MachineOpCode ChooseBFpccInstruction (const InstructionNode* instrNode,
- const BinaryOperator* setCCInst);
-
-static MachineOpCode ChooseMovFpccInstruction(const InstructionNode*);
-
-static MachineOpCode ChooseMovpccAfterSub (const InstructionNode* instrNode,
- bool& mustClearReg,
- int& valueToMove);
-
-static MachineOpCode ChooseConvertToFloatInstr(const InstructionNode*,
- const Type* opType);
-
-static MachineOpCode ChooseConvertToIntInstr(const InstructionNode* instrNode,
- const Type* opType);
-
-static MachineOpCode ChooseAddInstruction (const InstructionNode* instrNode);
-
-static MachineOpCode ChooseSubInstruction (const InstructionNode* instrNode);
-
-static MachineOpCode ChooseFcmpInstruction (const InstructionNode* instrNode);
-
-static MachineOpCode ChooseMulInstruction (const InstructionNode* instrNode,
- bool checkCasts);
-
-static MachineOpCode ChooseDivInstruction (const InstructionNode* instrNode);
-
-static MachineOpCode ChooseLoadInstruction (const Type* resultType);
-
-static MachineOpCode ChooseStoreInstruction (const Type* valueType);
-
-static void SetOperandsForMemInstr(MachineInstr* minstr,
- const InstructionNode* vmInstrNode,
- const TargetMachine& target);
-
-static void SetMemOperands_Internal (MachineInstr* minstr,
- const InstructionNode* vmInstrNode,
- Value* ptrVal,
- Value* arrayOffsetVal,
- const vector<ConstPoolVal*>& idxVec,
- const TargetMachine& target);
-
-static unsigned FixConstantOperands(const InstructionNode* vmInstrNode,
- MachineInstr** mvec,
- unsigned numInstr,
- TargetMachine& target);
-
-static MachineInstr* MakeLoadConstInstr(Instruction* vmInstr,
- Value* val,
- TmpInstruction*& tmpReg,
- MachineInstr*& getMinstr2);
-
-static void ForwardOperand (InstructionNode* treeNode,
- InstrTreeNode* parent,
- int operandNum);
+static void SetMemOperands_Internal (MachineInstr* minstr,
+ const InstructionNode* vmInstrNode,
+ Value* ptrVal,
+ Value* arrayOffsetVal,
+ const vector<ConstPoolVal*>& idxVec,
+ const TargetMachine& target);
//************************ Internal Functions ******************************/
@@ -105,31 +50,37 @@ static void ForwardOperand (InstructionNode* treeNode,
// Convenience function to get the value of an integer constant, for an
// appropriate integer or non-integer type that can be held in an integer.
// The type of the argument must be the following:
-// Signed or unsigned integer
-// Boolean
-// Pointer
+// Signed or unsigned integer
+// Boolean
+// Pointer
//
// isValidConstant is set to true if a valid constant was found.
//
static int64_t
GetConstantValueAsSignedInt(const Value *V,
- bool &isValidConstant)
+ bool &isValidConstant)
{
- if (!V->isConstant()) { isValidConstant = false; return 0; }
+ if (!V->isConstant())
+ {
+ isValidConstant = false;
+ return 0;
+ }
+
isValidConstant = true;
if (V->getType() == Type::BoolTy)
- return ((ConstPoolBool*)V)->getValue();
- if (V->getType()->isIntegral()) {
- if (V->getType()->isSigned())
- return ((ConstPoolSInt*)V)->getValue();
-
- assert(V->getType()->isUnsigned());
- uint64_t Val = ((ConstPoolUInt*)V)->getValue();
-
- if (Val < INT64_MAX) // then safe to cast to signed
- return (int64_t)Val;
- }
+ return (int64_t) ((ConstPoolBool*)V)->getValue();
+
+ if (V->getType()->isIntegral())
+ {
+ if (V->getType()->isSigned())
+ return ((ConstPoolSInt*)V)->getValue();
+
+ assert(V->getType()->isUnsigned());
+ uint64_t Val = ((ConstPoolUInt*)V)->getValue();
+ if (Val < INT64_MAX) // then safe to cast to signed
+ return (int64_t)Val;
+ }
isValidConstant = false;
return 0;
@@ -150,10 +101,7 @@ ThisIsAChainRule(int eruleno)
switch(eruleno)
{
case 111: // stmt: reg
- case 112: // stmt: boolconst
case 113: // stmt: bool
- case 121:
- case 122:
case 123:
case 124:
case 125:
@@ -165,11 +113,9 @@ ThisIsAChainRule(int eruleno)
case 131:
case 132:
case 133:
- case 153:
case 155:
case 221:
case 222:
- case 232:
case 241:
case 242:
case 243:
@@ -209,25 +155,8 @@ ChooseBprInstruction(const InstructionNode* instrNode)
static inline MachineOpCode
-ChooseBccInstruction(const InstructionNode* instrNode,
- bool& isFPBranch)
-{
- InstructionNode* setCCNode = (InstructionNode*) instrNode->leftChild();
- BinaryOperator* setCCInstr = (BinaryOperator*) setCCNode->getInstruction();
- const Type* setCCType = setCCInstr->getOperand(0)->getType();
-
- isFPBranch = (setCCType == Type::FloatTy || setCCType == Type::DoubleTy);
-
- if (isFPBranch)
- return ChooseBFpccInstruction(instrNode, setCCInstr);
- else
- return ChooseBpccInstruction(instrNode, setCCInstr);
-}
-
-
-static inline MachineOpCode
ChooseBpccInstruction(const InstructionNode* instrNode,
- const BinaryOperator* setCCInstr)
+ const BinaryOperator* setCCInstr)
{
MachineOpCode opCode = INVALID_OPCODE;
@@ -236,32 +165,32 @@ ChooseBpccInstruction(const InstructionNode* instrNode,
if (isSigned)
{
switch(setCCInstr->getOpcode())
- {
- case Instruction::SetEQ: opCode = BE; break;
- case Instruction::SetNE: opCode = BNE; break;
- case Instruction::SetLE: opCode = BLE; break;
- case Instruction::SetGE: opCode = BGE; break;
- case Instruction::SetLT: opCode = BL; break;
- case Instruction::SetGT: opCode = BG; break;
- default:
- assert(0 && "Unrecognized VM instruction!");
- break;
- }
+ {
+ case Instruction::SetEQ: opCode = BE; break;
+ case Instruction::SetNE: opCode = BNE; break;
+ case Instruction::SetLE: opCode = BLE; break;
+ case Instruction::SetGE: opCode = BGE; break;
+ case Instruction::SetLT: opCode = BL; break;
+ case Instruction::SetGT: opCode = BG; break;
+ default:
+ assert(0 && "Unrecognized VM instruction!");
+ break;
+ }
}
else
{
switch(setCCInstr->getOpcode())
- {
- case Instruction::SetEQ: opCode = BE; break;
- case Instruction::SetNE: opCode = BNE; break;
- case Instruction::SetLE: opCode = BLEU; break;
- case Instruction::SetGE: opCode = BCC; break;
- case Instruction::SetLT: opCode = BCS; break;
- case Instruction::SetGT: opCode = BGU; break;
- default:
- assert(0 && "Unrecognized VM instruction!");
- break;
- }
+ {
+ case Instruction::SetEQ: opCode = BE; break;
+ case Instruction::SetNE: opCode = BNE; break;
+ case Instruction::SetLE: opCode = BLEU; break;
+ case Instruction::SetGE: opCode = BCC; break;
+ case Instruction::SetLT: opCode = BCS; break;
+ case Instruction::SetGT: opCode = BGU; break;
+ default:
+ assert(0 && "Unrecognized VM instruction!");
+ break;
+ }
}
return opCode;
@@ -269,7 +198,7 @@ ChooseBpccInstruction(const InstructionNode* instrNode,
static inline MachineOpCode
ChooseBFpccInstruction(const InstructionNode* instrNode,
- const BinaryOperator* setCCInstr)
+ const BinaryOperator* setCCInstr)
{
MachineOpCode opCode = INVALID_OPCODE;
@@ -291,6 +220,23 @@ ChooseBFpccInstruction(const InstructionNode* instrNode,
static inline MachineOpCode
+ChooseBccInstruction(const InstructionNode* instrNode,
+ bool& isFPBranch)
+{
+ InstructionNode* setCCNode = (InstructionNode*) instrNode->leftChild();
+ BinaryOperator* setCCInstr = (BinaryOperator*) setCCNode->getInstruction();
+ const Type* setCCType = setCCInstr->getOperand(0)->getType();
+
+ isFPBranch = (setCCType == Type::FloatTy || setCCType == Type::DoubleTy);
+
+ if (isFPBranch)
+ return ChooseBFpccInstruction(instrNode, setCCInstr);
+ else
+ return ChooseBpccInstruction(instrNode, setCCInstr);
+}
+
+
+static inline MachineOpCode
ChooseMovFpccInstruction(const InstructionNode* instrNode)
{
MachineOpCode opCode = INVALID_OPCODE;
@@ -322,8 +268,8 @@ ChooseMovFpccInstruction(const InstructionNode* instrNode)
//
static MachineOpCode
ChooseMovpccAfterSub(const InstructionNode* instrNode,
- bool& mustClearReg,
- int& valueToMove)
+ bool& mustClearReg,
+ int& valueToMove)
{
MachineOpCode opCode = INVALID_OPCODE;
mustClearReg = true;
@@ -346,7 +292,7 @@ ChooseMovpccAfterSub(const InstructionNode* instrNode,
static inline MachineOpCode
ChooseConvertToFloatInstr(const InstructionNode* instrNode,
- const Type* opType)
+ const Type* opType)
{
MachineOpCode opCode = INVALID_OPCODE;
@@ -354,28 +300,28 @@ ChooseConvertToFloatInstr(const InstructionNode* instrNode,
{
case ToFloatTy:
if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
- opCode = FITOS;
+ opCode = FITOS;
else if (opType == Type::LongTy)
- opCode = FXTOS;
+ opCode = FXTOS;
else if (opType == Type::DoubleTy)
- opCode = FDTOS;
+ opCode = FDTOS;
else if (opType == Type::FloatTy)
- ;
+ ;
else
- assert(0 && "Cannot convert this type to FLOAT on SPARC");
+ assert(0 && "Cannot convert this type to FLOAT on SPARC");
break;
case ToDoubleTy:
if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
- opCode = FITOD;
+ opCode = FITOD;
else if (opType == Type::LongTy)
- opCode = FXTOD;
+ opCode = FXTOD;
else if (opType == Type::FloatTy)
- opCode = FSTOD;
+ opCode = FSTOD;
else if (opType == Type::DoubleTy)
- ;
+ ;
else
- assert(0 && "Cannot convert this type to DOUBLE on SPARC");
+ assert(0 && "Cannot convert this type to DOUBLE on SPARC");
break;
default:
@@ -387,7 +333,7 @@ ChooseConvertToFloatInstr(const InstructionNode* instrNode,
static inline MachineOpCode
ChooseConvertToIntInstr(const InstructionNode* instrNode,
- const Type* opType)
+ const Type* opType)
{
MachineOpCode opCode = INVALID_OPCODE;;
@@ -396,24 +342,24 @@ ChooseConvertToIntInstr(const InstructionNode* instrNode,
if (instrType == ToSByteTy || instrType == ToShortTy || instrType == ToIntTy)
{
switch (opType->getPrimitiveID())
- {
+ {
case Type::FloatTyID: opCode = FSTOI; break;
case Type::DoubleTyID: opCode = FDTOI; break;
- default:
- assert(0 && "Non-numeric non-bool type cannot be converted to Int");
- break;
- }
+ default:
+ assert(0 && "Non-numeric non-bool type cannot be converted to Int");
+ break;
+ }
}
else if (instrType == ToLongTy)
{
switch (opType->getPrimitiveID())
- {
+ {
case Type::FloatTyID: opCode = FSTOX; break;
case Type::DoubleTyID: opCode = FDTOX; break;
- default:
- assert(0 && "Non-numeric non-bool type cannot be converted to Long");
- break;
- }
+ default:
+ assert(0 && "Non-numeric non-bool type cannot be converted to Long");
+ break;
+ }
}
else
assert(0 && "Should not get here, Mo!");
@@ -423,44 +369,47 @@ ChooseConvertToIntInstr(const InstructionNode* instrNode,
static inline MachineOpCode
-ChooseAddInstruction(const InstructionNode* instrNode)
+ChooseAddInstructionByType(const Type* resultType)
{
MachineOpCode opCode = INVALID_OPCODE;
- const Type* resultType = instrNode->getInstruction()->getType();
-
if (resultType->isIntegral() ||
resultType->isPointerType() ||
resultType->isMethodType() ||
- resultType->isLabelType())
+ resultType->isLabelType() ||
+ resultType == Type::BoolTy)
{
opCode = ADD;
}
else
- {
- Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
- switch(operand->getType()->getPrimitiveID())
- {
- case Type::FloatTyID: opCode = FADDS; break;
- case Type::DoubleTyID: opCode = FADDD; break;
- default: assert(0 && "Invalid type for ADD instruction"); break;
- }
- }
+ switch(resultType->getPrimitiveID())
+ {
+ case Type::FloatTyID: opCode = FADDS; break;
+ case Type::DoubleTyID: opCode = FADDD; break;
+ default: assert(0 && "Invalid type for ADD instruction"); break;
+ }
return opCode;
}
+static inline MachineOpCode
+ChooseAddInstruction(const InstructionNode* instrNode)
+{
+ return ChooseAddInstructionByType(instrNode->getInstruction()->getType());
+}
+
+
static inline MachineInstr*
CreateMovFloatInstruction(const InstructionNode* instrNode,
- const Type* resultType)
+ const Type* resultType)
{
MachineInstr* minstr = new MachineInstr((resultType == Type::FloatTy)
- ? FMOVS : FMOVD);
+ ? FMOVS : FMOVD);
minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
+ instrNode->leftChild()->getValue());
minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- instrNode->getValue());
+ instrNode->getValue());
return minstr;
}
@@ -478,11 +427,13 @@ CreateAddConstInstruction(const InstructionNode* instrNode)
//
const Type* resultType = instrNode->getInstruction()->getType();
- if (resultType == Type::FloatTy || resultType == Type::DoubleTy) {
- double dval = ((ConstPoolFP*) constOp)->getValue();
- if (dval == 0.0)
- minstr = CreateMovFloatInstruction(instrNode, resultType);
- }
+ if (resultType == Type::FloatTy ||
+ resultType == Type::DoubleTy)
+ {
+ double dval = ((ConstPoolFP*) constOp)->getValue();
+ if (dval == 0.0)
+ minstr = CreateMovFloatInstruction(instrNode, resultType);
+ }
return minstr;
}
@@ -501,15 +452,12 @@ ChooseSubInstruction(const InstructionNode* instrNode)
opCode = SUB;
}
else
- {
- Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
- switch(operand->getType()->getPrimitiveID())
- {
- case Type::FloatTyID: opCode = FSUBS; break;
- case Type::DoubleTyID: opCode = FSUBD; break;
- default: assert(0 && "Invalid type for SUB instruction"); break;
- }
- }
+ switch(resultType->getPrimitiveID())
+ {
+ case Type::FloatTyID: opCode = FSUBS; break;
+ case Type::DoubleTyID: opCode = FSUBD; break;
+ default: assert(0 && "Invalid type for SUB instruction"); break;
+ }
return opCode;
}
@@ -534,7 +482,7 @@ CreateSubConstInstruction(const InstructionNode* instrNode)
{
double dval = ((ConstPoolFP*) constOp)->getValue();
if (dval == 0.0)
- minstr = CreateMovFloatInstruction(instrNode, resultType);
+ minstr = CreateMovFloatInstruction(instrNode, resultType);
}
return minstr;
@@ -570,14 +518,14 @@ BothFloatToDouble(const InstructionNode* instrNode)
// Check if both arguments are floats cast to double
return (leftArg->getValue()->getType() == Type::DoubleTy &&
- leftArgArg->getValue()->getType() == Type::FloatTy &&
- rightArgArg->getValue()->getType() == Type::FloatTy);
+ leftArgArg->getValue()->getType() == Type::FloatTy &&
+ rightArgArg->getValue()->getType() == Type::FloatTy);
}
static inline MachineOpCode
ChooseMulInstruction(const InstructionNode* instrNode,
- bool checkCasts)
+ bool checkCasts)
{
MachineOpCode opCode = INVALID_OPCODE;
@@ -594,24 +542,23 @@ ChooseMulInstruction(const InstructionNode* instrNode,
opCode = MULX;
}
else
- {
- switch(instrNode->leftChild()->getValue()->getType()->getPrimitiveID())
- {
- case Type::FloatTyID: opCode = FMULS; break;
- case Type::DoubleTyID: opCode = FMULD; break;
- default: assert(0 && "Invalid type for MUL instruction"); break;
- }
- }
+ switch(resultType->getPrimitiveID())
+ {
+ case Type::FloatTyID: opCode = FMULS; break;
+ case Type::DoubleTyID: opCode = FMULD; break;
+ default: assert(0 && "Invalid type for MUL instruction"); break;
+ }
return opCode;
}
static inline MachineInstr*
-CreateIntNegInstruction(Value* vreg)
+CreateIntNegInstruction(TargetMachine& target,
+ Value* vreg)
{
MachineInstr* minstr = new MachineInstr(SUB);
- minstr->SetMachineOperand(0, /*regNum %g0*/(unsigned int) 0);
+ minstr->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, vreg);
minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, vreg);
return minstr;
@@ -619,8 +566,9 @@ CreateIntNegInstruction(Value* vreg)
static inline MachineInstr*
-CreateMulConstInstruction(const InstructionNode* instrNode,
- MachineInstr*& getMinstr2)
+CreateMulConstInstruction(TargetMachine &target,
+ const InstructionNode* instrNode,
+ MachineInstr*& getMinstr2)
{
MachineInstr* minstr = NULL;
getMinstr2 = NULL;
@@ -641,111 +589,111 @@ CreateMulConstInstruction(const InstructionNode* instrNode,
bool isValidConst;
int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst);
if (isValidConst)
- {
- bool needNeg = false;
- if (C < 0)
- {
- needNeg = true;
- C = -C;
- }
-
- if (C == 0 || C == 1)
- {
- minstr = new MachineInstr(ADD);
-
- if (C == 0)
- minstr->SetMachineOperand(0, /*regNum %g0*/ (unsigned int) 0);
- else
- minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
- }
- else if (IsPowerOf2(C, pow))
- {
- minstr = new MachineInstr((resultType == Type::LongTy)
- ? SLLX : SLL);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
- pow);
- }
-
- if (minstr && needNeg)
- { // insert <reg = SUB 0, reg> after the instr to flip the sign
- getMinstr2 = CreateIntNegInstruction(instrNode->getValue());
- }
- }
+ {
+ bool needNeg = false;
+ if (C < 0)
+ {
+ needNeg = true;
+ C = -C;
+ }
+
+ if (C == 0 || C == 1)
+ {
+ minstr = new MachineInstr(ADD);
+
+ if (C == 0)
+ minstr->SetMachineOperand(0,
+ target.getRegInfo().getZeroRegNum());
+ else
+ minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
+ instrNode->leftChild()->getValue());
+ minstr->SetMachineOperand(1,target.getRegInfo().getZeroRegNum());
+ }
+ else if (IsPowerOf2(C, pow))
+ {
+ minstr = new MachineInstr((resultType == Type::LongTy)
+ ? SLLX : SLL);
+ minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ instrNode->leftChild()->getValue());
+ minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
+ pow);
+ }
+
+ if (minstr && needNeg)
+ { // insert <reg = SUB 0, reg> after the instr to flip the sign
+ getMinstr2 = CreateIntNegInstruction(target,
+ instrNode->getValue());
+ }
+ }
}
else
{
if (resultType == Type::FloatTy ||
- resultType == Type::DoubleTy)
- {
- bool isValidConst;
- double dval = ((ConstPoolFP*) constOp)->getValue();
-
- if (isValidConst)
- {
- if (dval == 0)
- {
- minstr = new MachineInstr((resultType == Type::FloatTy)
- ? FITOS : FITOD);
- minstr->SetMachineOperand(0, /*regNum %g0*/(unsigned int) 0);
- }
- else if (fabs(dval) == 1)
- {
- bool needNeg = (dval < 0);
-
- MachineOpCode opCode = needNeg
- ? (resultType == Type::FloatTy? FNEGS : FNEGD)
- : (resultType == Type::FloatTy? FMOVS : FMOVD);
-
- minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0,
- MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- }
- }
- }
+ resultType == Type::DoubleTy)
+ {
+ bool isValidConst;
+ double dval = ((ConstPoolFP*) constOp)->getValue();
+
+ if (isValidConst)
+ {
+ if (dval == 0)
+ {
+ minstr = new MachineInstr((resultType == Type::FloatTy)
+ ? FITOS : FITOD);
+ minstr->SetMachineOperand(0,
+ target.getRegInfo().getZeroRegNum());
+ }
+ else if (fabs(dval) == 1)
+ {
+ bool needNeg = (dval < 0);
+
+ MachineOpCode opCode = needNeg
+ ? (resultType == Type::FloatTy? FNEGS : FNEGD)
+ : (resultType == Type::FloatTy? FMOVS : FMOVD);
+
+ minstr = new MachineInstr(opCode);
+ minstr->SetMachineOperand(0,
+ MachineOperand::MO_VirtualRegister,
+ instrNode->leftChild()->getValue());
+ }
+ }
+ }
}
if (minstr != NULL)
minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- instrNode->getValue());
+ instrNode->getValue());
return minstr;
}
static inline MachineOpCode
-ChooseDivInstruction(const InstructionNode* instrNode)
+ChooseDivInstruction(TargetMachine &target,
+ const InstructionNode* instrNode)
{
MachineOpCode opCode = INVALID_OPCODE;
const Type* resultType = instrNode->getInstruction()->getType();
if (resultType->isIntegral())
- {
- opCode = resultType->isSigned()? SDIVX : UDIVX;
- }
+ opCode = resultType->isSigned()? SDIVX : UDIVX;
else
- {
- Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
- switch(operand->getType()->getPrimitiveID())
- {
- case Type::FloatTyID: opCode = FDIVS; break;
- case Type::DoubleTyID: opCode = FDIVD; break;
- default: assert(0 && "Invalid type for DIV instruction"); break;
- }
- }
+ switch(resultType->getPrimitiveID())
+ {
+ case Type::FloatTyID: opCode = FDIVS; break;
+ case Type::DoubleTyID: opCode = FDIVD; break;
+ default: assert(0 && "Invalid type for DIV instruction"); break;
+ }
return opCode;
}
static inline MachineInstr*
-CreateDivConstInstruction(const InstructionNode* instrNode,
- MachineInstr*& getMinstr2)
+CreateDivConstInstruction(TargetMachine &target,
+ const InstructionNode* instrNode,
+ MachineInstr*& getMinstr2)
{
MachineInstr* minstr = NULL;
getMinstr2 = NULL;
@@ -765,71 +713,74 @@ CreateDivConstInstruction(const InstructionNode* instrNode,
bool isValidConst;
int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst);
if (isValidConst)
- {
- bool needNeg = false;
- if (C < 0)
- {
- needNeg = true;
- C = -C;
- }
-
- if (C == 1)
- {
- minstr = new MachineInstr(ADD);
- minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
- }
- 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,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
- pow);
- }
-
- if (minstr && needNeg)
- { // insert <reg = SUB 0, reg> after the instr to flip the sign
- getMinstr2 = CreateIntNegInstruction(instrNode->getValue());
- }
- }
+ {
+ bool needNeg = false;
+ if (C < 0)
+ {
+ needNeg = true;
+ C = -C;
+ }
+
+ if (C == 1)
+ {
+ minstr = new MachineInstr(ADD);
+ minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
+ instrNode->leftChild()->getValue());
+ minstr->SetMachineOperand(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,
+ instrNode->leftChild()->getValue());
+ minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
+ pow);
+ }
+
+ if (minstr && needNeg)
+ { // insert <reg = SUB 0, reg> after the instr to flip the sign
+ getMinstr2 = CreateIntNegInstruction(target,
+ instrNode->getValue());
+ }
+ }
}
else
{
if (resultType == Type::FloatTy ||
- resultType == Type::DoubleTy)
- {
- bool isValidConst;
- double dval = ((ConstPoolFP*) constOp)->getValue();
-
- if (isValidConst && fabs(dval) == 1)
- {
- bool needNeg = (dval < 0);
-
- MachineOpCode opCode = needNeg
- ? (resultType == Type::FloatTy? FNEGS : FNEGD)
- : (resultType == Type::FloatTy? FMOVS : FMOVD);
-
- minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- }
- }
+ resultType == Type::DoubleTy)
+ {
+ bool isValidConst;
+ double dval = ((ConstPoolFP*) constOp)->getValue();
+
+ if (isValidConst && fabs(dval) == 1)
+ {
+ bool needNeg = (dval < 0);
+
+ MachineOpCode opCode = needNeg
+ ? (resultType == Type::FloatTy? FNEGS : FNEGD)
+ : (resultType == Type::FloatTy? FMOVS : FMOVD);
+
+ minstr = new MachineInstr(opCode);
+ minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ instrNode->leftChild()->getValue());
+ }
+ }
}
if (minstr != NULL)
minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- instrNode->getValue());
+ instrNode->getValue());
return minstr;
}
-static inline MachineOpCode ChooseLoadInstruction(const Type *DestTy) {
+static inline MachineOpCode
+ChooseLoadInstruction(const Type *DestTy)
+{
switch (DestTy->getPrimitiveID()) {
case Type::BoolTyID:
case Type::UByteTyID: return LDUB;
@@ -850,7 +801,9 @@ static inline MachineOpCode ChooseLoadInstruction(const Type *DestTy) {
}
-static inline MachineOpCode ChooseStoreInstruction(const Type *DestTy) {
+static inline MachineOpCode
+ChooseStoreInstruction(const Type *DestTy)
+{
switch (DestTy->getPrimitiveID()) {
case Type::BoolTyID:
case Type::UByteTyID:
@@ -889,8 +842,8 @@ static inline MachineOpCode ChooseStoreInstruction(const Type *DestTy) {
static void
SetOperandsForMemInstr(MachineInstr* minstr,
- const InstructionNode* vmInstrNode,
- const TargetMachine& target)
+ const InstructionNode* vmInstrNode,
+ const TargetMachine& target)
{
MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
@@ -908,8 +861,8 @@ SetOperandsForMemInstr(MachineInstr* minstr,
// and in the right child for Store instructions.
//
InstrTreeNode* ptrChild = (vmInstrNode->getOpLabel() == Instruction::Store
- ? vmInstrNode->rightChild()
- : vmInstrNode->leftChild());
+ ? vmInstrNode->rightChild()
+ : vmInstrNode->leftChild());
if (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
ptrChild->getOpLabel() == GetElemPtrIdx)
@@ -927,7 +880,7 @@ SetOperandsForMemInstr(MachineInstr* minstr,
idxVec = newIdxVec;
assert(! ((PointerType*)ptrVal->getType())->getValueType()->isArrayType()
- && "GetElemPtr cannot be folded into array refs in selection");
+ && "GetElemPtr cannot be folded into array refs in selection");
}
else
{
@@ -938,19 +891,19 @@ SetOperandsForMemInstr(MachineInstr* minstr,
ptrVal = memInst->getPtrOperand();
const Type* opType =
- ((const PointerType*) ptrVal->getType())->getValueType();
+ ((const PointerType*) ptrVal->getType())->getValueType();
if (opType->isArrayType())
- {
- assert((memInst->getNumOperands()
- == (unsigned) 1 + memInst->getFirstOffsetIdx())
- && "Array refs must be lowered before Instruction Selection");
-
- arrayOffsetVal = memInst->getOperand(memInst->getFirstOffsetIdx());
- }
+ {
+ assert((memInst->getNumOperands()
+ == (unsigned) 1 + memInst->getFirstOffsetIdx())
+ && "Array refs must be lowered before Instruction Selection");
+
+ arrayOffsetVal = memInst->getOperand(memInst->getFirstOffsetIdx());
+ }
}
SetMemOperands_Internal(minstr, vmInstrNode, ptrVal, arrayOffsetVal,
- *idxVec, target);
+ *idxVec, target);
if (newIdxVec != NULL)
delete newIdxVec;
@@ -959,11 +912,11 @@ SetOperandsForMemInstr(MachineInstr* minstr,
static void
SetMemOperands_Internal(MachineInstr* minstr,
- const InstructionNode* vmInstrNode,
- Value* ptrVal,
- Value* arrayOffsetVal,
- const vector<ConstPoolVal*>& idxVec,
- const TargetMachine& target)
+ const InstructionNode* vmInstrNode,
+ Value* ptrVal,
+ Value* arrayOffsetVal,
+ const vector<ConstPoolVal*>& idxVec,
+ const TargetMachine& target)
{
MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
@@ -983,41 +936,41 @@ SetMemOperands_Internal(MachineInstr* minstr,
const PointerType* ptrType = (PointerType*) ptrVal->getType();
if (ptrType->getValueType()->isStructType())
- {
- // the offset is always constant for structs
- isConstantOffset = true;
-
- // Compute the offset value using the index vector
- offset = target.DataLayout.getIndexedOffset(ptrType, idxVec);
- }
+ {
+ // the offset is always constant for structs
+ isConstantOffset = true;
+
+ // Compute the offset value using the index vector
+ offset = target.DataLayout.getIndexedOffset(ptrType, idxVec);
+ }
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(ptrType->getValueType()->isArrayType());
- assert(arrayOffsetVal != NULL
- && "Expect to be given Value* for array offsets");
-
- if (ConstPoolVal *CPV = arrayOffsetVal->castConstant())
- {
- isConstantOffset = true; // always constant for structs
- assert(arrayOffsetVal->getType()->isIntegral());
- offset = (CPV->getType()->isSigned()
- ? ((ConstPoolSInt*)CPV)->getValue()
- : (int64_t) ((ConstPoolUInt*)CPV)->getValue());
- }
- else
- {
- va