diff options
Diffstat (limited to 'lib/CodeGen/TargetMachine')
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/Makefile | 14 | ||||
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/Sparc.burg | 286 | ||||
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/Sparc.cpp | 126 | ||||
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/SparcInstrSelection.cpp | 2016 | ||||
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/SparcInternals.h | 1667 | ||||
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp | 301 | ||||
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.h | 167 |
7 files changed, 0 insertions, 4577 deletions
diff --git a/lib/CodeGen/TargetMachine/Sparc/Makefile b/lib/CodeGen/TargetMachine/Sparc/Makefile deleted file mode 100644 index 2daca1f772..0000000000 --- a/lib/CodeGen/TargetMachine/Sparc/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -LEVEL = ../../../.. - -DIRS = - -LIBRARYNAME = sparc - -## List source files in link order -Source = \ - Sparc.o \ - Sparc.burm.o \ - SparcInstrSelection.o - -include $(LEVEL)/Makefile.common - diff --git a/lib/CodeGen/TargetMachine/Sparc/Sparc.burg b/lib/CodeGen/TargetMachine/Sparc/Sparc.burg deleted file mode 100644 index 14e122c597..0000000000 --- a/lib/CodeGen/TargetMachine/Sparc/Sparc.burg +++ /dev/null @@ -1,286 +0,0 @@ -%{ // -*- C++ -*- -#include <stdio.h> -#include <llvm/CodeGen/InstrForest.h> - //#include <llvm/Analysis/InstForest.h> - -typedef InstrTreeNode* NODEPTR_TYPE; -#define OP_LABEL(p) ((p)->opLabel) -#define LEFT_CHILD(p) ((p)->LeftChild) -#define RIGHT_CHILD(p) ((p)->RightChild) -#define STATE_LABEL(p) ((p)->state) -#define PANIC printf -%} - -%start stmt - -%term Ret=1 /* return void from a function */ -%term RetValue=101 /* return a value from a function */ -%term BrUncond=2 -%term BrCond=102 -%term Switch=3 - /* 4 is unused */ -%term Not=4 -%term Add=5 -%term Sub=6 -%term Mul=7 -%term Div=8 -%term Rem=9 -%term And=10 -%term Or=11 -%term Xor=12 -%term SetCC=113 /* use this to match all SetCC instructions */ - /* %term SetEQ=13 */ - /* %term SetNE=14 */ - /* %term SetLE=15 */ - /* %term SetGE=16 */ - /* %term SetLT=17 */ - /* %term SetGT=18 */ -%term Malloc=19 -%term Free=20 -%term Alloca=21 -%term AllocaN=121 /* alloca with arg N */ -%term Load=22 -%term LoadIdx=122 /* load with index vector */ -%term Store=23 -%term GetElemPtr=24 -%term GetElemPtrIdx=124 /* getElemPtr with index vector */ - -%term Phi=25 - -%term Cast=26 /* cast that will be ignored. others are made explicit */ -%term ToBoolTy=126 -%term ToUByteTy=127 -%term ToSByteTy=128 -%term ToUShortTy=129 -%term ToShortTy=130 -%term ToUIntTy=131 -%term ToIntTy=132 -%term ToULongTy=133 -%term ToLongTy=134 -%term ToFloatTy=135 -%term ToDoubleTy=136 -%term ToArrayTy=137 -%term ToPointerTy=138 - -%term Call=27 -%term Shl=28 -%term Shr=29 - /* 30...46 are unused */ - /* - * The foll. values should match the constants in InstrForest.h - */ -%term VRegList=97 -%term VReg=98 -%term Constant=99 -%term Label=100 - /* 50+i is a variant of i, as defined above */ - - -%% -/*-----------------------------------------------------------------------* - * The productions of the grammar. - * Note that all chain rules are numbered 101 and above. - * Also, a special case of production X is numbered 100+X, 200+X, etc. - * The cost of a 1-cycle operation is represented as 10, to allow - * finer comparisons of costs (effectively, fractions of 1/10). - *-----------------------------------------------------------------------*/ - - /* - * The top-level statements - */ -stmt: Ret = 1 (30); -stmt: RetValue(reg) = 2 (30); -stmt: Store(reg,reg) = 3 (10); -stmt: Store(reg,ptrreg) = 4 (10); -stmt: BrUncond = 5 (20); -stmt: BrCond(boolconst) = 6 (10); /* may save one instruction */ -stmt: BrCond(bool) = 7 (20); -stmt: BrCond(boolreg) = 8 (20); -stmt: Switch(reg) = 9 (30); /* cost = load + branch */ - -stmt: reg = 111 (0); -stmt: boolconst = 112 (0); -stmt: bool = 113 (0); - - /* - * List node used for nodes with more than 2 children - */ -reg: VRegList(reg,reg) = 10 (0); - - /* - * The unary operators. We encode NOT and individual casts into - * separate non-terminals to combine instructions for some cases: - * Eg1: zdouble <- todouble(xfloat) * todouble(yfloat) - * Eg2: c <- a AND (NOT b). - * Note that the costs are counted for the individual non-terminals - * below, not for reg. - */ -reg: not = 121 (0); -reg: tobool = 122 (0); -reg: toubyte = 123 (0); -reg: tosbyte = 124 (0); -reg: toushort = 125 (0); -reg: toshort = 126 (0); -reg: touint = 127 (0); -reg: toint = 128 (0); -reg: toulong = 129 (0); -reg: tolong = 130 (0); -reg: tofloat = 131 (0); -reg: todouble = 132 (0); -reg: todoubleConst = 133 (0); - -not: Not(reg) = 21 (10); -tobool: ToBoolTy(reg) = 22 (10); -toubyte: ToUByteTy(reg) = 23 (10); -tosbyte: ToSByteTy(reg) = 24 (10); -toushort: ToUShortTy(reg) = 25 (10); -toshort: ToShortTy(reg) = 26 (10); -touint: ToUIntTy(reg) = 27 (10); -toint: ToIntTy(reg) = 28 (10); -toulong: ToULongTy(reg) = 29 (10); -tolong: ToLongTy(reg) = 30 (10); -tofloat: ToFloatTy(reg) = 31 (10); -todouble: ToDoubleTy(reg) = 32 (10); -todoubleConst: ToDoubleTy(Constant) = 232 (10); - -reg: ToArrayTy(reg) = 19 (10); -reg: ToPointerTy(reg) = 20 (10); - - /* - * The binary operators. - */ -reg: Add(reg,reg) = 33 (10); -reg: Sub(reg,reg) = 34 (10); -reg: Mul(reg,reg) = 35 (30); -reg: Mul(todouble,todouble) = 135 (20); /* avoids 1-2 type converts */ -reg: Div(reg,reg) = 36 (60); -reg: Rem(reg,reg) = 37 (60); -reg: And(reg,reg) = 38 (10); -reg: And(reg,not) = 138 (0); /* cost is counted for not */ -reg: Or (reg,reg) = 39 (10); -reg: Or (reg,not) = 139 (0); /* cost is counted for not */ -reg: Xor(reg,reg) = 40 (10); -reg: Xor(reg,not) = 140 (0); /* cost is counted for not */ - - /* - * The binary operators with one constant argument. - * We do not need the not(Constant) case because - * constant folding should take care of that beforehand. - */ -reg: Add(reg,Constant) = 233 (10); -reg: Sub(reg,Constant) = 234 (10); -reg: Mul(reg,Constant) = 235 (30); -reg: Mul(todouble,todoubleConst) = 335 (20); /* avoids 1-2 type converts */ -reg: Div(reg,Constant) = 236 (60); -reg: Rem(reg,Constant) = 237 (60); -reg: And(reg,Constant) = 238 (10); -reg: Or (reg,Constant) = 239 (10); -reg: Xor(reg,Constant) = 240 (10); - - /* - * The SetCC instructions and other boolean values - */ -boolconst: SetCC(reg,Constant) = 41 (10); -bool: SetCC(reg,reg) = 42 (10); -boolreg: VReg = 43 (0); -boolreg: Constant = 44 (0); - - /* - * Memory access instructions - */ -reg: Load(reg) = 51 (30); -reg: Load(ptrreg) = 52 (20); /* 1 counted for ptrreg */ -reg: LoadIdx(reg,reg) = 53 (30); -reg: LoadIdx(ptrreg,reg) = 54 (20); /* 1 counted for ptrreg */ -reg: ptrreg = 155 (0); -ptrreg: GetElemPtr(reg) = 55 (10); -ptrreg: GetElemPtrIdx(reg,reg) = 56 (10); -reg: Alloca = 57 (10); -reg: AllocaN(reg) = 58 (10); - - /* - * Other operators producing register values - */ -reg: Call = 61 (0); -reg: Shl(reg,reg) = 62 (20); /* 1 for issue restrictions */ -reg: Shr(reg,reg) = 63 (20); /* 1 for issue restrictions */ -reg: Phi(reg,reg) = 64 (0); - - /* - * Finally, leaf nodes of expression trees (other than boolreg) - */ -reg: VReg = 71 (0); -reg: Constant = 72 (3); /* prefer direct use */ - - - -%% -/*-----------------------------------------------------------------------* - * The rest of this file provides code to print the cover produced - * by BURG and information about computed tree cost and matches. - * This code was taken from sample.gr provided with BURG. - *-----------------------------------------------------------------------*/ - -void printcover(NODEPTR_TYPE p, int goalnt, int indent) { - int eruleno = burm_rule(STATE_LABEL(p), goalnt); - short *nts = burm_nts[eruleno]; - NODEPTR_TYPE kids[10]; - int i; - - if (eruleno == 0) { - printf("no cover\n"); - return; - } - for (i = 0; i < indent; i++) - printf("."); - printf("%s\n", burm_string[eruleno]); - burm_kids(p, eruleno, kids); - for (i = 0; nts[i]; i++) - printcover(kids[i], nts[i], indent+1); -} - -void printtree(NODEPTR_TYPE p) { - int op = burm_op_label(p); - - printf("%s", burm_opname[op]); - switch (burm_arity[op]) { - case 0: - break; - case 1: - printf("("); - printtree(burm_child(p, 0)); - printf(")"); - break; - case 2: - printf("("); - printtree(burm_child(p, 0)); - printf(", "); - printtree(burm_child(p, 1)); - printf(")"); - break; - } -} - -int treecost(NODEPTR_TYPE p, int goalnt, int costindex) { - int eruleno = burm_rule(STATE_LABEL(p), goalnt); - int cost = burm_cost[eruleno][costindex], i; - short *nts = burm_nts[eruleno]; - NODEPTR_TYPE kids[10]; - - burm_kids(p, eruleno, kids); - for (i = 0; nts[i]; i++) - cost += treecost(kids[i], nts[i], costindex); - return cost; -} - -void printMatches(NODEPTR_TYPE p) { - int nt; - int eruleno; - - printf("Node 0x%lx= ", (unsigned long)p); - printtree(p); - printf(" matched rules:\n"); - for (nt = 1; burm_ntname[nt] != (char*)NULL; nt++) - if ((eruleno = burm_rule(STATE_LABEL(p), nt)) != 0) - printf("\t%s\n", burm_string[eruleno]); -} diff --git a/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp b/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp deleted file mode 100644 index 017749f110..0000000000 --- a/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp +++ /dev/null @@ -1,126 +0,0 @@ -//*************************************************************************** -// File: -// Sparc.cpp -// -// Purpose: -// -// History: -// 7/15/01 - Vikram Adve - Created -//**************************************************************************/ - -#include "SparcInternals.h" -#include "llvm/Method.h" -#include "llvm/CodeGen/InstrScheduling.h" -#include "llvm/CodeGen/InstrSelection.h" - - - -//--------------------------------------------------------------------------- -// class UltraSparcInstrInfo -// -// Purpose: -// Information about individual instructions. -// Most information is stored in the SparcMachineInstrDesc array above. -// Other information is computed on demand, and most such functions -// default to member functions in base class MachineInstrInfo. -//--------------------------------------------------------------------------- - -/*ctor*/ -UltraSparcInstrInfo::UltraSparcInstrInfo() - : MachineInstrInfo(SparcMachineInstrDesc, - /*descSize = */ NUM_TOTAL_OPCODES, - /*numRealOpCodes = */ NUM_REAL_OPCODES) -{ -} - - -//--------------------------------------------------------------------------- -// class UltraSparcSchedInfo -// -// Purpose: -// Scheduling information for the UltraSPARC. -// Primarily just initializes machine-dependent parameters in -// class MachineSchedInfo. -//--------------------------------------------------------------------------- - -/*ctor*/ -UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii) - : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES, - mii, - SparcRUsageDesc, - SparcInstrUsageDeltas, - SparcInstrIssueDeltas, - sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta), - sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta)) -{ - maxNumIssueTotal = 4; - longestIssueConflict = 0; // computed from issuesGaps[] - - branchMispredictPenalty = 4; // 4 for SPARC IIi - branchTargetUnknownPenalty = 2; // 2 for SPARC IIi - l1DCacheMissPenalty = 8; // 7 or 9 for SPARC IIi - l1ICacheMissPenalty = 8; // ? for SPARC IIi - - inOrderLoads = true; // true for SPARC IIi - inOrderIssue = true; // true for SPARC IIi - inOrderExec = false; // false for most architectures - inOrderRetire= true; // true for most architectures - - // must be called after above parameters are initialized. - this->initializeResources(); -} - -void -UltraSparcSchedInfo::initializeResources() -{ - // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps - MachineSchedInfo::initializeResources(); - - // Machine-dependent fixups go here. None for now. -} - - -//--------------------------------------------------------------------------- -// class UltraSparcMachine -// -// Purpose: -// Primary interface to machine description for the UltraSPARC. -// Primarily just initializes machine-dependent parameters in -// class TargetMachine, and creates machine-dependent subclasses -// for classes such as MachineInstrInfo. -// -//--------------------------------------------------------------------------- - -UltraSparc::UltraSparc() - : TargetMachine("UltraSparc-Native") -{ - machineInstrInfo = new UltraSparcInstrInfo; - machineSchedInfo = new UltraSparcSchedInfo(machineInstrInfo); - - optSizeForSubWordData = 4; - minMemOpWordSize = 8; - maxAtomicMemOpWordSize = 8; - zeroRegNum = 0; // %g0 always gives 0 on Sparc -} - -UltraSparc::~UltraSparc() -{ - delete (UltraSparcInstrInfo*) machineInstrInfo; - delete (UltraSparcSchedInfo*) machineSchedInfo; -} - - -bool UltraSparc::compileMethod(Method *M) { - if (SelectInstructionsForMethod(M, *this)) { - cerr << "Instruction selection failed for method " << M->getName() - << "\n\n"; - return true; - } - - if (ScheduleInstructionsWithSSA(M, *this)) { - cerr << "Instruction scheduling before allocation failed for method " - << M->getName() << "\n\n"; - return true; - } - return false; -} diff --git a/lib/CodeGen/TargetMachine/Sparc/SparcInstrSelection.cpp b/lib/CodeGen/TargetMachine/Sparc/SparcInstrSelection.cpp deleted file mode 100644 index c73264c221..0000000000 --- a/lib/CodeGen/TargetMachine/Sparc/SparcInstrSelection.cpp +++ /dev/null @@ -1,2016 +0,0 @@ -//*************************************************************************** -// File: -// SparcInstrSelection.cpp -// -// Purpose: -// -// History: -// 7/02/01 - Vikram Adve - Created -//**************************************************************************/ - -#include "SparcInternals.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/InstrForest.h" -#include "llvm/CodeGen/InstrSelection.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/DerivedTypes.h" -#include "llvm/iTerminators.h" -#include "llvm/iMemory.h" -#include "llvm/iOther.h" -#include "llvm/BasicBlock.h" -#include "llvm/Method.h" -#include "llvm/ConstPoolVals.h" - - -//******************** Internal Data Declarations ************************/ - -// to be used later -struct BranchPattern { - 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 -}; - -//************************* 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, - InstructionNode* parent, - int operandNum); - - -//************************ Internal Functions ******************************/ - -// 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: -// GetConstantValueAsSignedInt: any of the above, but the value -// must fit into a int64_t. -// -// isValidConstant is set to true if a valid constant was found. -// - -static int64_t GetConstantValueAsSignedInt(const Value *V, - bool &isValidConstant) { - 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; - } - - isValidConstant = false; - return 0; -} - - - -//------------------------------------------------------------------------ -// External Function: ThisIsAChainRule -// -// Purpose: -// Check if a given BURG rule is a chain rule. -//------------------------------------------------------------------------ - -extern bool -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: - case 126: - case 127: - case 128: - case 129: - case 130: - case 131: - case 132: - case 153: - case 155: return true; break; - - default: return false; break; - } -} - - -static inline MachineOpCode -ChooseBprInstruction(const InstructionNode* instrNode) -{ - MachineOpCode opCode; - - Instruction* setCCInstr = - ((InstructionNode*) instrNode->leftChild())->getInstruction(); - - switch(setCCInstr->getOpcode()) - { - case Instruction::SetEQ: opCode = BRZ; break; - case Instruction::SetNE: opCode = BRNZ; break; - case Instruction::SetLE: opCode = BRLEZ; break; - case Instruction::SetGE: opCode = BRGEZ; break; - case Instruction::SetLT: opCode = BRLZ; break; - case Instruction::SetGT: opCode = BRGZ; break; - default: - assert(0 && "Unrecognized VM instruction!"); - opCode = INVALID_OPCODE; - break; - } - - return opCode; -} - - -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) -{ - MachineOpCode opCode = INVALID_OPCODE; - - bool isSigned = setCCInstr->getOperand(0)->getType()->isSigned(); - - 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; - } - } - 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; - } - } - - return opCode; -} - -static inline MachineOpCode -ChooseBFpccInstruction(const InstructionNode* instrNode, - const BinaryOperator* setCCInstr) -{ - MachineOpCode opCode = INVALID_OPCODE; - - switch(setCCInstr->getOpcode()) - { - case Instruction::SetEQ: opCode = FBE; break; - case Instruction::SetNE: opCode = FBNE; break; - case Instruction::SetLE: opCode = FBLE; break; - case Instruction::SetGE: opCode = FBGE; break; - case Instruction::SetLT: opCode = FBL; break; - case Instruction::SetGT: opCode = FBG; break; - default: - assert(0 && "Unrecognized VM instruction!"); - break; - } - - return opCode; -} - - -static inline MachineOpCode -ChooseMovFpccInstruction(const InstructionNode* instrNode) -{ - MachineOpCode opCode = INVALID_OPCODE; - - switch(instrNode->getInstruction()->getOpcode()) - { - case Instruction::SetEQ: opCode = MOVFE; break; - case Instruction::SetNE: opCode = MOVFNE; break; - case Instruction::SetLE: opCode = MOVFLE; break; - case Instruction::SetGE: opCode = MOVFGE; break; - case Instruction::SetLT: opCode = MOVFL; break; - case Instruction::SetGT: opCode = MOVFG; break; - default: - assert(0 && "Unrecognized VM instruction!"); - break; - } - - return opCode; -} - - -// Assumes that SUBcc v1, v2 -> v3 has been executed. -// In most cases, we want to clear v3 and then follow it by instruction -// MOVcc 1 -> v3. -// Set mustClearReg=false if v3 need not be cleared before conditional move. -// Set valueToMove=0 if we want to conditionally move 0 instead of 1 -// (i.e., we want to test inverse of a condition) -// -// -static MachineOpCode -ChooseMovpccAfterSub(const InstructionNode* instrNode, - bool& mustClearReg, - int& valueToMove) -{ - MachineOpCode opCode = INVALID_OPCODE; - mustClearReg = true; - valueToMove = 1; - - switch(instrNode->getInstruction()->getOpcode()) - { - case Instruction::SetEQ: opCode = MOVNE; mustClearReg = false; - valueToMove = 0; break; - case Instruction::SetLE: opCode = MOVLE; break; - case Instruction::SetGE: opCode = MOVGE; break; - case Instruction::SetLT: opCode = MOVL; break; - case Instruction::SetGT: opCode = MOVG; break; - - case Instruction::SetNE: assert(0 && "No move required!"); - - default: - assert(0 && "Unrecognized VM instruction!"); - break; - } - - return opCode; -} - - -static inline MachineOpCode -ChooseConvertToFloatInstr(const InstructionNode* instrNode, - const Type* opType) -{ - MachineOpCode opCode = INVALID_OPCODE; - - switch(instrNode->getOpLabel()) - { - case ToFloatTy: - if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy) - opCode = FITOS; - else if (opType == Type::LongTy) - opCode = FXTOS; - else if (opType == Type::DoubleTy) - opCode = FDTOS; - else if (opType == Type::FloatTy) - ; - else - 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; - else if (opType == Type::LongTy) - opCode = FXTOD; - else if (opType == Type::FloatTy) - opCode = FSTOD; - else if (opType == Type::DoubleTy) - ; - else - assert(0 && "Cannot convert this type to DOUBLE on SPARC"); - break; - - default: - break; - } - - return opCode; -} - -static inline MachineOpCode -ChooseConvertToIntInstr(const InstructionNode* instrNode, - const Type* opType) -{ - MachineOpCode opCode = INVALID_OPCODE;; - - int instrType = (int) instrNode->getOpLabel(); - - 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; - } - } - 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; - } - } - else - assert(0 && "Should not get here, Mo!"); - - return opCode; -} - - -static inline MachineOpCode -ChooseAddInstruction(const InstructionNode* instrNode) -{ - MachineOpCode opCode = INVALID_OPCODE; - - const Type* resultType = instrNode->getInstruction()->getType(); - - if (resultType->isIntegral() || - resultType->isPointerType() || - resultType->isMethodType() || - resultType->isLabelType()) - { - 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; - } - } - - return opCode; -} - - -static inline MachineInstr* -CreateMovFloatInstruction(const InstructionNode* instrNode, - const Type* resultType) -{ - 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()); - return minstr; -} - -static inline MachineInstr* -CreateAddConstInstruction(const InstructionNode* instrNode) -{ - MachineInstr* minstr = NULL; - - Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue(); - assert(constOp->isConstant()); - - // Cases worth optimizing are: - // (1) Add with 0 for float or double: use an FMOV of appropriate type, - // instead of an FADD (1 vs 3 cycles). There is no integer MOV. - // - 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); - } - - return minstr; -} - - -static inline MachineOpCode -ChooseSubInstruction(const InstructionNode* instrNode) -{ - MachineOpCode opCode = INVALID_OPCODE; - - const Type* resultType = instrNode->getInstruction()->getType(); - - if (resultType->isIntegral() || - resultType->isPointerType()) - { - 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; - } - } - - return opCode; -} - - -static inline MachineInstr* -CreateSubConstInstruction(const InstructionNode* instrNode) -{ - MachineInstr* minstr = NULL; - - Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue(); - assert(constOp->isConstant()); - - // Cases worth optimizing are: - // (1) Sub with 0 for float or double: use an FMOV of appropriate type, - // instead of an FSUB (1 vs 3 cycles). There is no integer MOV. - // - 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); - } - - return minstr; -} - - -static inline MachineOpCode -ChooseFcmpInstruction(const InstructionNode* instrNode) -{ - MachineOpCode opCode = INVALID_OPCODE; - - Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue(); - switch(operand->getType()->getPrimitiveID()) { - case Type::FloatTyID: opCode = FCMPS; break; - case Type::DoubleTyID: opCode = FCMPD; break; - default: assert(0 && "Invalid type for FCMP instruction"); break; - } - - return opCode; -} - - -// Assumes that leftArg and rightArg are both cast instructions. -// -static inline bool -BothFloatToDouble(const InstructionNode* instrNode) -{ - InstrTreeNode* leftArg = instrNode->leftChild(); - InstrTreeNode* rightArg = instrNode->rightChild(); - InstrTreeNode* leftArgArg = leftArg->leftChild(); - InstrTreeNode* rightArgArg = rightArg->leftChild(); - assert(leftArg->getValue()->getType() == rightArg->getValue()->getType()); - - // 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); -} - - -static inline MachineOpCode -ChooseMulInstruction(const InstructionNode* instrNode, - bool checkCasts) -{ - MachineOpCode opCode = INVALID_OPCODE; - - if (checkCasts && BothFloatToDouble(instrNode)) - { - return opCode = FSMULD; - } - // else fall through and use the regular multiply instructions - - const Type* resultType = instrNode->getInstruction()->getType(); - - if (resultType->isIntegral()) - { - 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; - } - } - - return opCode; -} - - -static inline MachineInstr* -CreateIntNegInstruction(Value* vreg) -{ - MachineInstr* minstr = new MachineInstr(SUB); - minstr->SetMachineOperand(0, /*regNum %g0*/(unsigned int) 0); - minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, vreg); - minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, vreg); - return minstr; -} - - -static inline MachineInstr* -CreateMulConstInstruction(const InstructionNode* instrNode, - MachineInstr*& getMinstr2) -{ - MachineInstr* minstr = NULL; - getMinstr2 = NULL; - bool needNeg = false; - - Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue(); - assert(constOp->isConstant()); - - // 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(); - - if (resultType->isIntegral()) - { |