diff options
| author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-07-31 21:01:34 +0000 | 
|---|---|---|
| committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-07-31 21:01:34 +0000 | 
| commit | defe6ec939866876b5da6c4dff209dcdf4cc3fef (patch) | |
| tree | 5e4ba2f85278eba3c319789916b2b3b5dc539e61 /llvm/lib/Target/Sparc/SparcInstrSelection.cpp | |
| parent | ad5a79527f48dba62488cb28e2b2e389bb9d73d5 (diff) | |
| download | bcm5719-llvm-defe6ec939866876b5da6c4dff209dcdf4cc3fef.tar.gz bcm5719-llvm-defe6ec939866876b5da6c4dff209dcdf4cc3fef.zip  | |
Add a missing case: converting float/double to unsigned integer types.
llvm-svn: 3188
Diffstat (limited to 'llvm/lib/Target/Sparc/SparcInstrSelection.cpp')
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcInstrSelection.cpp | 150 | 
1 files changed, 73 insertions, 77 deletions
diff --git a/llvm/lib/Target/Sparc/SparcInstrSelection.cpp b/llvm/lib/Target/Sparc/SparcInstrSelection.cpp index 8783a1e86e5..36c05f09176 100644 --- a/llvm/lib/Target/Sparc/SparcInstrSelection.cpp +++ b/llvm/lib/Target/Sparc/SparcInstrSelection.cpp @@ -286,11 +286,12 @@ ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType)  }  static inline MachineOpCode  -ChooseConvertToIntInstr(OpLabel vopCode, const Type* opType) +ChooseConvertToIntInstr(Type::PrimitiveID tid, const Type* opType)  {    MachineOpCode opCode = INVALID_OPCODE;; -  if (vopCode == ToSByteTy || vopCode == ToShortTy || vopCode == ToIntTy) +  if (tid==Type::SByteTyID || tid==Type::ShortTyID  || tid==Type::IntTyID || +      tid==Type::UByteTyID || tid==Type::UShortTyID || tid==Type::UIntTyID)      {        switch (opType->getPrimitiveID())          { @@ -301,7 +302,7 @@ ChooseConvertToIntInstr(OpLabel vopCode, const Type* opType)            break;          }      } -  else if (vopCode == ToLongTy) +  else if (tid==Type::LongTyID || tid==Type::ULongTyID)      {        switch (opType->getPrimitiveID())          { @@ -319,9 +320,9 @@ ChooseConvertToIntInstr(OpLabel vopCode, const Type* opType)  }  MachineInstr* -CreateConvertToIntInstr(OpLabel vopCode, Value* srcVal, Value* destVal) +CreateConvertToIntInstr(Type::PrimitiveID destTID, Value* srcVal,Value* destVal)  { -  MachineOpCode opCode = ChooseConvertToIntInstr(vopCode, srcVal->getType()); +  MachineOpCode opCode = ChooseConvertToIntInstr(destTID, srcVal->getType());    assert(opCode != INVALID_OPCODE && "Expected to need conversion!");    MachineInstr* M = new MachineInstr(opCode); @@ -330,6 +331,38 @@ CreateConvertToIntInstr(OpLabel vopCode, Value* srcVal, Value* destVal)    return M;  } +// CreateCodeToConvertIntToFloat: 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. +static void +CreateCodeToConvertIntToFloat (const TargetMachine& target, +                               Value* opVal, +                               Instruction* destI, +                               std::vector<MachineInstr*>& mvec, +                               MachineCodeForInstruction& mcfi) +{ +  // Create a temporary to represent the FP register into which the +  // int value will placed after conversion.  The type of this temporary +  // 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); +  mcfi.addTemp(destForCast); + +  // Create the fp-to-int conversion code +  MachineInstr* M = CreateConvertToIntInstr(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); +} + +  static inline MachineOpCode   ChooseAddInstruction(const InstructionNode* instrNode)  { @@ -1494,30 +1527,34 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,          Instruction* destI =  subtreeRoot->getInstruction();          Value* opVal = subtreeRoot->leftChild()->getValue();          const Type* opType = subtreeRoot->leftChild()->getValue()->getType(); -        assert(opType->isIntegral() || -               isa<PointerType>(opType) || -               opType == Type::BoolTy && "Cast is illegal for other types"); -         -        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 (opType->isIntegral() +            || isa<PointerType>(opType) +            || opType == Type::BoolTy) +          { +            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); +              } +            else +              forwardOperandNum = 0;          // forward first operand to user            } +        else if (opType->isFloatingPoint()) +          CreateCodeToConvertIntToFloat(target, opVal, destI, mvec, +                                        MachineCodeForInstruction::get(destI));          else -          forwardOperandNum = 0;          // forward first operand to user -         +          assert(0 && "Unrecognized operand type for convert-to-unsigned"); +          break;        } @@ -1526,11 +1563,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,        case 28:	// reg:   ToIntTy(reg)        case 30:	// reg:   ToLongTy(reg)        { -        unsigned int oldMvecSize = mvec.size(); // to check if it grew          Instruction* destI =  subtreeRoot->getInstruction();          Value* opVal = subtreeRoot->leftChild()->getValue();          MachineCodeForInstruction& mcfi =MachineCodeForInstruction::get(destI); -         +          const Type* opType = opVal->getType();          if (opType->isIntegral()              || isa<PointerType>(opType) @@ -1542,11 +1578,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,              const Type* destType = destI->getType();              unsigned opSize = target.DataLayout.getTypeSize(opType);              unsigned destSize = target.DataLayout.getTypeSize(destType); -            if (opSize <= destSize && !opType->isSigned()) -              { // operand is smaller than or same size as dest: -                // -- if operand is signed (checked above), nothing to do -                // -- if operand is unsigned, sign-extend the value: -                //  +            if (opSize < destSize && !opType->isSigned()) +              { // operand is unsigned and smaller than dest: sign-extend                  target.getInstrInfo().CreateSignExtensionInstructions(target, destI->getParent()->getParent(), opVal, 8*opSize, destI, mvec, mcfi);                }              else if (opSize > destSize) @@ -1564,51 +1597,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,                  target.getInstrInfo().CreateSignExtensionInstructions(target, destI->getParent()->getParent(), tmpI, 8*destSize, destI, mvec, mcfi);                } -          } -        else -          { -            // If the source operand is an FP type, the int result must be -            // copied from float to int register via memory! -            Value* leftVal = subtreeRoot->leftChild()->getValue(); -            Value* destForCast; -            vector<MachineInstr*> minstrVec; -             -            if (opType->isFloatingPoint()) -              { -                // Create a temporary to represent the INT register -                // into which the FP value 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. -                //  -                const Type* destTypeToUse = -                  (destI->getType() == Type::LongTy)? Type::DoubleTy -                                                   : Type::FloatTy; -                destForCast = new TmpInstruction(destTypeToUse, leftVal); -                MachineCodeForInstruction &destMCFI =  -                  MachineCodeForInstruction::get(destI); -                destMCFI.addTemp(destForCast); -                 -                target.getInstrInfo(). -                  CreateCodeToCopyFloatToInt(target, -                                             destI->getParent()->getParent(), -                                             (TmpInstruction*) destForCast, -                                             destI, minstrVec, destMCFI); -              }              else -              destForCast = leftVal; -             -            M = CreateConvertToIntInstr(subtreeRoot->getOpLabel(), -                                        leftVal, destForCast); -            mvec.push_back(M); -             -            // Append the copy code, if any, after the conversion instr. -            mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end()); +              forwardOperandNum = 0;          // forward first operand to user            } -         -        if (oldMvecSize == mvec.size()) // no instruction was generated -          forwardOperandNum = 0;  // forward first operand to user -         +        else if (opType->isFloatingPoint()) +          CreateCodeToConvertIntToFloat(target, opVal, destI, mvec, mcfi); +        else +          assert(0 && "Unrecognized operand type for convert-to-signed"); +          break;        }    | 

