aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/TargetMachine/Sparc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/TargetMachine/Sparc')
-rw-r--r--lib/CodeGen/TargetMachine/Sparc/Makefile14
-rw-r--r--lib/CodeGen/TargetMachine/Sparc/Sparc.burg286
-rw-r--r--lib/CodeGen/TargetMachine/Sparc/Sparc.cpp126
-rw-r--r--lib/CodeGen/TargetMachine/Sparc/SparcInstrSelection.cpp2016
-rw-r--r--lib/CodeGen/TargetMachine/Sparc/SparcInternals.h1667
-rw-r--r--lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp301
-rw-r--r--lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.h167
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 = instrNod