X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSparcV9%2FSparcV9InstrSelection.cpp;h=5195f4ac29faef839c3603f35fff817e89f62238;hb=edf3a727b7106cfa9f10aadd5e6f603bcc0b879f;hp=a68331b53ed3ca15dfcf838218857c4111d6ded3;hpb=0c4e886dbf1cf7736819a49d5143ae1c2a0cfb79;p=oota-llvm.git diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp index a68331b53ed..5195f4ac29f 100644 --- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp +++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp @@ -20,13 +20,11 @@ #include "llvm/iOther.h" #include "llvm/Function.h" #include "llvm/Constants.h" +#include "llvm/ConstantHandling.h" #include "Support/MathExtras.h" #include using std::vector; -//************************* Forward Declarations ***************************/ - - //************************ Internal Functions ******************************/ @@ -271,43 +269,38 @@ ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType) } static inline MachineOpCode -ChooseConvertToIntInstr(Type::PrimitiveID tid, const Type* opType) +ChooseConvertFPToIntInstr(Type::PrimitiveID tid, const Type* opType) { MachineOpCode opCode = INVALID_OPCODE;; - - if (tid==Type::SByteTyID || tid==Type::ShortTyID || tid==Type::IntTyID || - tid==Type::UByteTyID || tid==Type::UShortTyID || tid==Type::UIntTyID) + + assert((opType == Type::FloatTy || opType == Type::DoubleTy) + && "This function should only be called for FLOAT or DOUBLE"); + + if (tid==Type::UIntTyID) { - switch (opType->getPrimitiveID()) - { - case Type::FloatTyID: opCode = FSTOI; break; - case Type::DoubleTyID: opCode = FDTOI; break; - default: - assert(0 && "Non-numeric non-bool type cannot be converted to Int"); - break; - } + assert(tid != Type::UIntTyID && "FP-to-uint conversions must be expanded" + " into FP->long->uint for SPARC v9: SO RUN PRESELECTION PASS!"); + } + else if (tid==Type::SByteTyID || tid==Type::ShortTyID || tid==Type::IntTyID || + tid==Type::UByteTyID || tid==Type::UShortTyID) + { + opCode = (opType == Type::FloatTy)? FSTOI : FDTOI; } else if (tid==Type::LongTyID || tid==Type::ULongTyID) { - switch (opType->getPrimitiveID()) - { - case Type::FloatTyID: opCode = FSTOX; break; - case Type::DoubleTyID: opCode = FDTOX; break; - default: - assert(0 && "Non-numeric non-bool type cannot be converted to Long"); - break; - } + opCode = (opType == Type::FloatTy)? FSTOX : FDTOX; } else assert(0 && "Should not get here, Mo!"); - + return opCode; } MachineInstr* -CreateConvertToIntInstr(Type::PrimitiveID destTID, Value* srcVal,Value* destVal) +CreateConvertFPToIntInstr(Type::PrimitiveID destTID, + Value* srcVal, Value* destVal) { - MachineOpCode opCode = ChooseConvertToIntInstr(destTID, srcVal->getType()); + MachineOpCode opCode = ChooseConvertFPToIntInstr(destTID, srcVal->getType()); assert(opCode != INVALID_OPCODE && "Expected to need conversion!"); MachineInstr* M = new MachineInstr(opCode); @@ -319,6 +312,20 @@ CreateConvertToIntInstr(Type::PrimitiveID destTID, Value* srcVal,Value* destVal) // CreateCodeToConvertFloatToInt: Convert FP value to signed or unsigned integer // The FP value must be converted to the dest type in an FP register, // and the result is then copied from FP to int register via memory. +// +// Since fdtoi converts to signed integers, any FP value V between MAXINT+1 +// and MAXUNSIGNED (i.e., 2^31 <= V <= 2^32-1) would be converted incorrectly +// *only* when converting to an unsigned int. (Unsigned byte, short or long +// don't have this problem.) +// For unsigned int, we therefore have to generate the code sequence: +// +// if (V > (float) MAXINT) { +// unsigned result = (unsigned) (V - (float) MAXINT); +// result = result + (unsigned) MAXINT; +// } +// else +// result = (unsigned int) V; +// static void CreateCodeToConvertFloatToInt(const TargetMachine& target, Value* opVal, @@ -331,20 +338,20 @@ CreateCodeToConvertFloatToInt(const TargetMachine& target, // depends on the type of FP register to use: single-prec for a 32-bit // int or smaller; double-prec for a 64-bit int. // - const Type* destTypeToUse = (destI->getType() == Type::LongTy)? Type::DoubleTy - : Type::FloatTy; - Value* destForCast = new TmpInstruction(destTypeToUse, opVal); + size_t destSize = target.DataLayout.getTypeSize(destI->getType()); + const Type* destTypeToUse = (destSize > 4)? Type::DoubleTy : Type::FloatTy; + TmpInstruction* destForCast = new TmpInstruction(destTypeToUse, opVal); mcfi.addTemp(destForCast); // Create the fp-to-int conversion code - MachineInstr* M = CreateConvertToIntInstr(destI->getType()->getPrimitiveID(), - opVal, destForCast); + MachineInstr* M =CreateConvertFPToIntInstr(destI->getType()->getPrimitiveID(), + opVal, destForCast); mvec.push_back(M); // Create the fpreg-to-intreg copy code target.getInstrInfo(). CreateCodeToCopyFloatToInt(target, destI->getParent()->getParent(), - (TmpInstruction*)destForCast, destI, mvec, mcfi); + destForCast, destI, mvec, mcfi); } @@ -529,7 +536,6 @@ CreateShiftInstructions(const TargetMachine& target, // of dest, so we need to put the result of the SLL into a temporary. // Value* shiftDest = destVal; - const Type* opType = argVal1->getType(); unsigned opSize = target.DataLayout.getTypeSize(argVal1->getType()); if ((shiftOpCode == SLL || shiftOpCode == SLLX) && opSize < target.DataLayout.getIntegerRegize()) @@ -547,8 +553,8 @@ CreateShiftInstructions(const TargetMachine& target, { // 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, 8*opSize, - destVal, mvec, mcfi); + CreateSignExtensionInstructions(target, F, shiftDest, destVal, + 8*opSize, mvec, mcfi); } } @@ -659,18 +665,10 @@ CreateCheapestMulConstInstruction(const TargetMachine &target, { Value* constOp; if (isa(lval) && isa(rval)) - { // both operands are constant: try both orders! - vector mvec1, mvec2; - unsigned int lcost = CreateMulConstInstruction(target, F, lval, rval, - destVal, mvec1, mcfi); - unsigned int rcost = CreateMulConstInstruction(target, F, rval, lval, - destVal, mvec2, mcfi); - vector& mincostMvec = (lcost <= rcost)? mvec1 : mvec2; - vector& maxcostMvec = (lcost <= rcost)? mvec2 : mvec1; - mvec.insert(mvec.end(), mincostMvec.begin(), mincostMvec.end()); - - for (unsigned int i=0; i < maxcostMvec.size(); ++i) - delete maxcostMvec[i]; + { // both operands are constant: evaluate and "set" in dest + Constant* P = ConstantFoldBinaryInstruction(Instruction::Mul, + cast(lval), cast(rval)); + target.getInstrInfo().CreateCodeToLoadConst(target,F,P,destVal,mvec,mcfi); } else if (isa(rval)) // rval is constant, but not lval CreateMulConstInstruction(target, F, lval, rval, destVal, mvec, mcfi); @@ -836,7 +834,8 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target, vector& getMvec) { MachineInstr* M; - + MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(result); + // Create a Value to hold the (constant) element size Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize); @@ -853,14 +852,11 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target, // Create a temporary value to hold the result of MUL TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal); - MachineCodeForInstruction::get(result).addTemp(tmpProd); + mcfi.addTemp(tmpProd); // Instruction 1: mul numElements, typeSize -> tmpProd - M = new MachineInstr(MULX); - M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, numElementsVal); - M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tsizeVal); - M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, tmpProd); - getMvec.push_back(M); + CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd, getMvec, + mcfi, INVALID_MACHINE_OPCODE); // Instruction 2: sub %sp, tmpProd -> %sp M = new MachineInstr(SUB); @@ -885,6 +881,7 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target, unsigned int numElements, vector& getMvec) { + assert(tsize > 0 && "Illegal (zero) type size for alloca"); assert(result && result->getParent() && "Result value is not part of a function?"); Function *F = result->getParent()->getParent(); @@ -923,15 +920,6 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target, } - -// Check for a constant (uint) 0. -inline bool -IsZero(Value* idx) -{ - return (isa(idx) && cast(idx)->isNullValue()); -} - - //------------------------------------------------------------------------ // Function SetOperandsForMemInstr // @@ -950,7 +938,7 @@ IsZero(Value* idx) static void SetOperandsForMemInstr(vector& mvec, - const InstructionNode* vmInstrNode, + InstructionNode* vmInstrNode, const TargetMachine& target) { Instruction* memInst = vmInstrNode->getInstruction(); @@ -990,35 +978,36 @@ SetOperandsForMemInstr(vector& mvec, // offset. (An extra leading zero offset, if any, can be ignored.) // Generate code sequence to compute address from index. // - assert(idxVec.size() == 1U + IsZero(idxVec[0]) + bool firstIdxIsZero = + (idxVec[0] == Constant::getNullValue(idxVec[0]->getType())); + assert(idxVec.size() == 1U + firstIdxIsZero && "Array refs must be lowered before Instruction Selection"); - Value* idxVal = idxVec[IsZero(idxVec[0])]; - assert(! isa(idxVal) && "Need to sign-extend uint to 64b!"); + Value* idxVal = idxVec[firstIdxIsZero]; vector mulVec; - Instruction* addr = new TmpInstruction(Type::UIntTy, memInst); + 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. - unsigned int eltSize = - target.DataLayout.getTypeSize(ptrType->getElementType()); - assert(eltSize > 0 && "Invalid or non-const array element size"); - ConstantUInt* eltVal = ConstantUInt::get(Type::UIntTy, eltSize); + const Type* vecType = (firstIdxIsZero + ? GetElementPtrInst::getIndexedType(ptrType, + std::vector(1U, idxVec[0]), + /*AllowCompositeLeaf*/ true) + : ptrType); + const Type* eltType = cast(vecType)->getElementType(); + ConstantUInt* eltSizeVal = ConstantUInt::get(Type::ULongTy, + target.DataLayout.getTypeSize(eltType)); // CreateMulInstruction() folds constants intelligently enough. - CreateMulInstruction(target, - memInst->getParent()->getParent(), - idxVal, /* lval, not likely const */ - eltVal, /* rval, likely constant */ - addr, /* result*/ - mulVec, - MachineCodeForInstruction::get(memInst), + 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); - // Sign-extend the result of MUL from 32 to 64 bits. - target.getInstrInfo().CreateSignExtensionInstructions(target, memInst->getParent()->getParent(), addr, /*srcSizeInBits*/32, addr, mulVec, MachineCodeForInstruction::get(memInst)); - // Insert mulVec[] before *mvecI in mvec[] and update mvecI // to point to the same instruction it pointed to before. assert(mulVec.size() > 0 && "No multiply code created?"); @@ -1438,29 +1427,64 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, } case 23: // reg: ToUByteTy(reg) + case 24: // reg: ToSByteTy(reg) case 25: // reg: ToUShortTy(reg) + case 26: // reg: ToShortTy(reg) case 27: // reg: ToUIntTy(reg) - case 29: // reg: ToULongTy(reg) + case 28: // reg: ToIntTy(reg) { + //====================================================================== + // Rules for integer conversions: + // + //-------- + // From ISO 1998 C++ Standard, Sec. 4.7: + // + // 2. If the destination type is unsigned, the resulting value is + // the least unsigned integer congruent to the source integer + // (modulo 2n where n is the number of bits used to represent the + // unsigned type). [Note: In a two s complement representation, + // this conversion is conceptual and there is no change in the + // bit pattern (if there is no truncation). ] + // + // 3. If the destination type is signed, the value is unchanged if + // it can be represented in the destination type (and bitfield width); + // otherwise, the value is implementation-defined. + //-------- + // + // Since we assume 2s complement representations, this implies: + // + // -- if operand is smaller than destination, zero-extend or sign-extend + // according to the signedness of the *operand*: source decides. + // ==> we have to do nothing here! + // + // -- if operand is same size as or larger than destination, and the + // destination is *unsigned*, zero-extend the operand: dest. decides + // + // -- if operand is same size as or larger than destination, and the + // destination is *signed*, the choice is implementation defined: + // we sign-extend the operand: i.e., again dest. decides. + // Note: this matches both Sun's cc and gcc3.2. + //====================================================================== + Instruction* destI = subtreeRoot->getInstruction(); Value* opVal = subtreeRoot->leftChild()->getValue(); - const Type* opType = subtreeRoot->leftChild()->getValue()->getType(); + const Type* opType = opVal->getType(); if (opType->isIntegral() || isa(opType)) { unsigned opSize = target.DataLayout.getTypeSize(opType); unsigned destSize = target.DataLayout.getTypeSize(destI->getType()); - if (opSize > destSize || - (opType->isSigned() - && destSize < target.DataLayout.getIntegerRegize())) - { // operand is larger than dest, - // OR both are equal but smaller than the full register size - // AND operand is signed, so it may have extra sign bits: - // mask high bits using AND - M = Create3OperandInstr(AND, opVal, - ConstantUInt::get(Type::ULongTy, - ((uint64_t) 1 << 8*destSize) - 1), - destI); - mvec.push_back(M); + 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, + destI->getParent()->getParent(), opVal, destI, 8*destSize, + mvec, MachineCodeForInstruction::get(destI)); } else forwardOperandNum = 0; // forward first operand to user @@ -1469,85 +1493,53 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, { CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, MachineCodeForInstruction::get(destI)); - maskUnsignedResult = true; // not handled by convert code + if (destI->getType()->isUnsigned()) + maskUnsignedResult = true; // not handled by fp->int code } else assert(0 && "Unrecognized operand type for convert-to-unsigned"); break; } - - case 24: // reg: ToSByteTy(reg) - case 26: // reg: ToShortTy(reg) - case 28: // reg: ToIntTy(reg) + + case 29: // reg: ToULongTy(reg) case 30: // reg: ToLongTy(reg) { - Instruction* destI = subtreeRoot->getInstruction(); Value* opVal = subtreeRoot->leftChild()->getValue(); - MachineCodeForInstruction& mcfi =MachineCodeForInstruction::get(destI); - const Type* opType = opVal->getType(); if (opType->isIntegral() || isa(opType)) + forwardOperandNum = 0; // forward first operand to user + else if (opType->isFloatingPoint()) { - // These operand types have the same format as the destination, - // but may have different size: add sign bits or mask as needed. - // - const Type* destType = destI->getType(); - unsigned opSize = target.DataLayout.getTypeSize(opType); - unsigned destSize = target.DataLayout.getTypeSize(destType); - - if (opSize < destSize || - (opSize == destSize && - opSize == target.DataLayout.getIntegerRegize())) - { // operand is smaller or both operand and result fill register - forwardOperandNum = 0; // forward first operand to user - } - else - { // need to mask (possibly) and then sign-extend (definitely) - Value* srcForSignExt = opVal; - unsigned srcSizeForSignExt = 8 * opSize; - if (opSize > destSize) - { // operand is larger than dest: mask high bits - TmpInstruction *tmpI = new TmpInstruction(destType, opVal, - destI, "maskHi"); - mcfi.addTemp(tmpI); - M = Create3OperandInstr(AND, opVal, - ConstantUInt::get(Type::ULongTy, - ((uint64_t) 1 << 8*destSize)-1), - tmpI); - mvec.push_back(M); - srcForSignExt = tmpI; - srcSizeForSignExt = 8 * destSize; - } - - // sign-extend - target.getInstrInfo().CreateSignExtensionInstructions(target, destI->getParent()->getParent(), srcForSignExt, srcSizeForSignExt, destI, mvec, mcfi); - } + Instruction* destI = subtreeRoot->getInstruction(); + CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, + MachineCodeForInstruction::get(destI)); } - else if (opType->isFloatingPoint()) - CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, mcfi); else assert(0 && "Unrecognized operand type for convert-to-signed"); - break; - } + } case 31: // reg: ToFloatTy(reg): case 32: // reg: ToDoubleTy(reg): case 232: // reg: ToDoubleTy(Constant): - + // If this instruction has a parent (a user) in the tree // and the user is translated as an FsMULd instruction, // then the cast is unnecessary. So check that first. // 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 && - MachineCodeForInstruction::get(((InstructionNode*)subtreeRoot->parent())->getInstruction())[0]->getOpCode() == FSMULD) + if (subtreeRoot->parent() != NULL) { - forwardOperandNum = 0; // forward first operand to user + const MachineCodeForInstruction& mcfi = + MachineCodeForInstruction::get( + cast(subtreeRoot->parent())->getInstruction()); + if (mcfi.size() == 0 || mcfi.front()->getOpCode() == FSMULD) + forwardOperandNum = 0; // forward first operand to user } - else + + if (forwardOperandNum != 0) // we do need the cast { Value* leftVal = subtreeRoot->leftChild()->getValue(); const Type* opType = leftVal->getType(); @@ -1572,23 +1564,23 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, // register used: single-prec for a 32-bit int or smaller, // double-prec for a 64-bit int. // - const Type* srcTypeToUse = - (leftVal->getType() == Type::LongTy)? Type::DoubleTy - : Type::FloatTy; - - srcForCast = new TmpInstruction(srcTypeToUse, dest); + uint64_t srcSize = + target.DataLayout.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, (TmpInstruction*) srcForCast, + leftVal, cast(srcForCast), mvec, destMCFI); } else srcForCast = leftVal; - + M = new MachineInstr(opCode); M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, srcForCast); @@ -1923,18 +1915,18 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, mvec.push_back(new MachineInstr(ADD)); SetOperandsForMemInstr(mvec, subtreeRoot, target); break; - + case 57: // reg: Alloca: Implement as 1 instruction: { // add %fp, offsetFromFP -> result AllocationInst* instr = cast(subtreeRoot->getInstruction()); unsigned int tsize = - target.findOptimalStorageSize(instr->getAllocatedType()); + target.DataLayout.getTypeSize(instr->getAllocatedType()); assert(tsize != 0); CreateCodeForFixedSizeAlloca(target, instr, tsize, 1, mvec); break; } - + case 58: // reg: Alloca(reg): Implement as 3 instructions: // mul num, typeSz -> tmp // sub %sp, tmp -> %sp @@ -1944,7 +1936,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, const Type* eltType = instr->getAllocatedType(); // If #elements is constant, use simpler code for fixed-size allocas - int tsize = (int) target.findOptimalStorageSize(eltType); + int tsize = (int) target.DataLayout.getTypeSize(eltType); Value* numElementsVal = NULL; bool isArray = instr->isArrayAllocation(); @@ -1961,13 +1953,13 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, numElementsVal, mvec); break; } - + case 61: // reg: Call - { // Generate a direct (CALL) or indirect (JMPL). depending - // Mark the return-address register and the indirection - // register (if any) as hidden virtual registers. - // Also, mark the operands of the Call and return value (if - // any) as implicit operands of the CALL machine instruction. + { // Generate a direct (CALL) or indirect (JMPL) call. + // Mark the return-address register, the indirection + // register (for indirect calls), the operands of the Call, + // and the return value (if any) as implicit operands + // of the machine instruction. // // If this is a varargs function, floating point arguments // have to passed in integer registers so insert @@ -1975,34 +1967,22 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, // CallInst *callInstr = cast(subtreeRoot->getInstruction()); Value *callee = callInstr->getCalledValue(); - - // Create hidden virtual register for return address, with type void*. + + // 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 (isa(callee)) - { // direct function call - M = new MachineInstr(CALL); - M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp, - callee); - } - else - { // indirect function call - M = new MachineInstr(JMPLCALL); - M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, - callee); - M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed, - (int64_t) 0); - M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, - retAddrReg); - } - + if (isa(callee)) // direct function call + M = Create1OperandInstr_Addr(CALL, callee); + else // indirect function call + M = Create3OperandInstr_SImmed(JMPLCALL, callee, + (int64_t) 0, retAddrReg); mvec.push_back(M); const FunctionType* funcType = @@ -2037,7 +2017,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); @@ -2150,7 +2130,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, if (dest->getType()->isUnsigned()) { unsigned destSize = target.DataLayout.getTypeSize(dest->getType()); - if (destSize < target.DataLayout.getIntegerRegize()) + 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 @@ -2162,12 +2142,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, for (unsigned i=0, N=mvec.size(); i < N; ++i) mvec[i]->substituteValue(dest, tmpI); - M = Create3OperandInstr(AND, tmpI, - ConstantUInt::get(Type::ULongTy, - ((uint64_t) 1 << 8*destSize) - 1), - dest); + M = Create3OperandInstr_UImmed(SRL, tmpI, 8*(4-destSize), dest); mvec.push_back(M); } + else if (destSize < target.DataLayout.getIntegerRegize()) + assert(0 && "Unsupported type size: 32 < size < 64 bits"); } } }