forked from OSchip/llvm-project
Moved and expanded convertOpcodeFromRegToImm() to conver more opcodes.
Code beautification for the rest of the code: changed layout to match the rest of the code base. llvm-svn: 6446
This commit is contained in:
parent
c1830a472a
commit
a853af587a
|
@ -747,8 +747,8 @@ CreateShiftInstructions(const TargetMachine& target,
|
|||
//
|
||||
Value* shiftDest = destVal;
|
||||
unsigned opSize = target.getTargetData().getTypeSize(argVal1->getType());
|
||||
if ((shiftOpCode == V9::SLLr6 || shiftOpCode == V9::SLLXr6) && opSize < 8)
|
||||
{ // put SLL result into a temporary
|
||||
if ((shiftOpCode == V9::SLLr6 || shiftOpCode == V9::SLLXr6) && opSize < 8) {
|
||||
// put SLL result into a temporary
|
||||
shiftDest = new TmpInstruction(argVal1, optArgVal2, "sllTmp");
|
||||
mcfi.addTemp(shiftDest);
|
||||
}
|
||||
|
@ -760,8 +760,8 @@ CreateShiftInstructions(const TargetMachine& target,
|
|||
.addReg(shiftDest, MOTy::Def);
|
||||
mvec.push_back(M);
|
||||
|
||||
if (shiftDest != destVal)
|
||||
{ // extend the sign-bit of the result into all upper bits of dest
|
||||
if (shiftDest != destVal) {
|
||||
// extend the sign-bit of the result into all upper bits of dest
|
||||
assert(8*opSize <= 32 && "Unexpected type size > 4 and < IntRegSize?");
|
||||
target.getInstrInfo().
|
||||
CreateSignExtensionInstructions(target, F, shiftDest, destVal,
|
||||
|
@ -814,16 +814,15 @@ CreateMulConstInstruction(const TargetMachine &target, Function* F,
|
|||
else
|
||||
M = BuildMI(V9::ADDr,3).addReg(lval).addMReg(Zero).addRegDef(destVal);
|
||||
mvec.push_back(M);
|
||||
}
|
||||
else if (isPowerOf2(C, pow)) {
|
||||
} else if (isPowerOf2(C, pow)) {
|
||||
unsigned opSize = target.getTargetData().getTypeSize(resultType);
|
||||
MachineOpCode opCode = (opSize <= 32)? V9::SLLr6 : V9::SLLXr6;
|
||||
CreateShiftInstructions(target, F, opCode, lval, NULL, pow,
|
||||
destVal, mvec, mcfi);
|
||||
}
|
||||
|
||||
if (mvec.size() > 0 && needNeg)
|
||||
{ // insert <reg = SUB 0, reg> after the instr to flip the sign
|
||||
if (mvec.size() > 0 && needNeg) {
|
||||
// insert <reg = SUB 0, reg> after the instr to flip the sign
|
||||
MachineInstr* M = CreateIntNegInstruction(target, destVal);
|
||||
mvec.push_back(M);
|
||||
}
|
||||
|
@ -862,10 +861,11 @@ CreateCheapestMulConstInstruction(const TargetMachine &target,
|
|||
MachineCodeForInstruction& mcfi)
|
||||
{
|
||||
Value* constOp;
|
||||
if (isa<Constant>(lval) && isa<Constant>(rval))
|
||||
{ // both operands are constant: evaluate and "set" in dest
|
||||
if (isa<Constant>(lval) && isa<Constant>(rval)) {
|
||||
// both operands are constant: evaluate and "set" in dest
|
||||
Constant* P = ConstantFoldBinaryInstruction(Instruction::Mul,
|
||||
cast<Constant>(lval), cast<Constant>(rval));
|
||||
cast<Constant>(lval),
|
||||
cast<Constant>(rval));
|
||||
target.getInstrInfo().CreateCodeToLoadConst(target,F,P,destVal,mvec,mcfi);
|
||||
}
|
||||
else if (isa<Constant>(rval)) // rval is constant, but not lval
|
||||
|
@ -946,8 +946,7 @@ CreateDivConstInstruction(TargetMachine &target,
|
|||
//
|
||||
const Type* resultType = instrNode->getInstruction()->getType();
|
||||
|
||||
if (resultType->isInteger())
|
||||
{
|
||||
if (resultType->isInteger()) {
|
||||
unsigned pow;
|
||||
bool isValidConst;
|
||||
int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst);
|
||||
|
@ -995,8 +994,7 @@ CreateDivConstInstruction(TargetMachine &target,
|
|||
// Get the shift operand and "right-shift" opcode to do the divide
|
||||
shiftOperand = addTmp;
|
||||
opCode = (resultType==Type::LongTy) ? V9::SRAXi6 : V9::SRAi6;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Get the shift operand and "right-shift" opcode to do the divide
|
||||
shiftOperand = LHS;
|
||||
opCode = (resultType==Type::LongTy) ? V9::SRLXi6 : V9::SRLi6;
|
||||
|
@ -1041,8 +1039,7 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target,
|
|||
|
||||
// Enforce the alignment constraints on the stack pointer at
|
||||
// compile time if the total size is a known constant.
|
||||
if (isa<Constant>(numElementsVal))
|
||||
{
|
||||
if (isa<Constant>(numElementsVal)) {
|
||||
bool isValid;
|
||||
int64_t numElem = GetConstantValueAsSignedInt(numElementsVal, isValid);
|
||||
assert(isValid && "Unexpectedly large array dimension in alloca!");
|
||||
|
@ -1050,9 +1047,7 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target,
|
|||
if (int extra= total % target.getFrameInfo().getStackFrameSizeAlignment())
|
||||
total += target.getFrameInfo().getStackFrameSizeAlignment() - extra;
|
||||
totalSizeVal = ConstantSInt::get(Type::IntTy, total);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// The size is not a constant. Generate code to compute it and
|
||||
// code to pad the size for stack alignment.
|
||||
// Create a Value to hold the (constant) element size
|
||||
|
@ -1140,39 +1135,6 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target,
|
|||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
convertOpcodeFromRegToImm(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
case V9::ADDr: return V9::ADDi;
|
||||
|
||||
/* load opcodes */
|
||||
case V9::LDUBr: return V9::LDUBi;
|
||||
case V9::LDSBr: return V9::LDSBi;
|
||||
case V9::LDUHr: return V9::LDUHi;
|
||||
case V9::LDSHr: return V9::LDSHi;
|
||||
case V9::LDUWr: return V9::LDUWi;
|
||||
case V9::LDSWr: return V9::LDSWi;
|
||||
case V9::LDXr: return V9::LDXi;
|
||||
case V9::LDFr: return V9::LDFi;
|
||||
case V9::LDDFr: return V9::LDDFi;
|
||||
|
||||
/* store opcodes */
|
||||
case V9::STBr: return V9::STBi;
|
||||
case V9::STHr: return V9::STHi;
|
||||
case V9::STWr: return V9::STWi;
|
||||
case V9::STXr: return V9::STXi;
|
||||
case V9::STFr: return V9::STFi;
|
||||
case V9::STDFr: return V9::STDFi;
|
||||
|
||||
default:
|
||||
std::cerr << "Not handled opcode in convert from reg to imm: " << Opcode
|
||||
<< "\n";
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Function SetOperandsForMemInstr
|
||||
//
|
||||
|
@ -1211,20 +1173,16 @@ SetOperandsForMemInstr(unsigned Opcode,
|
|||
// Check if there is an index vector and if so, compute the
|
||||
// right offset for structures and for arrays
|
||||
//
|
||||
if (!idxVec.empty())
|
||||
{
|
||||
if (!idxVec.empty()) {
|
||||
const PointerType* ptrType = cast<PointerType>(ptrVal->getType());
|
||||
|
||||
// If all indices are constant, compute the combined offset directly.
|
||||
if (allConstantIndices)
|
||||
{
|
||||
if (allConstantIndices) {
|
||||
// Compute the offset value using the index vector. Create a
|
||||
// virtual reg. for it since it may not fit in the immed field.
|
||||
uint64_t offset = target.getTargetData().getIndexedOffset(ptrType,idxVec);
|
||||
valueForRegOffset = ConstantSInt::get(Type::LongTy, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// There is at least one non-constant offset. Therefore, this must
|
||||
// be an array ref, and must have been lowered to a single non-zero
|
||||
// offset. (An extra leading zero offset, if any, can be ignored.)
|
||||
|
@ -1264,9 +1222,7 @@ SetOperandsForMemInstr(unsigned Opcode,
|
|||
|
||||
valueForRegOffset = addr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
offsetOpType = MachineOperand::MO_SignExtendedImmed;
|
||||
smallConstOffset = 0;
|
||||
}
|
||||
|
@ -1279,19 +1235,19 @@ SetOperandsForMemInstr(unsigned Opcode,
|
|||
unsigned offsetOpNum, ptrOpNum;
|
||||
MachineInstr *MI;
|
||||
if (memInst->getOpcode() == Instruction::Store) {
|
||||
if (offsetOpType == MachineOperand::MO_VirtualRegister)
|
||||
if (offsetOpType == MachineOperand::MO_VirtualRegister) {
|
||||
MI = BuildMI(Opcode, 3).addReg(vmInstrNode->leftChild()->getValue())
|
||||
.addReg(ptrVal).addReg(valueForRegOffset);
|
||||
else {
|
||||
} else {
|
||||
Opcode = convertOpcodeFromRegToImm(Opcode);
|
||||
MI = BuildMI(Opcode, 3).addReg(vmInstrNode->leftChild()->getValue())
|
||||
.addReg(ptrVal).addSImm(smallConstOffset);
|
||||
}
|
||||
} else {
|
||||
if (offsetOpType == MachineOperand::MO_VirtualRegister)
|
||||
if (offsetOpType == MachineOperand::MO_VirtualRegister) {
|
||||
MI = BuildMI(Opcode, 3).addReg(ptrVal).addReg(valueForRegOffset)
|
||||
.addRegDef(memInst);
|
||||
else {
|
||||
} else {
|
||||
Opcode = convertOpcodeFromRegToImm(Opcode);
|
||||
MI = BuildMI(Opcode, 3).addReg(ptrVal).addSImm(smallConstOffset)
|
||||
.addRegDef(memInst);
|
||||
|
@ -1333,33 +1289,31 @@ ForwardOperand(InstructionNode* treeNode,
|
|||
// The parent's mvec would be empty if it was itself forwarded.
|
||||
// Recursively call ForwardOperand in that case...
|
||||
//
|
||||
if (mvec.size() == 0)
|
||||
{
|
||||
if (mvec.size() == 0) {
|
||||
assert(parent->parent() != NULL &&
|
||||
"Parent could not have been forwarded, yet has no instructions?");
|
||||
ForwardOperand(treeNode, parent->parent(), operandNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i=0, N=mvec.size(); i < N; i++)
|
||||
{
|
||||
} else {
|
||||
for (unsigned i=0, N=mvec.size(); i < N; i++) {
|
||||
MachineInstr* minstr = mvec[i];
|
||||
for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i)
|
||||
{
|
||||
for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i) {
|
||||
const MachineOperand& mop = minstr->getOperand(i);
|
||||
if (mop.getType() == MachineOperand::MO_VirtualRegister &&
|
||||
mop.getVRegValue() == unusedOp)
|
||||
minstr->SetMachineOperandVal(i,
|
||||
MachineOperand::MO_VirtualRegister, fwdOp);
|
||||
{
|
||||
minstr->SetMachineOperandVal(i, MachineOperand::MO_VirtualRegister,
|
||||
fwdOp);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i=0,numOps=minstr->getNumImplicitRefs(); i<numOps; ++i)
|
||||
if (minstr->getImplicitRef(i) == unusedOp)
|
||||
if (minstr->getImplicitRef(i) == unusedOp) {
|
||||
minstr->setImplicitRef(i, fwdOp,
|
||||
minstr->getImplicitOp(i).opIsDefOnly(),
|
||||
minstr->getImplicitOp(i).opIsDefAndUse());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1728,12 +1682,12 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
Instruction* destI = subtreeRoot->getInstruction();
|
||||
Value* opVal = subtreeRoot->leftChild()->getValue();
|
||||
const Type* opType = opVal->getType();
|
||||
if (opType->isIntegral() || isa<PointerType>(opType))
|
||||
{
|
||||
if (opType->isIntegral() || isa<PointerType>(opType)) {
|
||||
unsigned opSize = target.getTargetData().getTypeSize(opType);
|
||||
unsigned destSize = target.getTargetData().getTypeSize(destI->getType());
|
||||
if (opSize >= destSize)
|
||||
{ // Operand is same size as or larger than dest:
|
||||
unsigned destSize =
|
||||
target.getTargetData().getTypeSize(destI->getType());
|
||||
if (opSize >= destSize) {
|
||||
// Operand is same size as or larger than dest:
|
||||
// zero- or sign-extend, according to the signeddness of
|
||||
// the destination (see above).
|
||||
if (destI->getType()->isSigned())
|
||||
|
@ -1744,18 +1698,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
target.getInstrInfo().CreateZeroExtensionInstructions(target,
|
||||
destI->getParent()->getParent(), opVal, destI, 8*destSize,
|
||||
mvec, MachineCodeForInstruction::get(destI));
|
||||
}
|
||||
else
|
||||
} else
|
||||
forwardOperandNum = 0; // forward first operand to user
|
||||
}
|
||||
else if (opType->isFloatingPoint())
|
||||
{
|
||||
} else if (opType->isFloatingPoint()) {
|
||||
CreateCodeToConvertFloatToInt(target, opVal, destI, mvec,
|
||||
MachineCodeForInstruction::get(destI));
|
||||
if (destI->getType()->isUnsigned())
|
||||
maskUnsignedResult = true; // not handled by fp->int code
|
||||
}
|
||||
else
|
||||
} else
|
||||
assert(0 && "Unrecognized operand type for convert-to-unsigned");
|
||||
|
||||
break;
|
||||
|
@ -1768,13 +1718,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
const Type* opType = opVal->getType();
|
||||
if (opType->isIntegral() || isa<PointerType>(opType))
|
||||
forwardOperandNum = 0; // forward first operand to user
|
||||
else if (opType->isFloatingPoint())
|
||||
{
|
||||
else if (opType->isFloatingPoint()) {
|
||||
Instruction* destI = subtreeRoot->getInstruction();
|
||||
CreateCodeToConvertFloatToInt(target, opVal, destI, mvec,
|
||||
MachineCodeForInstruction::get(destI));
|
||||
}
|
||||
else
|
||||
} else
|
||||
assert(0 && "Unrecognized operand type for convert-to-signed");
|
||||
break;
|
||||
}
|
||||
|
@ -1789,8 +1737,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
// In the future, we'll want to do the same for the FdMULq instruction,
|
||||
// so do the check here instead of only for ToFloatTy(reg).
|
||||
//
|
||||
if (subtreeRoot->parent() != NULL)
|
||||
{
|
||||
if (subtreeRoot->parent() != NULL) {
|
||||
const MachineCodeForInstruction& mcfi =
|
||||
MachineCodeForInstruction::get(
|
||||
cast<InstructionNode>(subtreeRoot->parent())->getInstruction());
|
||||
|
@ -1798,25 +1745,20 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
forwardOperandNum = 0; // forward first operand to user
|
||||
}
|
||||
|
||||
if (forwardOperandNum != 0) // we do need the cast
|
||||
{
|
||||
if (forwardOperandNum != 0) { // we do need the cast
|
||||
Value* leftVal = subtreeRoot->leftChild()->getValue();
|
||||
const Type* opType = leftVal->getType();
|
||||
MachineOpCode opCode=ChooseConvertToFloatInstr(
|
||||
subtreeRoot->getOpLabel(), opType);
|
||||
if (opCode == V9::INVALID_OPCODE) // no conversion needed
|
||||
{
|
||||
if (opCode == V9::INVALID_OPCODE) { // no conversion needed
|
||||
forwardOperandNum = 0; // forward first operand to user
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// If the source operand is a non-FP type it must be
|
||||
// first copied from int to float register via memory!
|
||||
Instruction *dest = subtreeRoot->getInstruction();
|
||||
Value* srcForCast;
|
||||
int n = 0;
|
||||
if (! opType->isFloatingPoint())
|
||||
{
|
||||
if (! opType->isFloatingPoint()) {
|
||||
// Create a temporary to represent the FP register
|
||||
// into which the integer will be copied via memory.
|
||||
// The type of this temporary will determine the FP
|
||||
|
@ -1836,8 +1778,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
dest->getParent()->getParent(),
|
||||
leftVal, cast<Instruction>(srcForCast),
|
||||
mvec, destMCFI);
|
||||
}
|
||||
else
|
||||
} else
|
||||
srcForCast = leftVal;
|
||||
|
||||
M = BuildMI(opCode, 2).addReg(srcForCast).addRegDef(dest);
|
||||
|
@ -1854,8 +1795,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
case 233: // reg: Add(reg, Constant)
|
||||
maskUnsignedResult = true;
|
||||
M = CreateAddConstInstruction(subtreeRoot);
|
||||
if (M != NULL)
|
||||
{
|
||||
if (M != NULL) {
|
||||
mvec.push_back(M);
|
||||
break;
|
||||
}
|
||||
|
@ -1869,8 +1809,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
case 234: // reg: Sub(reg, Constant)
|
||||
maskUnsignedResult = true;
|
||||
M = CreateSubConstInstruction(subtreeRoot);
|
||||
if (M != NULL)
|
||||
{
|
||||
if (M != NULL) {
|
||||
mvec.push_back(M);
|
||||
break;
|
||||
}
|
||||
|
@ -2089,8 +2028,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
isFPCompare ? Type::FloatTy : Type::IntTy);
|
||||
MachineCodeForInstruction::get(setCCInstr).addTemp(tmpForCC);
|
||||
|
||||
if (! isFPCompare)
|
||||
{
|
||||
if (! isFPCompare) {
|
||||
// Integer condition: dest. should be %g0 or an integer register.
|
||||
// If result must be saved but condition is not SetEQ then we need
|
||||
// a separate instruction to compute the bool result, so discard
|
||||
|
@ -2111,14 +2049,12 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
}
|
||||
mvec.push_back(M);
|
||||
|
||||
if (computeBoolVal)
|
||||
{ // recompute bool using the integer condition codes
|
||||
if (computeBoolVal) {
|
||||
// recompute bool using the integer condition codes
|
||||
movOpCode =
|
||||
ChooseMovpccAfterSub(subtreeRoot,mustClearReg,valueToMove);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// FP condition: dest of FCMP should be some FCCn register
|
||||
M = BuildMI(ChooseFcmpInstruction(subtreeRoot), 3)
|
||||
.addCCReg(tmpForCC, MOTy::Def)
|
||||
|
@ -2126,18 +2062,17 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
.addRegDef(subtreeRoot->rightChild()->getValue());
|
||||
mvec.push_back(M);
|
||||
|
||||
if (computeBoolVal)
|
||||
{// recompute bool using the FP condition codes
|
||||
if (computeBoolVal) {
|
||||
// recompute bool using the FP condition codes
|
||||
mustClearReg = true;
|
||||
valueToMove = 1;
|
||||
movOpCode = ChooseMovFpccInstruction(subtreeRoot);
|
||||
}
|
||||
}
|
||||
|
||||
if (computeBoolVal)
|
||||
{
|
||||
if (mustClearReg)
|
||||
{// Unconditionally set register to 0
|
||||
if (computeBoolVal) {
|
||||
if (mustClearReg) {
|
||||
// Unconditionally set register to 0
|
||||
M = BuildMI(V9::SETHI, 2).addZImm(0).addRegDef(setCCInstr);
|
||||
mvec.push_back(M);
|
||||
}
|
||||
|
@ -2192,7 +2127,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
|
||||
if (!isArray ||
|
||||
isa<Constant>(numElementsVal = instr->getArraySize()))
|
||||
{ // total size is constant: generate code for fixed-size alloca
|
||||
{
|
||||
// total size is constant: generate code for fixed-size alloca
|
||||
unsigned numElements = isArray?
|
||||
cast<ConstantUInt>(numElementsVal)->getValue() : 1;
|
||||
CreateCodeForFixedSizeAlloca(target, instr, tsize,
|
||||
|
@ -2230,8 +2166,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
// If not, generate the normal call sequence for the function.
|
||||
// This can also handle any intrinsics that are just function calls.
|
||||
//
|
||||
if (! specialIntrinsic)
|
||||
{
|
||||
if (! specialIntrinsic) {
|
||||
// Create hidden virtual register for return address with type void*
|
||||
TmpInstruction* retAddrReg =
|
||||
new TmpInstruction(PointerType::get(Type::VoidTy), callInstr);
|
||||
|
@ -2265,16 +2200,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
assert(callInstr->getOperand(0) == callee
|
||||
&& "This is assumed in the loop below!");
|
||||
|
||||
for (unsigned i=1, N=callInstr->getNumOperands(); i < N; ++i)
|
||||
{
|
||||
for (unsigned i=1, N=callInstr->getNumOperands(); i < N; ++i) {
|
||||
Value* argVal = callInstr->getOperand(i);
|
||||
Instruction* intArgReg = NULL;
|
||||
|
||||
// Check for FP arguments to varargs functions.
|
||||
// Any such argument in the first $K$ args must be passed in an
|
||||
// integer register, where K = #integer argument registers.
|
||||
if (isVarArgs && argVal->getType()->isFloatingPoint())
|
||||
{
|
||||
if (isVarArgs && argVal->getType()->isFloatingPoint()) {
|
||||
// If it is a function with no prototype, pass value
|
||||
// as an FP value as well as a varargs value
|
||||
if (noPrototype)
|
||||
|
@ -2282,8 +2215,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
|
||||
// If this arg. is in the first $K$ regs, add a copy
|
||||
// float-to-int instruction to pass the value as an integer.
|
||||
if (i <= target.getRegInfo().getNumOfIntArgRegs())
|
||||
{
|
||||
if (i <= target.getRegInfo().getNumOfIntArgRegs()) {
|
||||
MachineCodeForInstruction &destMCFI =
|
||||
MachineCodeForInstruction::get(callInstr);
|
||||
intArgReg = new TmpInstruction(Type::IntTy, argVal);
|
||||
|
@ -2298,8 +2230,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
|
||||
argDesc->getArgInfo(i-1).setUseIntArgReg();
|
||||
argDesc->getArgInfo(i-1).setArgCopy(intArgReg);
|
||||
}
|
||||
else
|
||||
} else
|
||||
// Cannot fit in first $K$ regs so pass arg on stack
|
||||
argDesc->getArgInfo(i-1).setUseStackSlot();
|
||||
}
|
||||
|
@ -2344,7 +2275,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
}
|
||||
|
||||
case 63: // reg: Shr(reg, reg)
|
||||
{ const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
|
||||
{
|
||||
const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
|
||||
assert((opType->isInteger() || isa<PointerType>(opType)) &&
|
||||
"Shr unsupported for other types");
|
||||
Add3OperandInstr(opType->isSigned()
|
||||
|
@ -2380,15 +2312,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
}
|
||||
}
|
||||
|
||||
if (forwardOperandNum >= 0)
|
||||
{ // We did not generate a machine instruction but need to use operand.
|
||||
if (forwardOperandNum >= 0) {
|
||||
// We did not generate a machine instruction but need to use operand.
|
||||
// If user is in the same tree, replace Value in its machine operand.
|
||||
// If not, insert a copy instruction which should get coalesced away
|
||||
// by register allocation.
|
||||
if (subtreeRoot->parent() != NULL)
|
||||
ForwardOperand(subtreeRoot, subtreeRoot->parent(), forwardOperandNum);
|
||||
else
|
||||
{
|
||||
else {
|
||||
std::vector<MachineInstr*> minstrVec;
|
||||
Instruction* instr = subtreeRoot->getInstruction();
|
||||
target.getInstrInfo().
|
||||
|
@ -2402,16 +2333,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
}
|
||||
}
|
||||
|
||||
if (maskUnsignedResult)
|
||||
{ // If result is unsigned and smaller than int reg size,
|
||||
if (maskUnsignedResult) {
|
||||
// If result is unsigned and smaller than int reg size,
|
||||
// we need to clear high bits of result value.
|
||||
assert(forwardOperandNum < 0 && "Need mask but no instruction generated");
|
||||
Instruction* dest = subtreeRoot->getInstruction();
|
||||
if (dest->getType()->isUnsigned())
|
||||
{
|
||||
if (dest->getType()->isUnsigned()) {
|
||||
unsigned destSize=target.getTargetData().getTypeSize(dest->getType());
|
||||
if (destSize <= 4)
|
||||
{ // Mask high bits. Use a TmpInstruction to represent the
|
||||
if (destSize <= 4) {
|
||||
// Mask high bits. Use a TmpInstruction to represent the
|
||||
// intermediate result before masking. Since those instructions
|
||||
// have already been generated, go back and substitute tmpI
|
||||
// for dest in the result position of each one of them.
|
||||
|
@ -2425,9 +2355,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||
M = BuildMI(V9::SRLi6, 3).addReg(tmpI).addZImm(8*(4-destSize))
|
||||
.addReg(dest, MOTy::Def);
|
||||
mvec.push_back(M);
|
||||
}
|
||||
else if (destSize < 8)
|
||||
} else if (destSize < 8) {
|
||||
assert(0 && "Unsupported type size: 32 < size < 64 bits");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define SPARC_INSTR_SELECTION_SUPPORT_h
|
||||
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "SparcInternals.h"
|
||||
|
||||
inline MachineOpCode
|
||||
ChooseLoadInstruction(const Type *DestTy)
|
||||
|
@ -77,4 +78,82 @@ ChooseAddInstructionByType(const Type* resultType)
|
|||
return opCode;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
convertOpcodeFromRegToImm(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
/* arithmetic */
|
||||
case V9::ADDr: return V9::ADDi;
|
||||
case V9::ADDccr: return V9::ADDcci;
|
||||
case V9::ADDCr: return V9::ADDCi;
|
||||
case V9::ADDCccr: return V9::ADDCcci;
|
||||
case V9::SUBr: return V9::SUBi;
|
||||
case V9::SUBccr: return V9::SUBcci;
|
||||
case V9::SUBCr: return V9::SUBCi;
|
||||
case V9::SUBCccr: return V9::SUBCcci;
|
||||
case V9::MULXr: return V9::MULXi;
|
||||
case V9::SDIVXr: return V9::SDIVXi;
|
||||
case V9::UDIVXr: return V9::UDIVXi;
|
||||
|
||||
/* logical */
|
||||
case V9::ANDr: return V9::ANDi;
|
||||
case V9::ANDccr: return V9::ANDcci;
|
||||
case V9::ANDNr: return V9::ANDNi;
|
||||
case V9::ANDNccr: return V9::ANDNcci;
|
||||
case V9::ORr: return V9::ORi;
|
||||
case V9::ORccr: return V9::ORcci;
|
||||
case V9::ORNr: return V9::ORNi;
|
||||
case V9::ORNccr: return V9::ORNcci;
|
||||
case V9::XORr: return V9::XORi;
|
||||
case V9::XORccr: return V9::XORcci;
|
||||
case V9::XNORr: return V9::XNORi;
|
||||
case V9::XNORccr: return V9::XNORcci;
|
||||
|
||||
/* shift */
|
||||
case V9::SLLr6: return V9::SLLi6;
|
||||
case V9::SRLr6: return V9::SRLi6;
|
||||
case V9::SRAr6: return V9::SRAi6;
|
||||
case V9::SLLXr6: return V9::SLLXi6;
|
||||
case V9::SRLXr6: return V9::SRLXi6;
|
||||
case V9::SRAXr6: return V9::SRAXi6;
|
||||
|
||||
/* load */
|
||||
case V9::LDSBr: return V9::LDSBi;
|
||||
case V9::LDSHr: return V9::LDSHi;
|
||||
case V9::LDSWr: return V9::LDSWi;
|
||||
case V9::LDUBr: return V9::LDUBi;
|
||||
case V9::LDUHr: return V9::LDUHi;
|
||||
case V9::LDUWr: return V9::LDUWi;
|
||||
case V9::LDXr: return V9::LDXi;
|
||||
case V9::LDFr: return V9::LDFi;
|
||||
case V9::LDDFr: return V9::LDDFi;
|
||||
case V9::LDQFr: return V9::LDQFi;
|
||||
case V9::LDFSRr: return V9::LDFSRi;
|
||||
case V9::LDXFSRr: return V9::LDXFSRi;
|
||||
|
||||
/* store */
|
||||
case V9::STBr: return V9::STBi;
|
||||
case V9::STHr: return V9::STHi;
|
||||
case V9::STWr: return V9::STWi;
|
||||
case V9::STXr: return V9::STXi;
|
||||
case V9::STFr: return V9::STFi;
|
||||
case V9::STDFr: return V9::STDFi;
|
||||
case V9::STFSRr: return V9::STFSRi;
|
||||
case V9::STXFSRr: return V9::STXFSRi;
|
||||
|
||||
/* jump & return */
|
||||
case V9::JMPLCALLr: return V9::JMPLCALLi;
|
||||
case V9::JMPLRETr: return V9::JMPLRETi;
|
||||
case V9::RETURNr: return V9::RETURNi;
|
||||
|
||||
/* save and restore */
|
||||
case V9::SAVEr: return V9::SAVEi;
|
||||
case V9::RESTOREr: return V9::RESTOREi;
|
||||
|
||||
default:
|
||||
// It's already in correct format
|
||||
return Opcode;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue