mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-22 13:32:09 +00:00
Header files for the target architecture description and for instruction
selection, and instances of these for the SPARC. llvm-svn: 226
This commit is contained in:
parent
f88fee6cfe
commit
8d5ecffc9a
339
include/llvm/CodeGen/InstrForest.h
Normal file
339
include/llvm/CodeGen/InstrForest.h
Normal file
@ -0,0 +1,339 @@
|
||||
/* $Id$ -*-c++-*-
|
||||
****************************************************************************
|
||||
* File:
|
||||
* InstrForest.h
|
||||
*
|
||||
* Purpose:
|
||||
* Convert SSA graph to instruction trees for instruction selection.
|
||||
*
|
||||
* Strategy:
|
||||
* The basic idea is that we would like to group instructions into a single
|
||||
* tree if one or more of them might be potentially combined into a single
|
||||
* complex instruction in the target machine.
|
||||
* Since this grouping is completely machine-independent, it is as
|
||||
* aggressive as possible. In particular, we group two instructions
|
||||
* O and I if:
|
||||
* (1) Instruction O computes an operand of instruction I, and
|
||||
* (2) O and I are part of the same basic block, and
|
||||
* (3) O has only a single use, viz., I.
|
||||
*
|
||||
* History:
|
||||
* 6/28/01 - Vikram Adve - Created
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef LLVM_CODEGEN_INSTRFOREST_H
|
||||
#define LLVM_CODEGEN_INSTRFOREST_H
|
||||
|
||||
/*
|
||||
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
|
||||
C
|
||||
C The following types and macros are visible to the C code generated
|
||||
C by BURG.
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Data types needed by BURG and implemented by us
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
typedef int OpLabel;
|
||||
typedef int StateLabel;
|
||||
|
||||
typedef struct BasicTreeNode_struct {
|
||||
|
||||
BasicTreeNode_struct* leftChild;
|
||||
BasicTreeNode_struct* rightChild;
|
||||
BasicTreeNode_struct* parent;
|
||||
OpLabel opLabel;
|
||||
StateLabel state;
|
||||
void* treeNodePtr; /* points to the C++ tree node object
|
||||
* that "contains" this node */
|
||||
} BasicTreeNode;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Declarations of data and functions created by BURG
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
# ifdef __STDC__
|
||||
# define ARGS(x) x
|
||||
# else
|
||||
# define ARGS(x) ()
|
||||
# endif
|
||||
|
||||
extern short* burm_nts[];
|
||||
|
||||
extern StateLabel burm_label ARGS((BasicTreeNode* p));
|
||||
|
||||
extern StateLabel burm_state ARGS((OpLabel op,
|
||||
StateLabel leftState,
|
||||
StateLabel rightState));
|
||||
|
||||
extern StateLabel burm_rule ARGS((StateLabel state,
|
||||
int goalNT));
|
||||
|
||||
extern BasicTreeNode** burm_kids ARGS((BasicTreeNode* p,
|
||||
int eruleno,
|
||||
BasicTreeNode* kids[]));
|
||||
|
||||
extern void printcover ARGS((BasicTreeNode*, int, int));
|
||||
extern void printtree ARGS((BasicTreeNode*));
|
||||
extern int treecost ARGS((BasicTreeNode*, int, int));
|
||||
extern void printMatches ARGS((BasicTreeNode*));
|
||||
|
||||
}
|
||||
/* end extern "C" */
|
||||
|
||||
|
||||
/*CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
//************************** System Include Files **************************/
|
||||
|
||||
#include <bool.h>
|
||||
#include <hash_map>
|
||||
#include <hash_set>
|
||||
|
||||
//*************************** User Include Files ***************************/
|
||||
|
||||
#include "llvm/Support/Unique.h"
|
||||
#include "llvm/Instruction.h"
|
||||
|
||||
//************************* Opaque Declarations ****************************/
|
||||
|
||||
class Value;
|
||||
class Instruction;
|
||||
class ConstPoolVal;
|
||||
class BasicBlock;
|
||||
class Method;
|
||||
class InstrTreeNode;
|
||||
class InstrForest;
|
||||
|
||||
//************************ Exported Constants ******************************/
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// OpLabel values for special-case nodes created for instruction selection.
|
||||
// All op-labels not defined here are identical to the instruction
|
||||
// opcode returned by Instruction::getInstType()
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
const int InvalidOp = -1;
|
||||
const int VRegListOp = 97;
|
||||
const int VRegNodeOp = 98;
|
||||
const int ConstantNodeOp= 99;
|
||||
const int LabelNodeOp = 100;
|
||||
|
||||
const int RetValueOp = 100 + Instruction::Ret;
|
||||
const int BrCondOp = 100 + Instruction::Br;
|
||||
|
||||
const int SetCCOp = 100 + Instruction::SetEQ;
|
||||
|
||||
const int AllocaN = 100 + Instruction::Alloca; // 121
|
||||
const int LoadIdx = 100 + Instruction::Load; // 122
|
||||
const int GetElemPtrIdx= 100 + Instruction::GetElementPtr; // 124
|
||||
|
||||
const int ToBoolTy = 100 + Instruction::Cast; // 126
|
||||
const int ToUByteTy = ToBoolTy + 1;
|
||||
const int ToSByteTy = ToBoolTy + 2;
|
||||
const int ToUShortTy = ToBoolTy + 3;
|
||||
const int ToShortTy = ToBoolTy + 4;
|
||||
const int ToUIntTy = ToBoolTy + 5;
|
||||
const int ToIntTy = ToBoolTy + 6;
|
||||
const int ToULongTy = ToBoolTy + 7;
|
||||
const int ToLongTy = ToBoolTy + 8;
|
||||
const int ToFloatTy = ToBoolTy + 9;
|
||||
const int ToDoubleTy = ToBoolTy + 10;
|
||||
const int ToArrayTy = ToBoolTy + 11;
|
||||
const int ToPointerTy = ToBoolTy + 12;
|
||||
|
||||
|
||||
//************************ Exported Data Types *****************************/
|
||||
|
||||
struct ptrHashFunc {
|
||||
inline size_t operator()(const void* const& p) const
|
||||
{
|
||||
// Copied from body of hash<unsigned long>::operator().
|
||||
// I cannot figure out how to invoke that without an object
|
||||
return (size_t) ((const unsigned long) p);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// class InstrTreeNode
|
||||
//
|
||||
// A single tree node in the instruction tree used for
|
||||
// instruction selection via BURG.
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
inline InstrTreeNode*
|
||||
MainTreeNode(BasicTreeNode* node) {
|
||||
return (InstrTreeNode*) node->treeNodePtr;
|
||||
}
|
||||
|
||||
|
||||
class InstrTreeNode: public Unique {
|
||||
public:
|
||||
enum InstrTreeNodeType { NTInstructionNode,
|
||||
NTVRegListNode,
|
||||
NTVRegNode,
|
||||
NTConstNode,
|
||||
NTLabelNode };
|
||||
|
||||
protected:
|
||||
BasicTreeNode basicNode;
|
||||
InstrTreeNodeType treeNodeType;
|
||||
Value* val;
|
||||
|
||||
public:
|
||||
/*ctor*/ InstrTreeNode (InstrTreeNodeType nodeType,
|
||||
Value* _val);
|
||||
/*dtor*/ virtual ~InstrTreeNode ();
|
||||
|
||||
BasicTreeNode* getBasicNode () { return &basicNode; }
|
||||
|
||||
InstrTreeNodeType getNodeType () const { return treeNodeType; }
|
||||
|
||||
Value* getValue () const { return val; }
|
||||
|
||||
inline OpLabel getOpLabel () const { return basicNode.opLabel; }
|
||||
|
||||
inline InstrTreeNode* leftChild () const {
|
||||
return (InstrTreeNode*)
|
||||
(basicNode.leftChild? basicNode.leftChild->treeNodePtr : NULL);
|
||||
}
|
||||
|
||||
// If right child is a list node, recursively get its *left* child
|
||||
inline InstrTreeNode* rightChild () const {
|
||||
return (InstrTreeNode*)
|
||||
(basicNode.rightChild
|
||||
? (MainTreeNode(basicNode.rightChild)->getOpLabel() == VRegListOp
|
||||
? MainTreeNode(basicNode.rightChild)->leftChild()
|
||||
: MainTreeNode(basicNode.rightChild))
|
||||
: NULL);
|
||||
}
|
||||
|
||||
inline InstrTreeNode* parent () const {
|
||||
return (InstrTreeNode*)
|
||||
(basicNode.parent? basicNode.parent->treeNodePtr : NULL);
|
||||
}
|
||||
|
||||
void dump (int dumpChildren,
|
||||
int indent) const;
|
||||
|
||||
protected:
|
||||
virtual void dumpNode (int indent) const = 0;
|
||||
|
||||
friend class InstrForest;
|
||||
};
|
||||
|
||||
|
||||
class InstructionNode: public InstrTreeNode {
|
||||
public:
|
||||
/*ctor*/ InstructionNode (Instruction* _instr);
|
||||
Instruction* getInstruction () const { return (Instruction*) val; }
|
||||
void reverseBinaryArgumentOrder();
|
||||
protected:
|
||||
virtual void dumpNode (int indent) const;
|
||||
};
|
||||
|
||||
|
||||
class VRegListNode: public InstrTreeNode {
|
||||
public:
|
||||
/*ctor*/ VRegListNode ();
|
||||
protected:
|
||||
virtual void dumpNode (int indent) const;
|
||||
};
|
||||
|
||||
|
||||
class VRegNode: public InstrTreeNode {
|
||||
public:
|
||||
/*ctor*/ VRegNode (Value* _val);
|
||||
protected:
|
||||
virtual void dumpNode (int indent) const;
|
||||
};
|
||||
|
||||
|
||||
class ConstantNode: public InstrTreeNode {
|
||||
public:
|
||||
/*ctor*/ ConstantNode (ConstPoolVal* constVal);
|
||||
ConstPoolVal* getConstVal () const { return (ConstPoolVal*) val;}
|
||||
protected:
|
||||
virtual void dumpNode ( int indent) const;
|
||||
};
|
||||
|
||||
|
||||
class LabelNode: public InstrTreeNode {
|
||||
public:
|
||||
/*ctor*/ LabelNode (BasicBlock* _bblock);
|
||||
BasicBlock* getBasicBlock () const { return (BasicBlock*) val;}
|
||||
protected:
|
||||
virtual void dumpNode (int indent) const;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// class InstrForest
|
||||
//
|
||||
// A forest of instruction trees, usually for a single method.
|
||||
//
|
||||
// Methods:
|
||||
// buildTreesForMethod() Builds the forest of trees for a method
|
||||
// getTreeNodeForInstr() Returns the tree node for an Instruction
|
||||
// getRootSet() Returns a set of root nodes for all the trees
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
class InstrForest :
|
||||
public Unique,
|
||||
private hash_map<const Instruction*, InstructionNode*, ptrHashFunc > {
|
||||
|
||||
private:
|
||||
hash_set<InstructionNode*, ptrHashFunc > treeRoots;
|
||||
|
||||
public:
|
||||
/*ctor*/ InstrForest () {}
|
||||
/*dtor*/ ~InstrForest () {}
|
||||
|
||||
void buildTreesForMethod (Method *method);
|
||||
|
||||
inline InstructionNode*
|
||||
getTreeNodeForInstr(Instruction* instr)
|
||||
{
|
||||
return (*this)[instr];
|
||||
}
|
||||
|
||||
inline const hash_set<InstructionNode*, ptrHashFunc>&
|
||||
getRootSet() const {
|
||||
return treeRoots;
|
||||
}
|
||||
|
||||
void dump () const;
|
||||
|
||||
private:
|
||||
//
|
||||
// Private methods for buidling the instruction forest
|
||||
//
|
||||
void setLeftChild (InstrTreeNode* parent,
|
||||
InstrTreeNode* child);
|
||||
|
||||
void setRightChild (InstrTreeNode* parent,
|
||||
InstrTreeNode* child);
|
||||
|
||||
void setParent (InstrTreeNode* child,
|
||||
InstrTreeNode* parent);
|
||||
|
||||
void noteTreeNodeForInstr (Instruction* instr,
|
||||
InstructionNode* treeNode);
|
||||
|
||||
InstructionNode* buildTreeForInstruction(Instruction* instr);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#endif /* #ifndef INSTRFOREST_H */
|
121
include/llvm/CodeGen/InstrSelection.h
Normal file
121
include/llvm/CodeGen/InstrSelection.h
Normal file
@ -0,0 +1,121 @@
|
||||
// $Id$ -*-c++-*-
|
||||
//***************************************************************************
|
||||
// File:
|
||||
// InstrSelection.h
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// History:
|
||||
// 7/02/01 - Vikram Adve - Created
|
||||
//***************************************************************************
|
||||
|
||||
#ifndef LLVM_CODEGEN_INSTR_SELECTION_H
|
||||
#define LLVM_CODEGEN_INSTR_SELECTION_H
|
||||
|
||||
//************************** System Include Files **************************/
|
||||
|
||||
//*************************** User Include Files ***************************/
|
||||
|
||||
#include "llvm/Instruction.h"
|
||||
|
||||
//************************* Opaque Declarations ****************************/
|
||||
|
||||
class CompileContext;
|
||||
class Instruction;
|
||||
class Method;
|
||||
class InstrForest;
|
||||
class MachineInstruction;
|
||||
class TmpInstruction;
|
||||
|
||||
|
||||
//************************ Exported Constants ******************************/
|
||||
|
||||
const int DEBUG_INSTR_TREES = 2;
|
||||
const int DEBUG_BURG_TREES = 5;
|
||||
|
||||
|
||||
//****************** External Function Prototypes **************************/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// GLOBAL data and an external function that must be implemented
|
||||
// for each architecture.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const unsigned MAX_INSTR_PER_VMINSTR = 8;
|
||||
|
||||
extern unsigned GetInstructionsByRule (InstructionNode* subtreeRoot,
|
||||
int ruleForNode,
|
||||
short* nts,
|
||||
CompileContext& ccontext,
|
||||
MachineInstr** minstrVec);
|
||||
|
||||
extern bool ThisIsAChainRule (int eruleno);
|
||||
|
||||
|
||||
//************************ Exported Data Types *****************************/
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Function: SelectInstructionsForMethod
|
||||
//
|
||||
// Purpose:
|
||||
// Entry point for instruction selection using BURG.
|
||||
// Returns true if instruction selection failed, false otherwise.
|
||||
// Implemented in machine-specific instruction selection file.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool SelectInstructionsForMethod (Method* method,
|
||||
CompileContext& ccontext);
|
||||
|
||||
|
||||
// Debugging function to print the generated instructions
|
||||
void PrintMachineInstructions (Method* method,
|
||||
CompileContext& ccontext);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Function: FoldGetElemChain
|
||||
//
|
||||
// Purpose:
|
||||
// Fold a chain of GetElementPtr instructions into an equivalent
|
||||
// (Pointer, IndexVector) pair. Returns the pointer Value, and
|
||||
// stores the resulting IndexVector in argument chainIdxVec.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
Value* FoldGetElemChain (const InstructionNode* getElemInstrNode,
|
||||
vector<ConstPoolVal*>& chainIdxVec);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// class TmpInstruction
|
||||
//
|
||||
// This class represents temporary intermediate values
|
||||
// used within the machine code for a VM instruction
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class TmpInstruction : public Instruction {
|
||||
TmpInstruction (const TmpInstruction &CI) : Instruction(CI.getType(), CI.getOpcode()) {
|
||||
Operands.reserve(2);
|
||||
Operands.push_back(Use(Operands[0], this));
|
||||
Operands.push_back(Use(Operands[1], this));
|
||||
}
|
||||
public:
|
||||
TmpInstruction(OtherOps Opcode, Value *S1, Value* S2, const string &Name = "")
|
||||
: Instruction(S1->getType(), Opcode, Name)
|
||||
{
|
||||
assert(Opcode == UserOp1 && "Tmp instruction opcode invalid!");
|
||||
Operands.reserve(S2? 2 : 1);
|
||||
Operands.push_back(Use(S1, this));
|
||||
if (S2)
|
||||
Operands.push_back(Use(S2, this));
|
||||
}
|
||||
|
||||
virtual Instruction *clone() const { return new TmpInstruction(*this); }
|
||||
virtual const char *getOpcodeName() const {
|
||||
return "userOp1";
|
||||
}
|
||||
};
|
||||
|
||||
//**************************************************************************/
|
||||
|
||||
#endif
|
370
include/llvm/CodeGen/MachineInstr.h
Normal file
370
include/llvm/CodeGen/MachineInstr.h
Normal file
@ -0,0 +1,370 @@
|
||||
// $Id$ -*-c++-*-
|
||||
//***************************************************************************
|
||||
// File:
|
||||
// MachineInstr.h
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//
|
||||
// Strategy:
|
||||
//
|
||||
// History:
|
||||
// 7/2/01 - Vikram Adve - Created
|
||||
//**************************************************************************/
|
||||
|
||||
#ifndef LLVM_CODEGEN_MACHINEINSTR_H
|
||||
#define LLVM_CODEGEN_MACHINEINSTR_H
|
||||
|
||||
//************************** System Include Files **************************/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//*************************** User Include Files ***************************/
|
||||
|
||||
#include "llvm/Tools/DataTypes.h"
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/Support/Unique.h"
|
||||
#include "llvm/Codegen/TargetMachine.h"
|
||||
|
||||
|
||||
//************************* Opaque Declarations ****************************/
|
||||
|
||||
class Value;
|
||||
class InstrTreeNode;
|
||||
class InstructionNode;
|
||||
class MachineInstr;
|
||||
class MachineInstrInfo;
|
||||
class MachineOperand;
|
||||
|
||||
|
||||
//************************ Exported Data Types *****************************/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// class MachineOperand
|
||||
//
|
||||
// Purpose:
|
||||
// Representation of each machine instruction operand.
|
||||
// This class is designed so that you can allocate a vector of operands
|
||||
// first and initialize each one later.
|
||||
//
|
||||
// E.g, for this VM instruction:
|
||||
// ptr = alloca type, numElements
|
||||
// we generate 2 machine instructions on the SPARC:
|
||||
//
|
||||
// mul Constant, Numelements -> Reg
|
||||
// add %sp, Reg -> Ptr
|
||||
//
|
||||
// Each instruction has 3 operands, listed above. Of those:
|
||||
// - Reg, NumElements, and Ptr are of operand type MO_Register.
|
||||
// - Constant is of operand type MO_SignExtendedImmed on the SPARC.
|
||||
//
|
||||
// For the register operands, the virtual register type is as follows:
|
||||
//
|
||||
// - Reg will be of virtual register type MO_MInstrVirtualReg. The field
|
||||
// MachineInstr* minstr will point to the instruction that computes reg.
|
||||
//
|
||||
// - %sp will be of virtual register type MO_MachineReg.
|
||||
// The field regNum identifies the machine register.
|
||||
//
|
||||
// - NumElements will be of virtual register type MO_VirtualReg.
|
||||
// The field Value* value identifies the value.
|
||||
//
|
||||
// - Ptr will also be of virtual register type MO_VirtualReg.
|
||||
// Again, the field Value* value identifies the value.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class MachineOperand {
|
||||
public:
|
||||
friend ostream& operator<<(ostream& os, const MachineOperand& mop);
|
||||
|
||||
public:
|
||||
enum MachineOperandType {
|
||||
MO_Register,
|
||||
MO_CCRegister,
|
||||
MO_SignExtendedImmed,
|
||||
MO_UnextendedImmed,
|
||||
MO_PCRelativeDisp,
|
||||
};
|
||||
|
||||
enum VirtualRegisterType {
|
||||
MO_VirtualReg, // virtual register for *value
|
||||
MO_MachineReg // pre-assigned machine register `regNum'
|
||||
};
|
||||
|
||||
MachineOperandType machineOperandType;
|
||||
|
||||
VirtualRegisterType vregType;
|
||||
|
||||
Value* value; // BasicBlockVal for a label operand.
|
||||
// ConstantVal for a non-address immediate.
|
||||
// Virtual register for a register operand.
|
||||
|
||||
unsigned int regNum; // register number for an explicit register
|
||||
|
||||
int64_t immedVal; // constant value for an explicit constant
|
||||
|
||||
/*ctor*/ MachineOperand ();
|
||||
/*ctor*/ MachineOperand (MachineOperandType operandType,
|
||||
Value* _val);
|
||||
/*copy ctor*/ MachineOperand (const MachineOperand&);
|
||||
/*dtor*/ ~MachineOperand () {}
|
||||
|
||||
// These functions are provided so that a vector of operands can be
|
||||
// statically allocated and individual ones can be initialized later.
|
||||
//
|
||||
void Initialize (MachineOperandType operandType,
|
||||
Value* _val);
|
||||
void InitializeConst (MachineOperandType operandType,
|
||||
int64_t intValue);
|
||||
void InitializeReg (unsigned int regNum);
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
MachineOperand::MachineOperand()
|
||||
: machineOperandType(MO_Register),
|
||||
vregType(MO_VirtualReg),
|
||||
value(NULL),
|
||||
regNum(0),
|
||||
immedVal(0)
|
||||
{}
|
||||
|
||||
inline
|
||||
MachineOperand::MachineOperand(MachineOperandType operandType,
|
||||
Value* _val)
|
||||
: machineOperandType(operandType),
|
||||
vregType(MO_VirtualReg),
|
||||
value(_val),
|
||||
regNum(0),
|
||||
immedVal(0)
|
||||
{}
|
||||
|
||||
inline
|
||||
MachineOperand::MachineOperand(const MachineOperand& mo)
|
||||
: machineOperandType(mo.machineOperandType),
|
||||
vregType(mo.vregType),
|
||||
value(mo.value),
|
||||
regNum(mo.regNum),
|
||||
immedVal(mo.immedVal)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
MachineOperand::Initialize(MachineOperandType operandType,
|
||||
Value* _val)
|
||||
{
|
||||
machineOperandType = operandType;
|
||||
value = _val;
|
||||
}
|
||||
|
||||
inline void
|
||||
MachineOperand::InitializeConst(MachineOperandType operandType,
|
||||
int64_t intValue)
|
||||
{
|
||||
machineOperandType = operandType;
|
||||
value = NULL;
|
||||
immedVal = intValue;
|
||||
}
|
||||
|
||||
inline void
|
||||
MachineOperand::InitializeReg(unsigned int _regNum)
|
||||
{
|
||||
machineOperandType = MO_Register;
|
||||
vregType = MO_MachineReg;
|
||||
value = NULL;
|
||||
regNum = _regNum;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// class MachineInstr
|
||||
//
|
||||
// Purpose:
|
||||
// Representation of each machine instruction.
|
||||
//
|
||||
// MachineOpCode must be an enum, defined separately for each target.
|
||||
// E.g., It is defined in SparcInstructionSelection.h for the SPARC.
|
||||
// The array MachineInstrInfo TargetMachineInstrInfo[] objects
|
||||
// (indexed by opCode) provides information about each target instruction.
|
||||
//
|
||||
// opCodeMask is used to record variants of an instruction.
|
||||
// E.g., each branch instruction on SPARC has 2 flags (i.e., 4 variants):
|
||||
// ANNUL: if 1: Annul delay slot instruction.
|
||||
// PREDICT-NOT-TAKEN: if 1: predict branch not taken.
|
||||
// Instead of creating 4 different opcodes for BNZ, we create a single
|
||||
// opcode and set bits in opCodeMask for each of these flags.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class MachineInstr : public Unique {
|
||||
private:
|
||||
MachineOpCode opCode;
|
||||
OpCodeMask opCodeMask; // extra bits for variants of an opcode
|
||||
vector<MachineOperand> operands; // operand 0 is the result
|
||||
|
||||
public:
|
||||
/*ctor*/ MachineInstr (MachineOpCode _opCode,
|
||||
OpCodeMask _opCodeMask = 0x0);
|
||||
|
||||
/*dtor*/ virtual ~MachineInstr ();
|
||||
|
||||
const MachineOpCode getOpCode () const;
|
||||
|
||||
unsigned int getNumOperands () const;
|
||||
|
||||
const MachineOperand& getOperand (unsigned int i) const;
|
||||
|
||||
void dump (unsigned int indent = 0);
|
||||
|
||||
public:
|
||||
friend ostream& operator<<(ostream& os, const MachineInstr& minstr);
|
||||
|
||||
public:
|
||||
// Access to set the operands when building the machine instruction
|
||||
void SetMachineOperand(unsigned int i,
|
||||
MachineOperand::MachineOperandType operandType,
|
||||
Value* _val);
|
||||
void SetMachineOperand(unsigned int i,
|
||||
MachineOperand::MachineOperandType operandType,
|
||||
int64_t intValue);
|
||||
void SetMachineOperand(unsigned int i,
|
||||
unsigned int regNum);
|
||||
};
|
||||
|
||||
inline const MachineOpCode
|
||||
MachineInstr::getOpCode() const
|
||||
{
|
||||
return opCode;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
MachineInstr::getNumOperands() const
|
||||
{
|
||||
assert(operands.size() == TargetMachineInstrInfo[opCode].numOperands);
|
||||
return operands.size();
|
||||
}
|
||||
|
||||
inline const MachineOperand&
|
||||
MachineInstr::getOperand(unsigned int i) const
|
||||
{
|
||||
return operands[i];
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// class MachineInstructionsForVMInstr
|
||||
//
|
||||
// Purpose:
|
||||
// Representation of the sequence of machine instructions created
|
||||
// for a single VM instruction. Additionally records any temporary
|
||||
// "values" used as intermediate values in this sequence.
|
||||
// Note that such values should be treated as pure SSA values with
|
||||
// no interpretation of their operands (i.e., as a TmpInstruction object
|
||||
// which actually represents such a value).
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class MachineCodeForVMInstr: public vector<MachineInstr*>
|
||||
{
|
||||
private:
|
||||
vector<Value*> tempVec;
|
||||
|
||||
public:
|
||||
/*ctor*/ MachineCodeForVMInstr () {}
|
||||
/*ctor*/ ~MachineCodeForVMInstr ();
|
||||
|
||||
const vector<Value*>&
|
||||
getTempValues () const { return tempVec; }
|
||||
|
||||
void addTempValue (Value* val)
|
||||
{ tempVec.push_back(val); }
|
||||
|
||||
// dropAllReferences() - This function drops all references within
|
||||
// temporary (hidden) instructions created in implementing the original
|
||||
// VM intruction. This ensures there are no remaining "uses" within
|
||||
// these hidden instructions, before the values of a method are freed.
|
||||
//
|
||||
// Make this inline because it has to be called from class Instruction
|
||||
// and inlining it avoids a serious circurality in link order.
|
||||
inline void dropAllReferences() {
|
||||
for (unsigned i=0, N=tempVec.size(); i < N; i++)
|
||||
if (tempVec[i]->getValueType() == Value::InstructionVal)
|
||||
((Instruction*) tempVec[i])->dropAllReferences();
|
||||
}
|
||||
};
|
||||
|
||||
inline
|
||||
MachineCodeForVMInstr::~MachineCodeForVMInstr()
|
||||
{
|
||||
// Free the Value objects created to hold intermediate values
|
||||
for (unsigned i=0, N=tempVec.size(); i < N; i++)
|
||||
delete tempVec[i];
|
||||
|
||||
// Free the MachineInstr objects allocated, if any.
|
||||
for (unsigned i=0, N=this->size(); i < N; i++)
|
||||
delete (*this)[i];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Target-independent utility routines for creating machine instructions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Function Set2OperandsFromInstr
|
||||
// Function Set3OperandsFromInstr
|
||||
//
|
||||
// For the common case of 2- and 3-operand arithmetic/logical instructions,
|
||||
// set the m/c instr. operands directly from the VM instruction's operands.
|
||||
// Check whether the first or second operand is 0 and can use a dedicated
|
||||
// "0" register.
|
||||
// Check whether the second operand should use an immediate field or register.
|
||||
// (First and third operands are never immediates for such instructions.)
|
||||
//
|
||||
// Arguments:
|
||||
// canDiscardResult: Specifies that the result operand can be discarded
|
||||
// by using the dedicated "0"
|
||||
//
|
||||
// op1position, op2position and resultPosition: Specify in which position
|
||||
// in the machine instruction the 3 operands (arg1, arg2
|
||||
// and result) should go.
|
||||
//
|
||||
// RETURN VALUE: unsigned int flags, where
|
||||
// flags & 0x01 => operand 1 is constant and needs a register
|
||||
// flags & 0x02 => operand 2 is constant and needs a register
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
void Set2OperandsFromInstr (MachineInstr* minstr,
|
||||
InstructionNode* vmInstrNode,
|
||||
const TargetMachine& targetMachine,
|
||||
bool canDiscardResult = false,
|
||||
int op1Position = 0,
|
||||
int resultPosition = 1);
|
||||
|
||||
void Set3OperandsFromInstr (MachineInstr* minstr,
|
||||
InstructionNode* vmInstrNode,
|
||||
const TargetMachine& targetMachine,
|
||||
bool canDiscardResult = false,
|
||||
int op1Position = 0,
|
||||
int op2Position = 1,
|
||||
int resultPosition = 2);
|
||||
|
||||
MachineOperand::MachineOperandType
|
||||
ChooseRegOrImmed(Value* val,
|
||||
MachineOpCode opCode,
|
||||
const TargetMachine& targetMachine,
|
||||
bool canUseImmed,
|
||||
MachineOperand::VirtualRegisterType& getVRegType,
|
||||
unsigned int& getMachineRegNum,
|
||||
int64_t& getImmedValue);
|
||||
|
||||
ostream& operator<<(ostream& os, const MachineInstr& minstr);
|
||||
|
||||
|
||||
ostream& operator<<(ostream& os, const MachineOperand& mop);
|
||||
|
||||
|
||||
//**************************************************************************/
|
||||
|
||||
#endif
|
421
include/llvm/CodeGen/Sparc.h
Normal file
421
include/llvm/CodeGen/Sparc.h
Normal file
@ -0,0 +1,421 @@
|
||||
// $Id$ -*-c++-*-
|
||||
//***************************************************************************
|
||||
// File:
|
||||
// Sparc.cpp
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// History:
|
||||
// 7/15/01 - Vikram Adve - Created
|
||||
//**************************************************************************/
|
||||
|
||||
#ifndef LLVM_CODEGEN_SPARC_H
|
||||
#define LLVM_CODEGEN_SPARC_H
|
||||
|
||||
//************************** System Include Files **************************/
|
||||
|
||||
//*************************** User Include Files ***************************/
|
||||
|
||||
#include "llvm/Codegen/TargetMachine.h"
|
||||
#include "llvm/Codegen/MachineInstr.h"
|
||||
|
||||
|
||||
//************************* Opaque Declarations ****************************/
|
||||
|
||||
|
||||
//************************ Exported Constants ******************************/
|
||||
|
||||
|
||||
// OpCodeMask definitions for the Sparc V9
|
||||
//
|
||||
const OpCodeMask Immed = 0x00002000; // immed or reg operand?
|
||||
const OpCodeMask Annul = 0x20000000; // annul delay instr?
|
||||
const OpCodeMask PredictTaken = 0x00080000; // predict branch taken?
|
||||
|
||||
|
||||
//************************ Exported Data Types *****************************/
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// class UltraSparcMachine
|
||||
//
|
||||
// Purpose:
|
||||
// Machine description.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class UltraSparc: public TargetMachine {
|
||||
public:
|
||||
/*ctor*/ UltraSparc ();
|
||||
/*dtor*/ virtual ~UltraSparc () {}
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// enum SparcMachineOpCode.
|
||||
// const MachineInstrInfo SparcMachineInstrInfo[].
|
||||
//
|
||||
// Purpose:
|
||||
// Description of UltraSparc machine instructions.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
enum SparcMachineOpCode {
|
||||
|
||||
NOP,
|
||||
|
||||
// Synthetic SPARC assembly opcodes for setting a register to a constant
|
||||
SETSW,
|
||||
SETUW,
|
||||
|
||||
// Add or add with carry.
|
||||
// Immed bit specifies if second operand is immediate(1) or register(0)
|
||||
ADD,
|
||||
ADDcc,
|
||||
ADDC,
|
||||
ADDCcc,
|
||||
|
||||
// Subtract or subtract with carry.
|
||||
// Immed bit specifies if second operand is immediate(1) or register(0)
|
||||
SUB,
|
||||
SUBcc,
|
||||
SUBC,
|
||||
SUBCcc,
|
||||
|
||||
// Integer multiply, signed divide, unsigned divide.
|
||||
// Note that the deprecated 32-bit multiply and multiply-step are not used.
|
||||
MULX,
|
||||
SDIVX,
|
||||
UDIVX,
|
||||
|
||||
// Floating point add, subtract, compare
|
||||
FADDS,
|
||||
FADDD,
|
||||
FADDQ,
|
||||
FSUBS,
|
||||
FSUBD,
|
||||
FSUBQ,
|
||||
FCMPS,
|
||||
FCMPD,
|
||||
FCMPQ,
|
||||
// NOTE: FCMPE{S,D,Q}: FP Compare With Exception are currently unused!
|
||||
|
||||
// Floating point multiply or divide.
|
||||
FMULS,
|
||||
FMULD,
|
||||
FMULQ,
|
||||
FSMULD,
|
||||
FDMULQ,
|
||||
FDIVS,
|
||||
FDIVD,
|
||||
FDIVQ,
|
||||
|
||||
// Logical operations
|
||||
AND,
|
||||
ANDcc,
|
||||
ANDN,
|
||||
ANDNcc,
|
||||
OR,
|
||||
ORcc,
|
||||
ORN,
|
||||
ORNcc,
|
||||
XOR,
|
||||
XORcc,
|
||||
XNOR,
|
||||
XNORcc,
|
||||
|
||||
// Shift operations
|
||||
SLL,
|
||||
SRL,
|
||||
SRA,
|
||||
SLLX,
|
||||
SRLX,
|
||||
SRAX,
|
||||
|
||||
// Convert from floating point to floating point formats
|
||||
FSTOD,
|
||||
FSTOQ,
|
||||
FDTOS,
|
||||
FDTOQ,
|
||||
FQTOS,
|
||||
FQTOD,
|
||||
|
||||
// Convert from floating point to integer formats
|
||||
FSTOX,
|
||||
FDTOX,
|
||||
FQTOX,
|
||||
FSTOI,
|
||||
FDTOI,
|
||||
FQTOI,
|
||||
|
||||
// Convert from integer to floating point formats
|
||||
FXTOS,
|
||||
FXTOD,
|
||||
FXTOQ,
|
||||
FITOS,
|
||||
FITOD,
|
||||
FITOQ,
|
||||
|
||||
// Branch on integer comparison with zero.
|
||||
// Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
|
||||
// PredictTaken bit hints if branch should be predicted taken(1) or not(0).
|
||||
BRZ,
|
||||
BRLEZ,
|
||||
BRLZ,
|
||||
BRNZ,
|
||||
BRGZ,
|
||||
BRGEZ,
|
||||
|
||||
// Branch on integer condition code.
|
||||
// Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
|
||||
// PredictTaken bit hints if branch should be predicted taken(1) or not(0).
|
||||
BA,
|
||||
BN,
|
||||
BNE,
|
||||
BE,
|
||||
BG,
|
||||
BLE,
|
||||
BGE,
|
||||
BL,
|
||||
BGU,
|
||||
BLEU,
|
||||
BCC,
|
||||
BCS,
|
||||
BPOS,
|
||||
BNEG,
|
||||
BVC,
|
||||
BVS,
|
||||
|
||||
// Branch on floating point condition code.
|
||||
// Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
|
||||
// PredictTaken bit hints if branch should be predicted taken(1) or not(0).
|
||||
FBA,
|
||||
FBN,
|
||||
FBU,
|
||||
FBG,
|
||||
FBUG,
|
||||
FBL,
|
||||
FBUL,
|
||||
FBLG,
|
||||
FBNE,
|
||||
FBE,
|
||||
FBUE,
|
||||
FBGE,
|
||||
FBUGE,
|
||||
FBLE,
|
||||
FBULE,
|
||||
FBO,
|
||||
|
||||
// Load integer instructions
|
||||
LDSB,
|
||||
LDSH,
|
||||
LDSW,
|
||||
LDUB,
|
||||
LDUH,
|
||||
LDUW,
|
||||
LDX,
|
||||
|
||||
// Load floating-point instructions
|
||||
LD,
|
||||
LDD, // use of this for integers is deprecated for Sparc V9
|
||||
LDQ,
|
||||
|
||||
// Store integer instructions
|
||||
STB,
|
||||
STH,
|
||||
STW,
|
||||
STX,
|
||||
|
||||
// Store floating-point instructions
|
||||
ST,
|
||||
STD,
|
||||
|
||||
// Call, Return, and "Jump and link"
|
||||
// Immed bit specifies if second operand is immediate(1) or register(0)
|
||||
CALL,
|
||||
JMPL,
|
||||
RETURN,
|
||||
|
||||
// End-of-array marker
|
||||
INVALID_OPCODE
|
||||
};
|
||||
|
||||
const MachineInstrInfo SparcMachineInstrInfo[] = {
|
||||
|
||||
{ "NOP", 0, -1, 0, false },
|
||||
|
||||
// Synthetic SPARC assembly opcodes for setting a register to a constant
|
||||
{ "SETSW", 2, 1, 0, true }, // max immediate constant is ignored
|
||||
{ "SETUW", 2, 1, 0, false }, // max immediate constant is ignored
|
||||
|
||||
// Add or add with carry.
|
||||
{ "ADD", 3, 2, (1 << 12) - 1, true },
|
||||
{ "ADDcc", 3, 2, (1 << 12) - 1, true },
|
||||
{ "ADDC", 3, 2, (1 << 12) - 1, true },
|
||||
{ "ADDCcc", 3, 2, (1 << 12) - 1, true },
|
||||
|
||||
// Sub tract or subtract with carry.
|
||||
{ "SUB", 3, 2, (1 << 12) - 1, true },
|
||||
{ "SUBcc", 3, 2, (1 << 12) - 1, true },
|
||||
{ "SUBC", 3, 2, (1 << 12) - 1, true },
|
||||
{ "SUBCcc", 3, 2, (1 << 12) - 1, true },
|
||||
|
||||
// Integer multiply, signed divide, unsigned divide.
|
||||
// Note that the deprecated 32-bit multiply and multiply-step are not used.
|
||||
{ "MULX", 3, 2, (1 << 12) - 1, true },
|
||||
{ "SDIVX", 3, 2, (1 << 12) - 1, true },
|
||||
{ "UDIVX", 3, 2, (1 << 12) - 1, true },
|
||||
|
||||
// Floating point add, subtract, compare
|
||||
{ "FADDS", 3, 2, 0, false },
|
||||
{ "FADDD", 3, 2, 0, false },
|
||||
{ "FADDQ", 3, 2, 0, false },
|
||||
{ "FSUBS", 3, 2, 0, false },
|
||||
{ "FSUBD", 3, 2, 0, false },
|
||||
{ "FSUBQ", 3, 2, 0, false },
|
||||
{ "FCMPS", 3, 2, 0, false },
|
||||
{ "FCMPD", 3, 2, 0, false },
|
||||
{ "FCMPQ", 3, 2, 0, false },
|
||||
// NOTE: FCMPE{S,D,Q}: FP Compare With Exception are currently unused!
|
||||
|
||||
// Floating point multiply or divide.
|
||||
{ "FMULS", 3, 2, 0, false },
|
||||
{ "FMULD", 3, 2, 0, false },
|
||||
{ "FMULQ", 3, 2, 0, false },
|
||||
{ "FSMULD", 3, 2, 0, false },
|
||||
{ "FDMULQ", 3, 2, 0, false },
|
||||
{ "FDIVS", 3, 2, 0, false },
|
||||
{ "FDIVD", 3, 2, 0, false },
|
||||
{ "FDIVQ", 3, 2, 0, false },
|
||||
|
||||
// Logical operations
|
||||
{ "AND", 3, 2, (1 << 12) - 1, true },
|
||||
{ "ANDcc", 3, 2, (1 << 12) - 1, true },
|
||||
{ "ANDN", 3, 2, (1 << 12) - 1, true },
|
||||
{ "ANDNcc", 3, 2, (1 << 12) - 1, true },
|
||||
{ "OR", 3, 2, (1 << 12) - 1, true },
|
||||
{ "ORcc", 3, 2, (1 << 12) - 1, true },
|
||||
{ "ORN", 3, 2, (1 << 12) - 1, true },
|
||||
{ "ORNcc", 3, 2, (1 << 12) - 1, true },
|
||||
{ "XOR", 3, 2, (1 << 12) - 1, true },
|
||||
{ "XORcc", 3, 2, (1 << 12) - 1, true },
|
||||
{ "XNOR", 3, 2, (1 << 12) - 1, true },
|
||||
{ "XNORcc", 3, 2, (1 << 12) - 1, true },
|
||||
|
||||
// Shift operations
|
||||
{ "SLL", 3, 2, (1 << 5) - 1, true },
|
||||
{ "SRL", 3, 2, (1 << 5) - 1, true },
|
||||
{ "SRA", 3, 2, (1 << 5) - 1, true },
|
||||
{ "SLLX", 3, 2, (1 << 6) - 1, true },
|
||||
{ "SRLX", 3, 2, (1 << 6) - 1, true },
|
||||
{ "SRAX", 3, 2, (1 << 6) - 1, true },
|
||||
|
||||
// Convert from floating point to floating point formats
|
||||
{ "FSTOD", 2, 1, 0, false },
|
||||
{ "FSTOQ", 2, 1, 0, false },
|
||||
{ "FDTOS", 2, 1, 0, false },
|
||||
{ "FDTOQ", 2, 1, 0, false },
|
||||
{ "FQTOS", 2, 1, 0, false },
|
||||
{ "FQTOD", 2, 1, 0, false },
|
||||
|
||||
// Convert from floating point to integer formats
|
||||
{ "FSTOX", 2, 1, 0, false },
|
||||
{ "FDTOX", 2, 1, 0, false },
|
||||
{ "FQTOX", 2, 1, 0, false },
|
||||
{ "FSTOI", 2, 1, 0, false },
|
||||
{ "FDTOI", 2, 1, 0, false },
|
||||
{ "FQTOI", 2, 1, 0, false },
|
||||
|
||||
// Convert from integer to floating point formats
|
||||
{ "FXTOS", 2, 1, 0, false },
|
||||
{ "FXTOD", 2, 1, 0, false },
|
||||
{ "FXTOQ", 2, 1, 0, false },
|
||||
{ "FITOS", 2, 1, 0, false },
|
||||
{ "FITOD", 2, 1, 0, false },
|
||||
{ "FITOQ", 2, 1, 0, false },
|
||||
|
||||
// Branch on integer comparison with zero.
|
||||
{ "BRZ", 2, -1, (1 << 15) - 1, true },
|
||||
{ "BRLEZ", 2, -1, (1 << 15) - 1, true },
|
||||
{ "BRLZ", 2, -1, (1 << 15) - 1, true },
|
||||
{ "BRNZ", 2, -1, (1 << 15) - 1, true },
|
||||
{ "BRGZ", 2, -1, (1 << 15) - 1, true },
|
||||
{ "BRGEZ", 2, -1, (1 << 15) - 1, true },
|
||||
|
||||
// Branch on condition code.
|
||||
{ "BA", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BN", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BNE", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BE", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BG", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BLE", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BGE", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BL", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BGU", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BLEU", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BCC", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BCS", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BPOS", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BNEG", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BVC", 1, -1, (1 << 21) - 1, true },
|
||||
{ "BVS", 1, -1, (1 << 21) - 1, true },
|
||||
|
||||
// Branch on floating point condition code.
|
||||
// Annul bit specifies if intruction in delay slot is annulled(1) or not(0).
|
||||
// PredictTaken bit hints if branch should be predicted taken(1) or not(0).
|
||||
// The first argument is the FCCn register (0 <= n <= 3).
|
||||
{ "FBA", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBN", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBU", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBG", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBUG", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBL", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBUL", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBLG", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBNE", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBE", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBUE", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBGE", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBUGE", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBLE", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBULE", 2, -1, (1 << 18) - 1, true },
|
||||
{ "FBO", 2, -1, (1 << 18) - 1, true },
|
||||
|
||||
// Load integer instructions
|
||||
{ "LDSB", 3, 2, (1 << 12) - 1, true },
|
||||
{ "LDSH", 3, 2, (1 << 12) - 1, true },
|
||||
{ "LDSW", 3, 2, (1 << 12) - 1, true },
|
||||
{ "LDUB", 3, 2, (1 << 12) - 1, true },
|
||||
{ "LDUH", 3, 2, (1 << 12) - 1, true },
|
||||
{ "LDUW", 3, 2, (1 << 12) - 1, true },
|
||||
{ "LDX", 3, 2, (1 << 12) - 1, true },
|
||||
|
||||
// Load floating-point instructions
|
||||
{ "LD", 3, 2, (1 << 12) - 1, true },
|
||||
{ "LDD", 3, 2, (1 << 12) - 1, true },
|
||||
{ "LDQ", 3, 2, (1 << 12) - 1, true },
|
||||
|
||||
// Store integer instructions
|
||||
{ "STB", 3, -1, (1 << 12) - 1, true },
|
||||
{ "STH", 3, -1, (1 << 12) - 1, true },
|
||||
{ "STW", 3, -1, (1 << 12) - 1, true },
|
||||
{ "STX", 3, -1, (1 << 12) - 1, true },
|
||||
|
||||
// Store floating-point instructions
|
||||
{ "ST", 3, -1, (1 << 12) - 1, true },
|
||||
{ "STD", 3, -1, (1 << 12) - 1, true },
|
||||
|
||||
// Call, Return and "Jump and link"
|
||||
{ "CALL", 1, -1, (1 << 29) - 1, true },
|
||||
{ "JMPL", 3, -1, (1 << 12) - 1, true },
|
||||
{ "RETURN", 2, -1, 0, false },
|
||||
|
||||
// End-of-array marker
|
||||
{ "INVALID_SPARC_OPCODE", 0, -1, 0, false }
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#endif
|
111
include/llvm/CodeGen/TargetMachine.h
Normal file
111
include/llvm/CodeGen/TargetMachine.h
Normal file
@ -0,0 +1,111 @@
|
||||
// $Id$ -*-c++-*-
|
||||
//***************************************************************************
|
||||
// File:
|
||||
// TargetMachine.h
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// History:
|
||||
// 7/12/01 - Vikram Adve - Created
|
||||
//**************************************************************************/
|
||||
|
||||
#ifndef LLVM_CODEGEN_TARGETMACHINE_H
|
||||
#define LLVM_CODEGEN_TARGETMACHINE_H
|
||||
|
||||
//************************** System Include Files **************************/
|
||||
|
||||
//*************************** User Include Files ***************************/
|
||||
|
||||
#include "llvm/Support/Unique.h"
|
||||
#include "llvm/Tools/DataTypes.h"
|
||||
|
||||
//************************* Opaque Declarations ****************************/
|
||||
|
||||
class Type;
|
||||
class StructType;
|
||||
class MachineInstrInfo;
|
||||
|
||||
|
||||
//************************ Exported Data Types *****************************/
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Data types used to define information about a single machine instruction
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
typedef int MachineOpCode;
|
||||
typedef int OpCodeMask;
|
||||
|
||||
|
||||
// struct MachineInstrInfo:
|
||||
// Predefined information about each machine instruction.
|
||||
//
|
||||
struct MachineInstrInfo {
|
||||
string opCodeString; // Assembly language mnemonic for the opcode.
|
||||
unsigned int numOperands; // Number of arguments for the instruction.
|
||||
int resultPos; // Position of the result; -1 if no result
|
||||
unsigned int maxImmedConst; // Largest +ve constant in IMMMED field or 0.
|
||||
bool immedIsSignExtended; // Is the IMMED field sign-extended? If so,
|
||||
// smallest -ve value is -(maxImmedConst+1).
|
||||
|
||||
|
||||
// Check if the specified constant fits in the immediate field
|
||||
// of this machine instruction
|
||||
//
|
||||
bool constantFitsInImmedField (int64_t intValue) const;
|
||||
|
||||
// Return the largest +ve constant that can be held in the IMMMED field
|
||||
// of this machine instruction.
|
||||
// isSignExtended is set to true if the value is sign-extended before use
|
||||
// (this is true for all immediate fields in SPARC instructions).
|
||||
// Return 0 if the instruction has no IMMED field.
|
||||
//
|
||||
inline uint64_t maxImmedConstant(bool& isSignExtended) const {
|
||||
isSignExtended = immedIsSignExtended;
|
||||
return maxImmedConst; }
|
||||
};
|
||||
|
||||
// Global variable holding an array of the above structures.
|
||||
// This needs to be defined separately for each target machine.
|
||||
//
|
||||
extern const MachineInstrInfo* TargetMachineInstrInfo;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// class TargetMachine
|
||||
//
|
||||
// Purpose:
|
||||
// Machine description.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class TargetMachine: public Unique {
|
||||
public:
|
||||
int optSizeForSubWordData;
|
||||
int intSize;
|
||||
int longSize;
|
||||
int floatSize;
|
||||
int doubleSize;
|
||||
int longDoubleSize;
|
||||
int pointerSize;
|
||||
int minMemOpWordSize;
|
||||
int maxAtomicMemOpWordSize;
|
||||
|
||||
// Description of machine instructions (array indexed by machine opcode)
|
||||
const MachineInstrInfo* machineInstrInfo;
|
||||
|
||||
// Register information. This needs to be reorganized into a single class.
|
||||
int zeroRegNum; // register that gives 0 if any (-1 if none)
|
||||
|
||||
public:
|
||||
/*ctor*/ TargetMachine () {}
|
||||
/*dtor*/ virtual ~TargetMachine () {}
|
||||
|
||||
virtual unsigned int findOptimalStorageSize (const Type* ty) const;
|
||||
|
||||
virtual unsigned int* findOptimalMemberOffsets(const StructType* stype)const;
|
||||
};
|
||||
|
||||
//**************************************************************************/
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user