diff options
author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2001-10-01 00:12:53 +0000 |
---|---|---|
committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2001-10-01 00:12:53 +0000 |
commit | 4cecdd206ec0f2f9f24bb4149b31a383f90d7802 (patch) | |
tree | f7c3d570e57994c9dd42c18591ecead598d4179f | |
parent | 71939033dee310ad85d3ef10691b6588e4cd4fe5 (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.cpp | 2523 |
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 |