diff options
author | Misha Brukman <brukman+llvm@gmail.com> | 2003-05-30 20:11:56 +0000 |
---|---|---|
committer | Misha Brukman <brukman+llvm@gmail.com> | 2003-05-30 20:11:56 +0000 |
commit | 7b647942ef80aa7b522faf8c9677a1044ecd2cc2 (patch) | |
tree | 11e1498ec193566cbea973806e3594a3c8168e19 | |
parent | d1ef7a816e9bd1a658956cc04d01ff5dd1aca753 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6446 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/SparcV9/SparcV9InstrSelection.cpp | 826 | ||||
-rw-r--r-- | lib/Target/SparcV9/SparcV9InstrSelectionSupport.h | 79 |
2 files changed, 457 insertions, 448 deletions
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp index 62bc3cb6db..0670b4971f 100644 --- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp +++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp @@ -698,11 +698,11 @@ ChooseMulInstructionByType(const Type* resultType) opCode = V9::MULXr; else switch(resultType->getPrimitiveID()) - { - case Type::FloatTyID: opCode = V9::FMULS; break; - case Type::DoubleTyID: opCode = V9::FMULD; break; - default: assert(0 && "Invalid type for MUL instruction"); break; - } + { + case Type::FloatTyID: opCode = V9::FMULS; break; + case Type::DoubleTyID: opCode = V9::FMULD; break; + default: assert(0 && "Invalid type for MUL instruction"); break; + } return opCode; } @@ -747,11 +747,11 @@ 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 - shiftDest = new TmpInstruction(argVal1, optArgVal2, "sllTmp"); - mcfi.addTemp(shiftDest); - } + if ((shiftOpCode == V9::SLLr6 || shiftOpCode == V9::SLLXr6) && opSize < 8) { + // put SLL result into a temporary + shiftDest = new TmpInstruction(argVal1, optArgVal2, "sllTmp"); + mcfi.addTemp(shiftDest); + } MachineInstr* M = (optArgVal2 != NULL) ? BuildMI(shiftOpCode, 3).addReg(argVal1).addReg(optArgVal2) @@ -760,13 +760,13 @@ 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 - assert(8*opSize <= 32 && "Unexpected type size > 4 and < IntRegSize?"); - target.getInstrInfo(). - CreateSignExtensionInstructions(target, F, shiftDest, destVal, - 8*opSize, mvec, mcfi); - } + 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, + 8*opSize, mvec, mcfi); + } } @@ -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,12 +861,13 @@ CreateCheapestMulConstInstruction(const TargetMachine &target, MachineCodeForInstruction& mcfi) { Value* constOp; - 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)); - target.getInstrInfo().CreateCodeToLoadConst(target,F,P,destVal,mvec,mcfi); - } + 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)); + target.getInstrInfo().CreateCodeToLoadConst(target,F,P,destVal,mvec,mcfi); + } else if (isa<Constant>(rval)) // rval is constant, but not lval CreateMulConstInstruction(target, F, lval, rval, destVal, mvec, mcfi); else if (isa<Constant>(lval)) // lval is constant, but not rval @@ -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,41 +1039,38 @@ 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)) - { - bool isValid; - int64_t numElem = GetConstantValueAsSignedInt(numElementsVal, isValid); - assert(isValid && "Unexpectedly large array dimension in alloca!"); - int64_t total = numElem * tsize; - if (int extra= total % target.getFrameInfo().getStackFrameSizeAlignment()) - total += target.getFrameInfo().getStackFrameSizeAlignment() - extra; - totalSizeVal = ConstantSInt::get(Type::IntTy, total); - } - 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 - Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize); - - // Create temporary values to hold the result of MUL, SLL, SRL - // THIS CASE IS INCOMPLETE AND WILL BE FIXED SHORTLY. - TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal); - TmpInstruction* tmpSLL = new TmpInstruction(numElementsVal, tmpProd); - TmpInstruction* tmpSRL = new TmpInstruction(numElementsVal, tmpSLL); - mcfi.addTemp(tmpProd); - mcfi.addTemp(tmpSLL); - mcfi.addTemp(tmpSRL); - - // Instruction 1: mul numElements, typeSize -> tmpProd - // This will optimize the MUL as far as possible. - CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd,getMvec, - mcfi, INVALID_MACHINE_OPCODE); - - assert(0 && "Need to insert padding instructions here!"); - - totalSizeVal = tmpProd; - } + if (isa<Constant>(numElementsVal)) { + bool isValid; + int64_t numElem = GetConstantValueAsSignedInt(numElementsVal, isValid); + assert(isValid && "Unexpectedly large array dimension in alloca!"); + int64_t total = numElem * tsize; + if (int extra= total % target.getFrameInfo().getStackFrameSizeAlignment()) + total += target.getFrameInfo().getStackFrameSizeAlignment() - extra; + totalSizeVal = ConstantSInt::get(Type::IntTy, total); + } 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 + Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize); + + // Create temporary values to hold the result of MUL, SLL, SRL + // THIS CASE IS INCOMPLETE AND WILL BE FIXED SHORTLY. + TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal); + TmpInstruction* tmpSLL = new TmpInstruction(numElementsVal, tmpProd); + TmpInstruction* tmpSRL = new TmpInstruction(numElementsVal, tmpSLL); + mcfi.addTemp(tmpProd); + mcfi.addTemp(tmpSLL); + mcfi.addTemp(tmpSRL); + + // Instruction 1: mul numElements, typeSize -> tmpProd + // This will optimize the MUL as far as possible. + CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd,getMvec, + mcfi, INVALID_MACHINE_OPCODE); + + assert(0 && "Need to insert padding instructions here!"); + + totalSizeVal = tmpProd; + } // Get the constant offset from SP for dynamically allocated storage // and create a temporary Value to hold it. @@ -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,65 +1173,59 @@ 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()) - { - const PointerType* ptrType = cast<PointerType>(ptrVal->getType()); + if (!idxVec.empty()) { + const PointerType* ptrType = cast<PointerType>(ptrVal->getType()); - // If all indices are constant, compute the combined offset directly. - 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 - { - // 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.) - // Generate code sequence to compute address from index. - // - bool firstIdxIsZero = IsZero(idxVec[0]); - assert(idxVec.size() == 1U + firstIdxIsZero - && "Array refs must be lowered before Instruction Selection"); + // If all indices are constant, compute the combined offset directly. + 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 { + // 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.) + // Generate code sequence to compute address from index. + // + bool firstIdxIsZero = IsZero(idxVec[0]); + assert(idxVec.size() == 1U + firstIdxIsZero + && "Array refs must be lowered before Instruction Selection"); - Value* idxVal = idxVec[firstIdxIsZero]; + Value* idxVal = idxVec[firstIdxIsZero]; - std::vector<MachineInstr*> mulVec; - Instruction* addr = new TmpInstruction(Type::ULongTy, memInst); - MachineCodeForInstruction::get(memInst).addTemp(addr); + std::vector<MachineInstr*> mulVec; + Instruction* addr = new TmpInstruction(Type::ULongTy, memInst); + MachineCodeForInstruction::get(memInst).addTemp(addr); - // Get the array type indexed by idxVal, and compute its element size. - // The call to getTypeSize() will fail if size is not constant. - const Type* vecType = (firstIdxIsZero - ? GetElementPtrInst::getIndexedType(ptrType, + // Get the array type indexed by idxVal, and compute its element size. + // The call to getTypeSize() will fail if size is not constant. + const Type* vecType = (firstIdxIsZero + ? GetElementPtrInst::getIndexedType(ptrType, std::vector<Value*>(1U, idxVec[0]), /*AllowCompositeLeaf*/ true) : ptrType); - const Type* eltType = cast<SequentialType>(vecType)->getElementType(); - ConstantUInt* eltSizeVal = ConstantUInt::get(Type::ULongTy, - target.getTargetData().getTypeSize(eltType)); - - // CreateMulInstruction() folds constants intelligently enough. - CreateMulInstruction(target, memInst->getParent()->getParent(), - idxVal, /* lval, not likely to be const*/ - eltSizeVal, /* rval, likely to be constant */ - addr, /* result */ - mulVec, MachineCodeForInstruction::get(memInst), - INVALID_MACHINE_OPCODE); - - assert(mulVec.size() > 0 && "No multiply code created?"); - mvec.insert(mvec.end(), mulVec.begin(), mulVec.end()); - - valueForRegOffset = addr; - } - } - else - { - offsetOpType = MachineOperand::MO_SignExtendedImmed; - smallConstOffset = 0; + const Type* eltType = cast<SequentialType>(vecType)->getElementType(); + ConstantUInt* eltSizeVal = ConstantUInt::get(Type::ULongTy, + target.getTargetData().getTypeSize(eltType)); + + // CreateMulInstruction() folds constants intelligently enough. + CreateMulInstruction(target, memInst->getParent()->getParent(), + idxVal, /* lval, not likely to be const*/ + eltSizeVal, /* rval, likely to be constant */ + addr, /* result */ + mulVec, MachineCodeForInstruction::get(memInst), + INVALID_MACHINE_OPCODE); + + assert(mulVec.size() > 0 && "No multiply code created?"); + mvec.insert(mvec.end(), mulVec.begin(), mulVec.end()); + + valueForRegOffset = addr; } + } else { + offsetOpType = MachineOperand::MO_SignExtendedImmed; + smallConstOffset = 0; + } // For STORE: // Operand 0 is value, operand 1 is ptr, operand 2 is offset @@ -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) - { - 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++) + 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++) { + MachineInstr* minstr = mvec[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) { - MachineInstr* minstr = mvec[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) - minstr->setImplicitRef(i, fwdOp, - minstr->getImplicitOp(i).opIsDefOnly(), - minstr->getImplicitOp(i).opIsDefAndUse()); + for (unsigned i=0,numOps=minstr->getNumImplicitRefs(); i<numOps; ++i) + if (minstr->getImplicitRef(i) == unusedOp) { + minstr->setImplicitRef(i, fwdOp, + minstr->getImplicitOp(i).opIsDefOnly(), + minstr->getImplicitOp(i).opIsDefAndUse()); } } + } } @@ -1728,34 +1682,30 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, Instruction* destI = subtreeRoot->getInstruction(); Value* opVal = subtreeRoot->leftChild()->getValue(); const Type* opType = opVal->getType(); - 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: - // zero- or sign-extend, according to the signeddness of - // the destination (see above). - if (destI->getType()->isSigned()) - target.getInstrInfo().CreateSignExtensionInstructions(target, + 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: + // zero- or sign-extend, according to the signeddness of + // the destination (see above). + if (destI->getType()->isSigned()) + target.getInstrInfo().CreateSignExtensionInstructions(target, destI->getParent()->getParent(), opVal, destI, 8*destSize, mvec, MachineCodeForInstruction::get(destI)); - else - target.getInstrInfo().CreateZeroExtensionInstructions(target, + else + target.getInstrInfo().CreateZeroExtensionInstructions(target, destI->getParent()->getParent(), opVal, destI, 8*destSize, mvec, MachineCodeForInstruction::get(destI)); - } - else - forwardOperandNum = 0; // forward first operand to user - } - 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 + forwardOperandNum = 0; // forward first operand to user + } 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 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()) - { - Instruction* destI = subtreeRoot->getInstruction(); - CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, - MachineCodeForInstruction::get(destI)); - } - else + else if (opType->isFloatingPoint()) { + Instruction* destI = subtreeRoot->getInstruction(); + CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, + MachineCodeForInstruction::get(destI)); + } else assert(0 && "Unrecognized operand type for convert-to-signed"); break; } @@ -1789,61 +1737,54 @@ 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) - { - const MachineCodeForInstruction& mcfi = - MachineCodeForInstruction::get( + if (subtreeRoot->parent() != NULL) { + const MachineCodeForInstruction& mcfi = + MachineCodeForInstruction::get( cast<InstructionNode>(subtreeRoot->parent())->getInstruction()); - if (mcfi.size() == 0 || mcfi.front()->getOpCode() == V9::FSMULD) - forwardOperandNum = 0; // forward first operand to user - } + if (mcfi.size() == 0 || mcfi.front()->getOpCode() == V9::FSMULD) + forwardOperandNum = 0; // forward first operand to user + } - if (forwardOperandNum != 0) // we do need the cast - { - Value* leftVal = subtreeRoot->leftChild()->getValue(); - const Type* opType = leftVal->getType(); - MachineOpCode opCode=ChooseConvertToFloatInstr( + 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 - { - forwardOperandNum = 0; // forward first operand to user - } - 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()) - { - // 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 - // register used: single-prec for a 32-bit int or smaller, - // double-prec for a 64-bit int. - // - uint64_t srcSize = - target.getTargetData().getTypeSize(leftVal->getType()); - Type* tmpTypeToUse = - (srcSize <= 4)? Type::FloatTy : Type::DoubleTy; - srcForCast = new TmpInstruction(tmpTypeToUse, dest); - MachineCodeForInstruction &destMCFI = - MachineCodeForInstruction::get(dest); - destMCFI.addTemp(srcForCast); - - target.getInstrInfo().CreateCodeToCopyIntToFloat(target, + if (opCode == V9::INVALID_OPCODE) { // no conversion needed + forwardOperandNum = 0; // forward first operand to user + } 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()) { + // 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 + // register used: single-prec for a 32-bit int or smaller, + // double-prec for a 64-bit int. + // + uint64_t srcSize = + target.getTargetData().getTypeSize(leftVal->getType()); + Type* tmpTypeToUse = + (srcSize <= 4)? Type::FloatTy : Type::DoubleTy; + srcForCast = new TmpInstruction(tmpTypeToUse, dest); + MachineCodeForInstruction &destMCFI = + MachineCodeForInstruction::get(dest); + destMCFI.addTemp(srcForCast); + + target.getInstrInfo().CreateCodeToCopyIntToFloat(target, dest->getParent()->getParent(), leftVal, cast<Instruction>(srcForCast), mvec, destMCFI); - } - else - srcForCast = leftVal; + } else + srcForCast = leftVal; - M = BuildMI(opCode, 2).addReg(srcForCast).addRegDef(dest); - mvec.push_back(M); - } + M = BuildMI(opCode, 2).addReg(srcForCast).addRegDef(dest); + mvec.push_back(M); } + } break; case 19: // reg: ToArrayTy(reg): @@ -1854,11 +1795,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, case 233: // reg: Add(reg, Constant) maskUnsignedResult = true; M = CreateAddConstInstruction(subtreeRoot); - if (M != NULL) - { - mvec.push_back(M); - break; - } + if (M != NULL) { + mvec.push_back(M); + break; + } // ELSE FALL THROUGH case 33: // reg: Add(reg, reg) @@ -1869,11 +1809,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, case 234: // reg: Sub(reg, Constant) maskUnsignedResult = true; M = CreateSubConstInstruction(subtreeRoot); - if (M != NULL) - { - mvec.push_back(M); - break; - } + if (M != NULL) { + mvec.push_back(M); + break; + } // ELSE FALL THROUGH case 34: // reg: Sub(reg, reg) @@ -2089,68 +2028,64 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, isFPCompare ? Type::FloatTy : Type::IntTy); MachineCodeForInstruction::get(setCCInstr).addTemp(tmpForCC); - 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 - // result of SUBcc instruction anyway. - // - if (keepSubVal) { - M = BuildMI(V9::SUBccr, 4) - .addReg(subtreeRoot->leftChild()->getValue()) - .addReg(subtreeRoot->rightChild()->getValue()) - .addRegDef(subtreeRoot->getValue()) - .addCCReg(tmpForCC, MOTy::Def); - } else { - M = BuildMI(V9::SUBccr, 4) - .addReg(subtreeRoot->leftChild()->getValue()) - .addReg(subtreeRoot->rightChild()->getValue()) - .addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def) - .addCCReg(tmpForCC, MOTy::Def); - } - mvec.push_back(M); + 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 + // result of SUBcc instruction anyway. + // + if (keepSubVal) { + M = BuildMI(V9::SUBccr, 4) + .addReg(subtreeRoot->leftChild()->getValue()) + .addReg(subtreeRoot->rightChild()->getValue()) + .addRegDef(subtreeRoot->getValue()) + .addCCReg(tmpForCC, MOTy::Def); + } else { + M = BuildMI(V9::SUBccr, 4) + .addReg(subtreeRoot->leftChild()->getValue()) + .addReg(subtreeRoot->rightChild()->getValue()) + .addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def) + .addCCReg(tmpForCC, MOTy::Def); + } + mvec.push_back(M); - if (computeBoolVal) - { // recompute bool using the integer condition codes - movOpCode = - ChooseMovpccAfterSub(subtreeRoot,mustClearReg,valueToMove); - } + if (computeBoolVal) { + // recompute bool using the integer condition codes + movOpCode = + ChooseMovpccAfterSub(subtreeRoot,mustClearReg,valueToMove); } - else - { - // FP condition: dest of FCMP should be some FCCn register - M = BuildMI(ChooseFcmpInstruction(subtreeRoot), 3) - .addCCReg(tmpForCC, MOTy::Def) - .addReg(subtreeRoot->leftChild()->getValue()) - .addRegDef(subtreeRoot->rightChild()->getValue()); - mvec.push_back(M); + } else { + // FP condition: dest of FCMP should be some FCCn register + M = BuildMI(ChooseFcmpInstruction(subtreeRoot), 3) + .addCCReg(tmpForCC, MOTy::Def) + .addReg(subtreeRoot->leftChild()->getValue()) + .addRegDef(subtreeRoot->rightChild()->getValue()); + mvec.push_back(M); - if (computeBoolVal) - {// recompute bool using the FP condition codes - mustClearReg = true; - valueToMove = 1; - movOpCode = ChooseMovFpccInstruction(subtreeRoot); - } + 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 - M = BuildMI(V9::SETHI, 2).addZImm(0).addRegDef(setCCInstr); - mvec.push_back(M); - } - - // Now conditionally move `valueToMove' (0 or 1) into the register - // Mark the register as a use (as well as a def) because the old - // value should be retained if the condition is false. - M = BuildMI(movOpCode, 3).addCCReg(tmpForCC).addZImm(valueToMove) - .addReg(setCCInstr, MOTy::UseAndDef); + if (computeBoolVal) { + if (mustClearReg) { + // Unconditionally set register to 0 + M = BuildMI(V9::SETHI, 2).addZImm(0).addRegDef(setCCInstr); mvec.push_back(M); } + + // Now conditionally move `valueToMove' (0 or 1) into the register + // Mark the register as a use (as well as a def) because the old + // value should be retained if the condition is false. + M = BuildMI(movOpCode, 3).addCCReg(tmpForCC).addZImm(valueToMove) + .addReg(setCCInstr, MOTy::UseAndDef); + mvec.push_back(M); + } break; - } + } case 51: // reg: Load(reg) case 52: // reg: Load(ptrreg) @@ -2192,12 +2127,13 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, if (!isArray || isa<Constant>(numElementsVal = instr->getArraySize())) - { // total size is constant: generate code for fixed-size alloca - unsigned numElements = isArray? - cast<ConstantUInt>(numElementsVal)->getValue() : 1; - CreateCodeForFixedSizeAlloca(target, instr, tsize, - numElements, mvec); - } + { + // total size is constant: generate code for fixed-size alloca + unsigned numElements = isArray? + cast<ConstantUInt>(numElementsVal)->getValue() : 1; + CreateCodeForFixedSizeAlloca(target, instr, tsize, + numElements, mvec); + } else // total size is not constant. CreateCodeForVariableSizeAlloca(target, instr, tsize, numElementsVal, mvec); @@ -2230,98 +2166,93 @@ 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) - { - // Create hidden virtual register for return address with type void* - TmpInstruction* retAddrReg = - new TmpInstruction(PointerType::get(Type::VoidTy), callInstr); - MachineCodeForInstruction::get(callInstr).addTemp(retAddrReg); - - // Generate the machine instruction and its operands. - // Use CALL for direct function calls; this optimistically assumes - // the PC-relative address fits in the CALL address field (22 bits). - // Use JMPL for indirect calls. - // - if (calledFunc) // direct function call - M = BuildMI(V9::CALL, 1).addPCDisp(callee); - else // indirect function call - M = BuildMI(V9::JMPLCALLi, 3).addReg(callee).addSImm((int64_t)0) - .addRegDef(retAddrReg); - mvec.push_back(M); - - const FunctionType* funcType = - cast<FunctionType>(cast<PointerType>(callee->getType()) + if (! specialIntrinsic) { + // Create hidden virtual register for return address with type void* + TmpInstruction* retAddrReg = + new TmpInstruction(PointerType::get(Type::VoidTy), callInstr); + MachineCodeForInstruction::get(callInstr).addTemp(retAddrReg); + + // Generate the machine instruction and its operands. + // Use CALL for direct function calls; this optimistically assumes + // the PC-relative address fits in the CALL address field (22 bits). + // Use JMPL for indirect calls. + // + if (calledFunc) // direct function call + M = BuildMI(V9::CALL, 1).addPCDisp(callee); + else // indirect function call + M = BuildMI(V9::JMPLCALLi, 3).addReg(callee).addSImm((int64_t)0) + .addRegDef(retAddrReg); + mvec.push_back(M); + + const FunctionType* funcType = + cast<FunctionType>(cast<PointerType>(callee->getType()) ->getElementType()); - bool isVarArgs = funcType->isVarArg(); - bool noPrototype = isVarArgs && funcType->getNumParams() == 0; + bool isVarArgs = funcType->isVarArg(); + bool noPrototype = isVarArgs && funcType->getNumParams() == 0; - // Use a descriptor to pass information about call arguments - // to the register allocator. This descriptor will be "owned" - // and freed automatically when the MachineCodeForInstruction - // object for the callInstr goes away. - CallArgsDescriptor* argDesc = new CallArgsDescriptor(callInstr, |