mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-26 09:18:56 +00:00
Add a version of ChooseRegOrImmed to handle numerical constants
introduced by InstrSelection. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3735 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -312,6 +312,36 @@ Set3OperandsFromInstr(MachineInstr* minstr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MachineOperand::MachineOperandType
|
||||||
|
ChooseRegOrImmed(int64_t intValue,
|
||||||
|
bool isSigned,
|
||||||
|
MachineOpCode opCode,
|
||||||
|
const TargetMachine& target,
|
||||||
|
bool canUseImmed,
|
||||||
|
unsigned int& getMachineRegNum,
|
||||||
|
int64_t& getImmedValue)
|
||||||
|
{
|
||||||
|
MachineOperand::MachineOperandType opType=MachineOperand::MO_VirtualRegister;
|
||||||
|
getMachineRegNum = 0;
|
||||||
|
getImmedValue = 0;
|
||||||
|
|
||||||
|
if (canUseImmed &&
|
||||||
|
target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
|
||||||
|
{
|
||||||
|
opType = isSigned? MachineOperand::MO_SignExtendedImmed
|
||||||
|
: MachineOperand::MO_UnextendedImmed;
|
||||||
|
getImmedValue = intValue;
|
||||||
|
}
|
||||||
|
else if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
|
||||||
|
{
|
||||||
|
opType = MachineOperand::MO_MachineRegister;
|
||||||
|
getMachineRegNum = target.getRegInfo().getZeroRegNum();
|
||||||
|
}
|
||||||
|
|
||||||
|
return opType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MachineOperand::MachineOperandType
|
MachineOperand::MachineOperandType
|
||||||
ChooseRegOrImmed(Value* val,
|
ChooseRegOrImmed(Value* val,
|
||||||
MachineOpCode opCode,
|
MachineOpCode opCode,
|
||||||
@@ -320,34 +350,16 @@ ChooseRegOrImmed(Value* val,
|
|||||||
unsigned int& getMachineRegNum,
|
unsigned int& getMachineRegNum,
|
||||||
int64_t& getImmedValue)
|
int64_t& getImmedValue)
|
||||||
{
|
{
|
||||||
MachineOperand::MachineOperandType opType =
|
|
||||||
MachineOperand::MO_VirtualRegister;
|
|
||||||
getMachineRegNum = 0;
|
getMachineRegNum = 0;
|
||||||
getImmedValue = 0;
|
getImmedValue = 0;
|
||||||
|
|
||||||
// Check for the common case first: argument is not constant
|
// To use reg or immed, constant needs to be integer, bool, or a NULL pointer
|
||||||
//
|
|
||||||
Constant *CPV = dyn_cast<Constant>(val);
|
Constant *CPV = dyn_cast<Constant>(val);
|
||||||
if (!CPV) return opType;
|
if (CPV == NULL ||
|
||||||
|
(! CPV->getType()->isIntegral() &&
|
||||||
|
! (isa<PointerType>(CPV->getType()) && CPV->isNullValue())))
|
||||||
|
return MachineOperand::MO_VirtualRegister;
|
||||||
|
|
||||||
if (ConstantBool *CPB = dyn_cast<ConstantBool>(CPV))
|
|
||||||
{
|
|
||||||
if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0)
|
|
||||||
{
|
|
||||||
getMachineRegNum = target.getRegInfo().getZeroRegNum();
|
|
||||||
return MachineOperand::MO_MachineRegister;
|
|
||||||
}
|
|
||||||
|
|
||||||
getImmedValue = 1;
|
|
||||||
return MachineOperand::MO_SignExtendedImmed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise it needs to be an integer or a NULL pointer
|
|
||||||
if (! CPV->getType()->isInteger() &&
|
|
||||||
! (isa<PointerType>(CPV->getType()) &&
|
|
||||||
CPV->isNullValue()))
|
|
||||||
return opType;
|
|
||||||
|
|
||||||
// Now get the constant value and check if it fits in the IMMED field.
|
// Now get the constant value and check if it fits in the IMMED field.
|
||||||
// Take advantage of the fact that the max unsigned value will rarely
|
// Take advantage of the fact that the max unsigned value will rarely
|
||||||
// fit into any IMMED field and ignore that case (i.e., cast smaller
|
// fit into any IMMED field and ignore that case (i.e., cast smaller
|
||||||
@@ -355,35 +367,22 @@ ChooseRegOrImmed(Value* val,
|
|||||||
//
|
//
|
||||||
int64_t intValue;
|
int64_t intValue;
|
||||||
if (isa<PointerType>(CPV->getType()))
|
if (isa<PointerType>(CPV->getType()))
|
||||||
{
|
intValue = 0; // We checked above that it is NULL
|
||||||
intValue = 0;
|
else if (ConstantBool* CB = dyn_cast<ConstantBool>(CPV))
|
||||||
}
|
intValue = (int64_t) CB->getValue();
|
||||||
else if (CPV->getType()->isSigned())
|
else if (CPV->getType()->isSigned())
|
||||||
{
|
intValue = cast<ConstantSInt>(CPV)->getValue();
|
||||||
intValue = cast<ConstantSInt>(CPV)->getValue();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
assert(CPV->getType()->isUnsigned() && "Not pointer, bool, or integer?");
|
||||||
uint64_t V = cast<ConstantUInt>(CPV)->getValue();
|
uint64_t V = cast<ConstantUInt>(CPV)->getValue();
|
||||||
if (V >= INT64_MAX) return opType;
|
if (V >= INT64_MAX) return MachineOperand::MO_VirtualRegister;
|
||||||
intValue = (int64_t)V;
|
intValue = (int64_t) V;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
|
return ChooseRegOrImmed(intValue, CPV->getType()->isSigned(),
|
||||||
{
|
opCode, target, canUseImmed,
|
||||||
opType = MachineOperand::MO_MachineRegister;
|
getMachineRegNum, getImmedValue);
|
||||||
getMachineRegNum = target.getRegInfo().getZeroRegNum();
|
|
||||||
}
|
|
||||||
else if (canUseImmed &&
|
|
||||||
target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
|
|
||||||
{
|
|
||||||
opType = CPV->getType()->isSigned()
|
|
||||||
? MachineOperand::MO_SignExtendedImmed
|
|
||||||
: MachineOperand::MO_UnextendedImmed;
|
|
||||||
getImmedValue = intValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return opType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -409,55 +408,91 @@ FixConstantOperandsForInstr(Instruction* vmInstr,
|
|||||||
{
|
{
|
||||||
vector<MachineInstr*> loadConstVec;
|
vector<MachineInstr*> loadConstVec;
|
||||||
|
|
||||||
const MachineInstrDescriptor& instrDesc =
|
MachineOpCode opCode = minstr->getOpCode();
|
||||||
target.getInstrInfo().getDescriptor(minstr->getOpCode());
|
const MachineInstrInfo& instrInfo = target.getInstrInfo();
|
||||||
|
const MachineInstrDescriptor& instrDesc = instrInfo.getDescriptor(opCode);
|
||||||
|
int immedPos = instrInfo.getImmedConstantPos(opCode);
|
||||||
|
|
||||||
Function *F = vmInstr->getParent()->getParent();
|
Function *F = vmInstr->getParent()->getParent();
|
||||||
|
|
||||||
for (unsigned op=0; op < minstr->getNumOperands(); op++)
|
for (unsigned op=0; op < minstr->getNumOperands(); op++)
|
||||||
{
|
{
|
||||||
const MachineOperand& mop = minstr->getOperand(op);
|
const MachineOperand& mop = minstr->getOperand(op);
|
||||||
|
|
||||||
// skip the result position (for efficiency below) and any other
|
// Skip the result position, preallocated machine registers, or operands
|
||||||
// positions already marked as not a virtual register
|
// that cannot be constants (CC regs or PC-relative displacements)
|
||||||
if (instrDesc.resultPos == (int) op ||
|
if (instrDesc.resultPos == (int) op ||
|
||||||
mop.getOperandType() != MachineOperand::MO_VirtualRegister ||
|
mop.getOperandType() == MachineOperand::MO_MachineRegister ||
|
||||||
mop.getVRegValue() == NULL)
|
mop.getOperandType() == MachineOperand::MO_CCRegister ||
|
||||||
{
|
mop.getOperandType() == MachineOperand::MO_PCRelativeDisp)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
Value* opValue = mop.getVRegValue();
|
|
||||||
bool constantThatMustBeLoaded = false;
|
bool constantThatMustBeLoaded = false;
|
||||||
|
unsigned int machineRegNum = 0;
|
||||||
if (Constant *opConst = dyn_cast<Constant>(opValue))
|
int64_t immedValue = 0;
|
||||||
|
Value* opValue = NULL;
|
||||||
|
MachineOperand::MachineOperandType opType =
|
||||||
|
MachineOperand::MO_VirtualRegister;
|
||||||
|
|
||||||
|
// Operand may be a virtual register or a compile-time constant
|
||||||
|
if (mop.getOperandType() == MachineOperand::MO_VirtualRegister)
|
||||||
{
|
{
|
||||||
unsigned int machineRegNum;
|
assert(mop.getVRegValue() != NULL);
|
||||||
int64_t immedValue;
|
opValue = mop.getVRegValue();
|
||||||
MachineOperand::MachineOperandType opType =
|
if (Constant *opConst = dyn_cast<Constant>(opValue))
|
||||||
ChooseRegOrImmed(opValue, minstr->getOpCode(), target,
|
{
|
||||||
(target.getInstrInfo().getImmedConstantPos(minstr->getOpCode()) == (int) op),
|
opType = ChooseRegOrImmed(opConst, opCode, target,
|
||||||
machineRegNum, immedValue);
|
(immedPos == (int)op), machineRegNum, immedValue);
|
||||||
|
if (opType == MachineOperand::MO_VirtualRegister)
|
||||||
if (opType == MachineOperand::MO_MachineRegister)
|
constantThatMustBeLoaded = true;
|
||||||
minstr->SetMachineOperandReg(op, machineRegNum);
|
}
|
||||||
else if (opType == MachineOperand::MO_VirtualRegister)
|
|
||||||
constantThatMustBeLoaded = true; // load is generated below
|
|
||||||
else
|
|
||||||
minstr->SetMachineOperandConst(op, opType, immedValue);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (constantThatMustBeLoaded || isa<GlobalValue>(opValue))
|
{
|
||||||
{ // opValue is a constant that must be explicitly loaded into a reg.
|
assert(mop.getOperandType() == MachineOperand::MO_SignExtendedImmed ||
|
||||||
TmpInstruction* tmpReg = InsertCodeToLoadConstant(F, opValue,vmInstr,
|
mop.getOperandType() == MachineOperand::MO_UnextendedImmed);
|
||||||
loadConstVec,
|
|
||||||
target);
|
bool isSigned = (mop.getOperandType() ==
|
||||||
|
MachineOperand::MO_SignExtendedImmed);
|
||||||
|
|
||||||
|
// Bit-selection flags indicate an instruction that is extracting
|
||||||
|
// bits from its operand so ignore this even if it is a big constant.
|
||||||
|
if (mop.opHiBits32() || mop.opLoBits32() ||
|
||||||
|
mop.opHiBits64() || mop.opLoBits64())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
opType = ChooseRegOrImmed(mop.getImmedValue(), isSigned,
|
||||||
|
opCode, target, (immedPos == (int)op),
|
||||||
|
machineRegNum, immedValue);
|
||||||
|
|
||||||
|
if (opType == mop.getOperandType())
|
||||||
|
continue; // no change: this is the most common case
|
||||||
|
|
||||||
|
if (opType == MachineOperand::MO_VirtualRegister)
|
||||||
|
{
|
||||||
|
constantThatMustBeLoaded = true;
|
||||||
|
opValue = isSigned
|
||||||
|
? ConstantSInt::get(Type::LongTy, immedValue)
|
||||||
|
: ConstantUInt::get(Type::ULongTy, (uint64_t) immedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opType == MachineOperand::MO_MachineRegister)
|
||||||
|
minstr->SetMachineOperandReg(op, machineRegNum);
|
||||||
|
else if (opType == MachineOperand::MO_SignExtendedImmed ||
|
||||||
|
opType == MachineOperand::MO_UnextendedImmed)
|
||||||
|
minstr->SetMachineOperandConst(op, opType, immedValue);
|
||||||
|
else if (constantThatMustBeLoaded ||
|
||||||
|
(opValue && isa<GlobalValue>(opValue)))
|
||||||
|
{ // opValue is a constant that must be explicitly loaded into a reg
|
||||||
|
assert(opValue);
|
||||||
|
TmpInstruction* tmpReg = InsertCodeToLoadConstant(F, opValue, vmInstr,
|
||||||
|
loadConstVec, target);
|
||||||
minstr->SetMachineOperandVal(op, MachineOperand::MO_VirtualRegister,
|
minstr->SetMachineOperandVal(op, MachineOperand::MO_VirtualRegister,
|
||||||
tmpReg);
|
tmpReg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Also, check for implicit operands used by the machine instruction
|
// Also, check for implicit operands used by the machine instruction
|
||||||
// (no need to check those defined since they cannot be constants).
|
// (no need to check those defined since they cannot be constants).
|
||||||
// These include:
|
// These include:
|
||||||
@@ -468,7 +503,7 @@ FixConstantOperandsForInstr(Instruction* vmInstr,
|
|||||||
// have no immediate fields, so the constant always needs to be loaded
|
// have no immediate fields, so the constant always needs to be loaded
|
||||||
// into a register.
|
// into a register.
|
||||||
//
|
//
|
||||||
bool isCall = target.getInstrInfo().isCall(minstr->getOpCode());
|
bool isCall = instrInfo.isCall(opCode);
|
||||||
unsigned lastCallArgNum = 0; // unused if not a call
|
unsigned lastCallArgNum = 0; // unused if not a call
|
||||||
CallArgsDescriptor* argDesc = NULL; // unused if not a call
|
CallArgsDescriptor* argDesc = NULL; // unused if not a call
|
||||||
if (isCall)
|
if (isCall)
|
||||||
|
@@ -312,6 +312,36 @@ Set3OperandsFromInstr(MachineInstr* minstr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MachineOperand::MachineOperandType
|
||||||
|
ChooseRegOrImmed(int64_t intValue,
|
||||||
|
bool isSigned,
|
||||||
|
MachineOpCode opCode,
|
||||||
|
const TargetMachine& target,
|
||||||
|
bool canUseImmed,
|
||||||
|
unsigned int& getMachineRegNum,
|
||||||
|
int64_t& getImmedValue)
|
||||||
|
{
|
||||||
|
MachineOperand::MachineOperandType opType=MachineOperand::MO_VirtualRegister;
|
||||||
|
getMachineRegNum = 0;
|
||||||
|
getImmedValue = 0;
|
||||||
|
|
||||||
|
if (canUseImmed &&
|
||||||
|
target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
|
||||||
|
{
|
||||||
|
opType = isSigned? MachineOperand::MO_SignExtendedImmed
|
||||||
|
: MachineOperand::MO_UnextendedImmed;
|
||||||
|
getImmedValue = intValue;
|
||||||
|
}
|
||||||
|
else if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
|
||||||
|
{
|
||||||
|
opType = MachineOperand::MO_MachineRegister;
|
||||||
|
getMachineRegNum = target.getRegInfo().getZeroRegNum();
|
||||||
|
}
|
||||||
|
|
||||||
|
return opType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MachineOperand::MachineOperandType
|
MachineOperand::MachineOperandType
|
||||||
ChooseRegOrImmed(Value* val,
|
ChooseRegOrImmed(Value* val,
|
||||||
MachineOpCode opCode,
|
MachineOpCode opCode,
|
||||||
@@ -320,34 +350,16 @@ ChooseRegOrImmed(Value* val,
|
|||||||
unsigned int& getMachineRegNum,
|
unsigned int& getMachineRegNum,
|
||||||
int64_t& getImmedValue)
|
int64_t& getImmedValue)
|
||||||
{
|
{
|
||||||
MachineOperand::MachineOperandType opType =
|
|
||||||
MachineOperand::MO_VirtualRegister;
|
|
||||||
getMachineRegNum = 0;
|
getMachineRegNum = 0;
|
||||||
getImmedValue = 0;
|
getImmedValue = 0;
|
||||||
|
|
||||||
// Check for the common case first: argument is not constant
|
// To use reg or immed, constant needs to be integer, bool, or a NULL pointer
|
||||||
//
|
|
||||||
Constant *CPV = dyn_cast<Constant>(val);
|
Constant *CPV = dyn_cast<Constant>(val);
|
||||||
if (!CPV) return opType;
|
if (CPV == NULL ||
|
||||||
|
(! CPV->getType()->isIntegral() &&
|
||||||
|
! (isa<PointerType>(CPV->getType()) && CPV->isNullValue())))
|
||||||
|
return MachineOperand::MO_VirtualRegister;
|
||||||
|
|
||||||
if (ConstantBool *CPB = dyn_cast<ConstantBool>(CPV))
|
|
||||||
{
|
|
||||||
if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0)
|
|
||||||
{
|
|
||||||
getMachineRegNum = target.getRegInfo().getZeroRegNum();
|
|
||||||
return MachineOperand::MO_MachineRegister;
|
|
||||||
}
|
|
||||||
|
|
||||||
getImmedValue = 1;
|
|
||||||
return MachineOperand::MO_SignExtendedImmed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise it needs to be an integer or a NULL pointer
|
|
||||||
if (! CPV->getType()->isInteger() &&
|
|
||||||
! (isa<PointerType>(CPV->getType()) &&
|
|
||||||
CPV->isNullValue()))
|
|
||||||
return opType;
|
|
||||||
|
|
||||||
// Now get the constant value and check if it fits in the IMMED field.
|
// Now get the constant value and check if it fits in the IMMED field.
|
||||||
// Take advantage of the fact that the max unsigned value will rarely
|
// Take advantage of the fact that the max unsigned value will rarely
|
||||||
// fit into any IMMED field and ignore that case (i.e., cast smaller
|
// fit into any IMMED field and ignore that case (i.e., cast smaller
|
||||||
@@ -355,35 +367,22 @@ ChooseRegOrImmed(Value* val,
|
|||||||
//
|
//
|
||||||
int64_t intValue;
|
int64_t intValue;
|
||||||
if (isa<PointerType>(CPV->getType()))
|
if (isa<PointerType>(CPV->getType()))
|
||||||
{
|
intValue = 0; // We checked above that it is NULL
|
||||||
intValue = 0;
|
else if (ConstantBool* CB = dyn_cast<ConstantBool>(CPV))
|
||||||
}
|
intValue = (int64_t) CB->getValue();
|
||||||
else if (CPV->getType()->isSigned())
|
else if (CPV->getType()->isSigned())
|
||||||
{
|
intValue = cast<ConstantSInt>(CPV)->getValue();
|
||||||
intValue = cast<ConstantSInt>(CPV)->getValue();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
assert(CPV->getType()->isUnsigned() && "Not pointer, bool, or integer?");
|
||||||
uint64_t V = cast<ConstantUInt>(CPV)->getValue();
|
uint64_t V = cast<ConstantUInt>(CPV)->getValue();
|
||||||
if (V >= INT64_MAX) return opType;
|
if (V >= INT64_MAX) return MachineOperand::MO_VirtualRegister;
|
||||||
intValue = (int64_t)V;
|
intValue = (int64_t) V;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
|
return ChooseRegOrImmed(intValue, CPV->getType()->isSigned(),
|
||||||
{
|
opCode, target, canUseImmed,
|
||||||
opType = MachineOperand::MO_MachineRegister;
|
getMachineRegNum, getImmedValue);
|
||||||
getMachineRegNum = target.getRegInfo().getZeroRegNum();
|
|
||||||
}
|
|
||||||
else if (canUseImmed &&
|
|
||||||
target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
|
|
||||||
{
|
|
||||||
opType = CPV->getType()->isSigned()
|
|
||||||
? MachineOperand::MO_SignExtendedImmed
|
|
||||||
: MachineOperand::MO_UnextendedImmed;
|
|
||||||
getImmedValue = intValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return opType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -409,55 +408,91 @@ FixConstantOperandsForInstr(Instruction* vmInstr,
|
|||||||
{
|
{
|
||||||
vector<MachineInstr*> loadConstVec;
|
vector<MachineInstr*> loadConstVec;
|
||||||
|
|
||||||
const MachineInstrDescriptor& instrDesc =
|
MachineOpCode opCode = minstr->getOpCode();
|
||||||
target.getInstrInfo().getDescriptor(minstr->getOpCode());
|
const MachineInstrInfo& instrInfo = target.getInstrInfo();
|
||||||
|
const MachineInstrDescriptor& instrDesc = instrInfo.getDescriptor(opCode);
|
||||||
|
int immedPos = instrInfo.getImmedConstantPos(opCode);
|
||||||
|
|
||||||
Function *F = vmInstr->getParent()->getParent();
|
Function *F = vmInstr->getParent()->getParent();
|
||||||
|
|
||||||
for (unsigned op=0; op < minstr->getNumOperands(); op++)
|
for (unsigned op=0; op < minstr->getNumOperands(); op++)
|
||||||
{
|
{
|
||||||
const MachineOperand& mop = minstr->getOperand(op);
|
const MachineOperand& mop = minstr->getOperand(op);
|
||||||
|
|
||||||
// skip the result position (for efficiency below) and any other
|
// Skip the result position, preallocated machine registers, or operands
|
||||||
// positions already marked as not a virtual register
|
// that cannot be constants (CC regs or PC-relative displacements)
|
||||||
if (instrDesc.resultPos == (int) op ||
|
if (instrDesc.resultPos == (int) op ||
|
||||||
mop.getOperandType() != MachineOperand::MO_VirtualRegister ||
|
mop.getOperandType() == MachineOperand::MO_MachineRegister ||
|
||||||
mop.getVRegValue() == NULL)
|
mop.getOperandType() == MachineOperand::MO_CCRegister ||
|
||||||
{
|
mop.getOperandType() == MachineOperand::MO_PCRelativeDisp)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
Value* opValue = mop.getVRegValue();
|
|
||||||
bool constantThatMustBeLoaded = false;
|
bool constantThatMustBeLoaded = false;
|
||||||
|
unsigned int machineRegNum = 0;
|
||||||
if (Constant *opConst = dyn_cast<Constant>(opValue))
|
int64_t immedValue = 0;
|
||||||
|
Value* opValue = NULL;
|
||||||
|
MachineOperand::MachineOperandType opType =
|
||||||
|
MachineOperand::MO_VirtualRegister;
|
||||||
|
|
||||||
|
// Operand may be a virtual register or a compile-time constant
|
||||||
|
if (mop.getOperandType() == MachineOperand::MO_VirtualRegister)
|
||||||
{
|
{
|
||||||
unsigned int machineRegNum;
|
assert(mop.getVRegValue() != NULL);
|
||||||
int64_t immedValue;
|
opValue = mop.getVRegValue();
|
||||||
MachineOperand::MachineOperandType opType =
|
if (Constant *opConst = dyn_cast<Constant>(opValue))
|
||||||
ChooseRegOrImmed(opValue, minstr->getOpCode(), target,
|
{
|
||||||
(target.getInstrInfo().getImmedConstantPos(minstr->getOpCode()) == (int) op),
|
opType = ChooseRegOrImmed(opConst, opCode, target,
|
||||||
machineRegNum, immedValue);
|
(immedPos == (int)op), machineRegNum, immedValue);
|
||||||
|
if (opType == MachineOperand::MO_VirtualRegister)
|
||||||
if (opType == MachineOperand::MO_MachineRegister)
|
constantThatMustBeLoaded = true;
|
||||||
minstr->SetMachineOperandReg(op, machineRegNum);
|
}
|
||||||
else if (opType == MachineOperand::MO_VirtualRegister)
|
|
||||||
constantThatMustBeLoaded = true; // load is generated below
|
|
||||||
else
|
|
||||||
minstr->SetMachineOperandConst(op, opType, immedValue);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (constantThatMustBeLoaded || isa<GlobalValue>(opValue))
|
{
|
||||||
{ // opValue is a constant that must be explicitly loaded into a reg.
|
assert(mop.getOperandType() == MachineOperand::MO_SignExtendedImmed ||
|
||||||
TmpInstruction* tmpReg = InsertCodeToLoadConstant(F, opValue,vmInstr,
|
mop.getOperandType() == MachineOperand::MO_UnextendedImmed);
|
||||||
loadConstVec,
|
|
||||||
target);
|
bool isSigned = (mop.getOperandType() ==
|
||||||
|
MachineOperand::MO_SignExtendedImmed);
|
||||||
|
|
||||||
|
// Bit-selection flags indicate an instruction that is extracting
|
||||||
|
// bits from its operand so ignore this even if it is a big constant.
|
||||||
|
if (mop.opHiBits32() || mop.opLoBits32() ||
|
||||||
|
mop.opHiBits64() || mop.opLoBits64())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
opType = ChooseRegOrImmed(mop.getImmedValue(), isSigned,
|
||||||
|
opCode, target, (immedPos == (int)op),
|
||||||
|
machineRegNum, immedValue);
|
||||||
|
|
||||||
|
if (opType == mop.getOperandType())
|
||||||
|
continue; // no change: this is the most common case
|
||||||
|
|
||||||
|
if (opType == MachineOperand::MO_VirtualRegister)
|
||||||
|
{
|
||||||
|
constantThatMustBeLoaded = true;
|
||||||
|
opValue = isSigned
|
||||||
|
? ConstantSInt::get(Type::LongTy, immedValue)
|
||||||
|
: ConstantUInt::get(Type::ULongTy, (uint64_t) immedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opType == MachineOperand::MO_MachineRegister)
|
||||||
|
minstr->SetMachineOperandReg(op, machineRegNum);
|
||||||
|
else if (opType == MachineOperand::MO_SignExtendedImmed ||
|
||||||
|
opType == MachineOperand::MO_UnextendedImmed)
|
||||||
|
minstr->SetMachineOperandConst(op, opType, immedValue);
|
||||||
|
else if (constantThatMustBeLoaded ||
|
||||||
|
(opValue && isa<GlobalValue>(opValue)))
|
||||||
|
{ // opValue is a constant that must be explicitly loaded into a reg
|
||||||
|
assert(opValue);
|
||||||
|
TmpInstruction* tmpReg = InsertCodeToLoadConstant(F, opValue, vmInstr,
|
||||||
|
loadConstVec, target);
|
||||||
minstr->SetMachineOperandVal(op, MachineOperand::MO_VirtualRegister,
|
minstr->SetMachineOperandVal(op, MachineOperand::MO_VirtualRegister,
|
||||||
tmpReg);
|
tmpReg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Also, check for implicit operands used by the machine instruction
|
// Also, check for implicit operands used by the machine instruction
|
||||||
// (no need to check those defined since they cannot be constants).
|
// (no need to check those defined since they cannot be constants).
|
||||||
// These include:
|
// These include:
|
||||||
@@ -468,7 +503,7 @@ FixConstantOperandsForInstr(Instruction* vmInstr,
|
|||||||
// have no immediate fields, so the constant always needs to be loaded
|
// have no immediate fields, so the constant always needs to be loaded
|
||||||
// into a register.
|
// into a register.
|
||||||
//
|
//
|
||||||
bool isCall = target.getInstrInfo().isCall(minstr->getOpCode());
|
bool isCall = instrInfo.isCall(opCode);
|
||||||
unsigned lastCallArgNum = 0; // unused if not a call
|
unsigned lastCallArgNum = 0; // unused if not a call
|
||||||
CallArgsDescriptor* argDesc = NULL; // unused if not a call
|
CallArgsDescriptor* argDesc = NULL; // unused if not a call
|
||||||
if (isCall)
|
if (isCall)
|
||||||
|
Reference in New Issue
Block a user