forked from OSchip/llvm-project
Eliminate separate enum for operand register type.
Use union for alternative data for different operand types. Add iterator over Value* operands in a MachineInstr. llvm-svn: 307
This commit is contained in:
parent
3a7aa63841
commit
bff682dfac
|
@ -15,11 +15,15 @@
|
||||||
#ifndef LLVM_CODEGEN_MACHINEINSTR_H
|
#ifndef LLVM_CODEGEN_MACHINEINSTR_H
|
||||||
#define LLVM_CODEGEN_MACHINEINSTR_H
|
#define LLVM_CODEGEN_MACHINEINSTR_H
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include "llvm/CodeGen/InstrForest.h"
|
#include "llvm/CodeGen/InstrForest.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include "llvm/Support/NonCopyable.h"
|
#include "llvm/Support/NonCopyable.h"
|
||||||
#include "llvm/CodeGen/TargetMachine.h"
|
#include "llvm/CodeGen/TargetMachine.h"
|
||||||
|
|
||||||
|
template<class _MI, class _V> class ValOpIterator;
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// class MachineOperand
|
// class MachineOperand
|
||||||
//
|
//
|
||||||
|
@ -56,56 +60,78 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
class MachineOperand {
|
class MachineOperand {
|
||||||
public:
|
|
||||||
friend ostream& operator<<(ostream& os, const MachineOperand& mop);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum MachineOperandType {
|
enum MachineOperandType {
|
||||||
MO_Register,
|
MO_VirtualRegister, // virtual register for *value
|
||||||
|
MO_MachineRegister, // pre-assigned machine register `regNum'
|
||||||
MO_CCRegister,
|
MO_CCRegister,
|
||||||
MO_SignExtendedImmed,
|
MO_SignExtendedImmed,
|
||||||
MO_UnextendedImmed,
|
MO_UnextendedImmed,
|
||||||
MO_PCRelativeDisp,
|
MO_PCRelativeDisp,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum VirtualRegisterType {
|
private:
|
||||||
MO_VirtualReg, // virtual register for *value
|
MachineOperandType opType;
|
||||||
MO_MachineReg // pre-assigned machine register `regNum'
|
|
||||||
|
union {
|
||||||
|
Value* value; // BasicBlockVal for a label operand.
|
||||||
|
// ConstantVal for a non-address immediate.
|
||||||
|
// Virtual register for an SSA operand,
|
||||||
|
// including hidden operands required for
|
||||||
|
// the generated machine code.
|
||||||
|
|
||||||
|
unsigned int regNum; // register number for an explicit register
|
||||||
|
|
||||||
|
int64_t immedVal; // constant value for an explicit constant
|
||||||
};
|
};
|
||||||
|
|
||||||
MachineOperandType machineOperandType;
|
public:
|
||||||
|
|
||||||
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 ();
|
||||||
/*ctor*/ MachineOperand (MachineOperandType operandType,
|
/*ctor*/ MachineOperand (MachineOperandType operandType,
|
||||||
Value* _val);
|
Value* _val);
|
||||||
/*copy ctor*/ MachineOperand (const MachineOperand&);
|
/*copy ctor*/ MachineOperand (const MachineOperand&);
|
||||||
/*dtor*/ ~MachineOperand () {}
|
/*dtor*/ ~MachineOperand () {}
|
||||||
|
|
||||||
|
// Accessor methods. Caller is responsible for checking the
|
||||||
|
// operand type before invoking the corresponding accessor.
|
||||||
|
//
|
||||||
|
MachineOperandType getOperandType () const {
|
||||||
|
return opType;
|
||||||
|
}
|
||||||
|
Value* getVRegValue () const {
|
||||||
|
assert(opType == MO_VirtualRegister || opType == MO_CCRegister);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
unsigned int getMachineRegNum() const {
|
||||||
|
assert(opType == MO_MachineRegister);
|
||||||
|
return regNum;
|
||||||
|
}
|
||||||
|
int64_t getImmedValue () const {
|
||||||
|
assert(opType >= MO_SignExtendedImmed || opType <= MO_PCRelativeDisp);
|
||||||
|
return immedVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend ostream& operator<<(ostream& os, const MachineOperand& mop);
|
||||||
|
|
||||||
|
private:
|
||||||
// These functions are provided so that a vector of operands can be
|
// These functions are provided so that a vector of operands can be
|
||||||
// statically allocated and individual ones can be initialized later.
|
// statically allocated and individual ones can be initialized later.
|
||||||
|
// Give class MachineInstr gets access to these functions.
|
||||||
//
|
//
|
||||||
void Initialize (MachineOperandType operandType,
|
void Initialize (MachineOperandType operandType,
|
||||||
Value* _val);
|
Value* _val);
|
||||||
void InitializeConst (MachineOperandType operandType,
|
void InitializeConst (MachineOperandType operandType,
|
||||||
int64_t intValue);
|
int64_t intValue);
|
||||||
void InitializeReg (unsigned int regNum);
|
void InitializeReg (unsigned int regNum);
|
||||||
|
|
||||||
|
friend class MachineInstr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
MachineOperand::MachineOperand()
|
MachineOperand::MachineOperand()
|
||||||
: machineOperandType(MO_Register),
|
: opType(MO_VirtualRegister),
|
||||||
vregType(MO_VirtualReg),
|
|
||||||
value(NULL),
|
value(NULL),
|
||||||
regNum(0),
|
regNum(0),
|
||||||
immedVal(0)
|
immedVal(0)
|
||||||
|
@ -114,8 +140,7 @@ MachineOperand::MachineOperand()
|
||||||
inline
|
inline
|
||||||
MachineOperand::MachineOperand(MachineOperandType operandType,
|
MachineOperand::MachineOperand(MachineOperandType operandType,
|
||||||
Value* _val)
|
Value* _val)
|
||||||
: machineOperandType(operandType),
|
: opType(operandType),
|
||||||
vregType(MO_VirtualReg),
|
|
||||||
value(_val),
|
value(_val),
|
||||||
regNum(0),
|
regNum(0),
|
||||||
immedVal(0)
|
immedVal(0)
|
||||||
|
@ -123,19 +148,24 @@ MachineOperand::MachineOperand(MachineOperandType operandType,
|
||||||
|
|
||||||
inline
|
inline
|
||||||
MachineOperand::MachineOperand(const MachineOperand& mo)
|
MachineOperand::MachineOperand(const MachineOperand& mo)
|
||||||
: machineOperandType(mo.machineOperandType),
|
: opType(mo.opType)
|
||||||
vregType(mo.vregType),
|
|
||||||
value(mo.value),
|
|
||||||
regNum(mo.regNum),
|
|
||||||
immedVal(mo.immedVal)
|
|
||||||
{
|
{
|
||||||
|
switch(opType) {
|
||||||
|
case MO_VirtualRegister:
|
||||||
|
case MO_CCRegister: value = mo.value; break;
|
||||||
|
case MO_MachineRegister: regNum = mo.regNum; break;
|
||||||
|
case MO_SignExtendedImmed:
|
||||||
|
case MO_UnextendedImmed:
|
||||||
|
case MO_PCRelativeDisp: immedVal = mo.immedVal; break;
|
||||||
|
default: assert(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
MachineOperand::Initialize(MachineOperandType operandType,
|
MachineOperand::Initialize(MachineOperandType operandType,
|
||||||
Value* _val)
|
Value* _val)
|
||||||
{
|
{
|
||||||
machineOperandType = operandType;
|
opType = operandType;
|
||||||
value = _val;
|
value = _val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +173,7 @@ inline void
|
||||||
MachineOperand::InitializeConst(MachineOperandType operandType,
|
MachineOperand::InitializeConst(MachineOperandType operandType,
|
||||||
int64_t intValue)
|
int64_t intValue)
|
||||||
{
|
{
|
||||||
machineOperandType = operandType;
|
opType = operandType;
|
||||||
value = NULL;
|
value = NULL;
|
||||||
immedVal = intValue;
|
immedVal = intValue;
|
||||||
}
|
}
|
||||||
|
@ -151,8 +181,7 @@ MachineOperand::InitializeConst(MachineOperandType operandType,
|
||||||
inline void
|
inline void
|
||||||
MachineOperand::InitializeReg(unsigned int _regNum)
|
MachineOperand::InitializeReg(unsigned int _regNum)
|
||||||
{
|
{
|
||||||
machineOperandType = MO_Register;
|
opType = MO_MachineRegister;
|
||||||
vregType = MO_MachineReg;
|
|
||||||
value = NULL;
|
value = NULL;
|
||||||
regNum = _regNum;
|
regNum = _regNum;
|
||||||
}
|
}
|
||||||
|
@ -166,8 +195,6 @@ MachineOperand::InitializeReg(unsigned int _regNum)
|
||||||
//
|
//
|
||||||
// MachineOpCode must be an enum, defined separately for each target.
|
// MachineOpCode must be an enum, defined separately for each target.
|
||||||
// E.g., It is defined in SparcInstructionSelection.h for the SPARC.
|
// 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.
|
// opCodeMask is used to record variants of an instruction.
|
||||||
// E.g., each branch instruction on SPARC has 2 flags (i.e., 4 variants):
|
// E.g., each branch instruction on SPARC has 2 flags (i.e., 4 variants):
|
||||||
|
@ -181,12 +208,15 @@ class MachineInstr : public NonCopyable {
|
||||||
private:
|
private:
|
||||||
MachineOpCode opCode;
|
MachineOpCode opCode;
|
||||||
OpCodeMask opCodeMask; // extra bits for variants of an opcode
|
OpCodeMask opCodeMask; // extra bits for variants of an opcode
|
||||||
vector<MachineOperand> operands; // operand 0 is the result
|
vector<MachineOperand> operands;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef ValOpIterator<const MachineInstr, const Value> val_op_const_iterator;
|
||||||
|
typedef ValOpIterator< MachineInstr, Value> val_op_iterator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*ctor*/ MachineInstr (MachineOpCode _opCode,
|
/*ctor*/ MachineInstr (MachineOpCode _opCode,
|
||||||
OpCodeMask _opCodeMask = 0x0);
|
OpCodeMask _opCodeMask = 0x0);
|
||||||
|
|
||||||
inline ~MachineInstr () {}
|
inline ~MachineInstr () {}
|
||||||
|
|
||||||
const MachineOpCode getOpCode () const;
|
const MachineOpCode getOpCode () const;
|
||||||
|
@ -194,11 +224,14 @@ public:
|
||||||
unsigned int getNumOperands () const;
|
unsigned int getNumOperands () const;
|
||||||
|
|
||||||
const MachineOperand& getOperand (unsigned int i) const;
|
const MachineOperand& getOperand (unsigned int i) const;
|
||||||
|
MachineOperand& getOperand (unsigned int i);
|
||||||
|
|
||||||
void dump (unsigned int indent = 0);
|
void dump (unsigned int indent = 0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
friend ostream& operator<<(ostream& os, const MachineInstr& minstr);
|
friend ostream& operator<<(ostream& os, const MachineInstr& minstr);
|
||||||
|
friend val_op_const_iterator;
|
||||||
|
friend val_op_iterator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Access to set the operands when building the machine instruction
|
// Access to set the operands when building the machine instruction
|
||||||
|
@ -221,10 +254,15 @@ MachineInstr::getOpCode() const
|
||||||
inline unsigned int
|
inline unsigned int
|
||||||
MachineInstr::getNumOperands() const
|
MachineInstr::getNumOperands() const
|
||||||
{
|
{
|
||||||
assert(operands.size() == TargetMachineInstrInfo[opCode].numOperands);
|
|
||||||
return operands.size();
|
return operands.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline MachineOperand&
|
||||||
|
MachineInstr::getOperand(unsigned int i)
|
||||||
|
{
|
||||||
|
return operands[i];
|
||||||
|
}
|
||||||
|
|
||||||
inline const MachineOperand&
|
inline const MachineOperand&
|
||||||
MachineInstr::getOperand(unsigned int i) const
|
MachineInstr::getOperand(unsigned int i) const
|
||||||
{
|
{
|
||||||
|
@ -232,6 +270,38 @@ MachineInstr::getOperand(unsigned int i) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class _MI, class _V>
|
||||||
|
class ValOpIterator : public std::forward_iterator<_V, ptrdiff_t> {
|
||||||
|
private:
|
||||||
|
unsigned int i;
|
||||||
|
int resultPos;
|
||||||
|
_MI*& minstr;
|
||||||
|
|
||||||
|
inline void skipToNextVal() {
|
||||||
|
while (i < minstr->getNumOperands()
|
||||||
|
&& minstr->getOperand(i).getOperandType() != MachineOperand::MO_VirtualRegister
|
||||||
|
&& minstr->getOperand(i).getOperandType() != MachineOperand::MO_CCRegister)
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef ValOpIterator<_MI, _V> _Self;
|
||||||
|
|
||||||
|
inline ValOpIterator(_MI* _minstr) : i(0), minstr(_minstr) {
|
||||||
|
resultPos = TargetInstrDescriptors[minstr->opCode].resultPos;
|
||||||
|
skipToNextVal();
|
||||||
|
};
|
||||||
|
|
||||||
|
inline _V* operator*() const { return minstr->getOperand(i).getVRegValue();}
|
||||||
|
inline _V* operator->() const { return operator*(); }
|
||||||
|
inline bool isDef () const { return (((int) i) == resultPos); }
|
||||||
|
inline bool done () const { return (i == minstr->getNumOperands()); }
|
||||||
|
|
||||||
|
inline _Self& operator++() { i++; skipToNextVal(); return *this; }
|
||||||
|
inline _Self operator++(int) { _Self tmp = *this; ++*this; return tmp; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// class MachineInstructionsForVMInstr
|
// class MachineInstructionsForVMInstr
|
||||||
//
|
//
|
||||||
|
@ -332,12 +402,11 @@ void Set3OperandsFromInstr (MachineInstr* minstr,
|
||||||
|
|
||||||
MachineOperand::MachineOperandType
|
MachineOperand::MachineOperandType
|
||||||
ChooseRegOrImmed(Value* val,
|
ChooseRegOrImmed(Value* val,
|
||||||
MachineOpCode opCode,
|
MachineOpCode opCode,
|
||||||
const TargetMachine& targetMachine,
|
const TargetMachine& targetMachine,
|
||||||
bool canUseImmed,
|
bool canUseImmed,
|
||||||
MachineOperand::VirtualRegisterType& getVRegType,
|
unsigned int& getMachineRegNum,
|
||||||
unsigned int& getMachineRegNum,
|
int64_t& getImmedValue);
|
||||||
int64_t& getImmedValue);
|
|
||||||
|
|
||||||
ostream& operator<<(ostream& os, const MachineInstr& minstr);
|
ostream& operator<<(ostream& os, const MachineInstr& minstr);
|
||||||
|
|
||||||
|
|
|
@ -20,28 +20,11 @@
|
||||||
//************************ Class Implementations **************************/
|
//************************ Class Implementations **************************/
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
MachineInstrInfo::constantFitsInImmedField(int64_t intValue) const
|
|
||||||
{
|
|
||||||
// First, check if opCode has an immed field.
|
|
||||||
bool isSignExtended;
|
|
||||||
uint64_t maxImmedValue = this->maxImmedConstant(isSignExtended);
|
|
||||||
if (maxImmedValue != 0)
|
|
||||||
{
|
|
||||||
// Now check if the constant fits
|
|
||||||
if (intValue <= (int64_t) maxImmedValue &&
|
|
||||||
intValue >= -((int64_t) maxImmedValue+1))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MachineInstr::MachineInstr(MachineOpCode _opCode,
|
MachineInstr::MachineInstr(MachineOpCode _opCode,
|
||||||
OpCodeMask _opCodeMask)
|
OpCodeMask _opCodeMask)
|
||||||
: opCode(_opCode),
|
: opCode(_opCode),
|
||||||
opCodeMask(_opCodeMask),
|
opCodeMask(_opCodeMask),
|
||||||
operands(TargetMachineInstrInfo[_opCode].numOperands)
|
operands(TargetInstrDescriptors[_opCode].numOperands)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +33,7 @@ MachineInstr::SetMachineOperand(unsigned int i,
|
||||||
MachineOperand::MachineOperandType operandType,
|
MachineOperand::MachineOperandType operandType,
|
||||||
Value* _val)
|
Value* _val)
|
||||||
{
|
{
|
||||||
assert(i < TargetMachineInstrInfo[opCode].numOperands);
|
assert(i < operands.size());
|
||||||
operands[i].Initialize(operandType, _val);
|
operands[i].Initialize(operandType, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +42,7 @@ MachineInstr::SetMachineOperand(unsigned int i,
|
||||||
MachineOperand::MachineOperandType operandType,
|
MachineOperand::MachineOperandType operandType,
|
||||||
int64_t intValue)
|
int64_t intValue)
|
||||||
{
|
{
|
||||||
assert(i < TargetMachineInstrInfo[opCode].numOperands);
|
assert(i < operands.size());
|
||||||
operands[i].InitializeConst(operandType, intValue);
|
operands[i].InitializeConst(operandType, intValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +50,7 @@ void
|
||||||
MachineInstr::SetMachineOperand(unsigned int i,
|
MachineInstr::SetMachineOperand(unsigned int i,
|
||||||
unsigned int regNum)
|
unsigned int regNum)
|
||||||
{
|
{
|
||||||
assert(i < TargetMachineInstrInfo[opCode].numOperands);
|
assert(i < operands.size());
|
||||||
operands[i].InitializeReg(regNum);
|
operands[i].InitializeReg(regNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,11 +66,22 @@ MachineInstr::dump(unsigned int indent)
|
||||||
ostream&
|
ostream&
|
||||||
operator<< (ostream& os, const MachineInstr& minstr)
|
operator<< (ostream& os, const MachineInstr& minstr)
|
||||||
{
|
{
|
||||||
os << TargetMachineInstrInfo[minstr.opCode].opCodeString;
|
os << TargetInstrDescriptors[minstr.opCode].opCodeString;
|
||||||
|
|
||||||
for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
|
for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
|
||||||
os << "\t" << minstr.getOperand(i);
|
os << "\t" << minstr.getOperand(i);
|
||||||
|
|
||||||
|
#undef DEBUG_VAL_OP_ITERATOR
|
||||||
|
#ifdef DEBUG_VAL_OP_ITERATOR
|
||||||
|
os << endl << "\tValue operands are: ";
|
||||||
|
for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
|
||||||
|
{
|
||||||
|
const Value* val = *vo;
|
||||||
|
os << val << (vo.isDef()? "(def), " : ", ");
|
||||||
|
}
|
||||||
|
os << endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,19 +89,17 @@ ostream&
|
||||||
operator<< (ostream& os, const MachineOperand& mop)
|
operator<< (ostream& os, const MachineOperand& mop)
|
||||||
{
|
{
|
||||||
strstream regInfo;
|
strstream regInfo;
|
||||||
if (mop.machineOperandType == MachineOperand::MO_Register)
|
if (mop.opType == MachineOperand::MO_VirtualRegister)
|
||||||
{
|
regInfo << "(val " << mop.value << ")" << ends;
|
||||||
if (mop.vregType == MachineOperand::MO_VirtualReg)
|
else if (mop.opType == MachineOperand::MO_MachineRegister)
|
||||||
regInfo << "(val " << mop.value << ")" << ends;
|
regInfo << "(" << mop.regNum << ")" << ends;
|
||||||
else
|
else if (mop.opType == MachineOperand::MO_CCRegister)
|
||||||
regInfo << "(" << mop.regNum << ")" << ends;
|
|
||||||
}
|
|
||||||
else if (mop.machineOperandType == MachineOperand::MO_CCRegister)
|
|
||||||
regInfo << "(val " << mop.value << ")" << ends;
|
regInfo << "(val " << mop.value << ")" << ends;
|
||||||
|
|
||||||
switch(mop.machineOperandType)
|
switch(mop.opType)
|
||||||
{
|
{
|
||||||
case MachineOperand::MO_Register:
|
case MachineOperand::MO_VirtualRegister:
|
||||||
|
case MachineOperand::MO_MachineRegister:
|
||||||
os << "%reg" << regInfo.str();
|
os << "%reg" << regInfo.str();
|
||||||
free(regInfo.str());
|
free(regInfo.str());
|
||||||
break;
|
break;
|
||||||
|
@ -169,21 +161,22 @@ operator<< (ostream& os, const MachineOperand& mop)
|
||||||
void
|
void
|
||||||
Set2OperandsFromInstr(MachineInstr* minstr,
|
Set2OperandsFromInstr(MachineInstr* minstr,
|
||||||
InstructionNode* vmInstrNode,
|
InstructionNode* vmInstrNode,
|
||||||
const TargetMachine& targetMachine,
|
const TargetMachine& target,
|
||||||
bool canDiscardResult,
|
bool canDiscardResult,
|
||||||
int op1Position,
|
int op1Position,
|
||||||
int resultPosition)
|
int resultPosition)
|
||||||
{
|
{
|
||||||
Set3OperandsFromInstr(minstr, vmInstrNode, targetMachine,
|
Set3OperandsFromInstr(minstr, vmInstrNode, target,
|
||||||
canDiscardResult, op1Position,
|
canDiscardResult, op1Position,
|
||||||
/*op2Position*/ -1, resultPosition);
|
/*op2Position*/ -1, resultPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
|
||||||
|
#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
|
||||||
unsigned
|
unsigned
|
||||||
Set3OperandsFromInstrJUNK(MachineInstr* minstr,
|
Set3OperandsFromInstrJUNK(MachineInstr* minstr,
|
||||||
InstructionNode* vmInstrNode,
|
InstructionNode* vmInstrNode,
|
||||||
const TargetMachine& targetMachine,
|
const TargetMachine& target,
|
||||||
bool canDiscardResult,
|
bool canDiscardResult,
|
||||||
int op1Position,
|
int op1Position,
|
||||||
int op2Position,
|
int op2Position,
|
||||||
|
@ -198,16 +191,16 @@ Set3OperandsFromInstrJUNK(MachineInstr* minstr,
|
||||||
Value* op1Value = vmInstrNode->leftChild()->getValue();
|
Value* op1Value = vmInstrNode->leftChild()->getValue();
|
||||||
bool isValidConstant;
|
bool isValidConstant;
|
||||||
int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
|
int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
|
||||||
if (isValidConstant && intValue == 0 && targetMachine.zeroRegNum >= 0)
|
if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
|
||||||
minstr->SetMachineOperand(op1Position, /*regNum*/ targetMachine.zeroRegNum);
|
minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (op1Value->getValueType() == Value::ConstantVal)
|
if (op1Value->getValueType() == Value::ConstantVal)
|
||||||
{// value is constant and must be loaded from constant pool
|
{// value is constant and must be loaded from constant pool
|
||||||
returnFlags = returnFlags | (1 << op1Position);
|
returnFlags = returnFlags | (1 << op1Position);
|
||||||
}
|
}
|
||||||
minstr->SetMachineOperand(op1Position, MachineOperand::MO_Register,
|
minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
|
||||||
op1Value);
|
op1Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if operand 2 (if any) fits in the immediate field of the instruction,
|
// Check if operand 2 (if any) fits in the immediate field of the instruction,
|
||||||
|
@ -216,46 +209,45 @@ Set3OperandsFromInstrJUNK(MachineInstr* minstr,
|
||||||
{
|
{
|
||||||
Value* op2Value = vmInstrNode->rightChild()->getValue();
|
Value* op2Value = vmInstrNode->rightChild()->getValue();
|
||||||
int64_t immedValue;
|
int64_t immedValue;
|
||||||
MachineOperand::VirtualRegisterType vregType;
|
|
||||||
unsigned int machineRegNum;
|
unsigned int machineRegNum;
|
||||||
|
|
||||||
MachineOperand::MachineOperandType
|
MachineOperand::MachineOperandType
|
||||||
op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(),targetMachine,
|
op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
|
||||||
/*canUseImmed*/ true,
|
/*canUseImmed*/ true,
|
||||||
vregType, machineRegNum, immedValue);
|
machineRegNum, immedValue);
|
||||||
|
|
||||||
if (op2type == MachineOperand::MO_Register)
|
if (op2type == MachineOperand::MO_MachineRegister)
|
||||||
|
minstr->SetMachineOperand(op2Position, machineRegNum);
|
||||||
|
else if (op2type == MachineOperand::MO_VirtualRegister)
|
||||||
{
|
{
|
||||||
if (vregType == MachineOperand::MO_MachineReg)
|
if (op2Value->getValueType() == Value::ConstantVal)
|
||||||
minstr->SetMachineOperand(op2Position, machineRegNum);
|
{// value is constant and must be loaded from constant pool
|
||||||
else
|
returnFlags = returnFlags | (1 << op2Position);
|
||||||
{
|
|
||||||
if (op2Value->getValueType() == Value::ConstantVal)
|
|
||||||
{// value is constant and must be loaded from constant pool
|
|
||||||
returnFlags = returnFlags | (1 << op2Position);
|
|
||||||
}
|
|
||||||
minstr->SetMachineOperand(op2Position, op2type, op2Value);
|
|
||||||
}
|
}
|
||||||
|
minstr->SetMachineOperand(op2Position, op2type, op2Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
minstr->SetMachineOperand(op2Position, op2type, immedValue);
|
{
|
||||||
|
assert(op2type != MO_CCRegister);
|
||||||
|
minstr->SetMachineOperand(op2Position, op2type, immedValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If operand 3 (result) can be discarded, use a dead register if one exists
|
// If operand 3 (result) can be discarded, use a dead register if one exists
|
||||||
if (canDiscardResult && targetMachine.zeroRegNum >= 0)
|
if (canDiscardResult && target.zeroRegNum >= 0)
|
||||||
minstr->SetMachineOperand(resultPosition, targetMachine.zeroRegNum);
|
minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
|
||||||
else
|
else
|
||||||
minstr->SetMachineOperand(resultPosition, MachineOperand::MO_Register,
|
minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
|
||||||
vmInstrNode->getValue());
|
|
||||||
|
|
||||||
return returnFlags;
|
return returnFlags;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Set3OperandsFromInstr(MachineInstr* minstr,
|
Set3OperandsFromInstr(MachineInstr* minstr,
|
||||||
InstructionNode* vmInstrNode,
|
InstructionNode* vmInstrNode,
|
||||||
const TargetMachine& targetMachine,
|
const TargetMachine& target,
|
||||||
bool canDiscardResult,
|
bool canDiscardResult,
|
||||||
int op1Position,
|
int op1Position,
|
||||||
int op2Position,
|
int op2Position,
|
||||||
|
@ -265,34 +257,32 @@ Set3OperandsFromInstr(MachineInstr* minstr,
|
||||||
assert(resultPosition >= 0);
|
assert(resultPosition >= 0);
|
||||||
|
|
||||||
// operand 1
|
// operand 1
|
||||||
minstr->SetMachineOperand(op1Position, MachineOperand::MO_Register,
|
minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
|
||||||
vmInstrNode->leftChild()->getValue());
|
vmInstrNode->leftChild()->getValue());
|
||||||
|
|
||||||
// operand 2 (if any)
|
// operand 2 (if any)
|
||||||
if (op2Position >= 0)
|
if (op2Position >= 0)
|
||||||
minstr->SetMachineOperand(op2Position, MachineOperand::MO_Register,
|
minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
|
||||||
vmInstrNode->rightChild()->getValue());
|
vmInstrNode->rightChild()->getValue());
|
||||||
|
|
||||||
// result operand: if it can be discarded, use a dead register if one exists
|
// result operand: if it can be discarded, use a dead register if one exists
|
||||||
if (canDiscardResult && targetMachine.zeroRegNum >= 0)
|
if (canDiscardResult && target.zeroRegNum >= 0)
|
||||||
minstr->SetMachineOperand(resultPosition, targetMachine.zeroRegNum);
|
minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
|
||||||
else
|
else
|
||||||
minstr->SetMachineOperand(resultPosition, MachineOperand::MO_Register,
|
minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
|
||||||
vmInstrNode->getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MachineOperand::MachineOperandType
|
MachineOperand::MachineOperandType
|
||||||
ChooseRegOrImmed(Value* val,
|
ChooseRegOrImmed(Value* val,
|
||||||
MachineOpCode opCode,
|
MachineOpCode opCode,
|
||||||
const TargetMachine& targetMachine,
|
const TargetMachine& target,
|
||||||
bool canUseImmed,
|
bool canUseImmed,
|
||||||
MachineOperand::VirtualRegisterType& getVRegType,
|
|
||||||
unsigned int& getMachineRegNum,
|
unsigned int& getMachineRegNum,
|
||||||
int64_t& getImmedValue)
|
int64_t& getImmedValue)
|
||||||
{
|
{
|
||||||
MachineOperand::MachineOperandType opType = MachineOperand::MO_Register;
|
MachineOperand::MachineOperandType opType =
|
||||||
getVRegType = MachineOperand::MO_VirtualReg;
|
MachineOperand::MO_VirtualRegister;
|
||||||
getMachineRegNum = 0;
|
getMachineRegNum = 0;
|
||||||
getImmedValue = 0;
|
getImmedValue = 0;
|
||||||
|
|
||||||
|
@ -311,13 +301,13 @@ ChooseRegOrImmed(Value* val,
|
||||||
|
|
||||||
if (isValidConstant)
|
if (isValidConstant)
|
||||||
{
|
{
|
||||||
if (intValue == 0 && targetMachine.zeroRegNum >= 0)
|
if (intValue == 0 && target.zeroRegNum >= 0)
|
||||||
{
|
{
|
||||||
getVRegType = MachineOperand::MO_MachineReg;
|
opType = MachineOperand::MO_MachineRegister;
|
||||||
getMachineRegNum = targetMachine.zeroRegNum;
|
getMachineRegNum = target.zeroRegNum;
|
||||||
}
|
}
|
||||||
else if (canUseImmed &&
|
else if (canUseImmed &&
|
||||||
targetMachine.machineInstrInfo[opCode].constantFitsInImmedField(intValue))
|
target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
|
||||||
{
|
{
|
||||||
opType = MachineOperand::MO_SignExtendedImmed;
|
opType = MachineOperand::MO_SignExtendedImmed;
|
||||||
getImmedValue = intValue;
|
getImmedValue = intValue;
|
||||||
|
|
Loading…
Reference in New Issue