From: Reid Spencer Date: Wed, 2 May 2007 02:17:41 +0000 (+0000) Subject: Make sign extension work correctly for unusual bit widths. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=cee7ba389e169a43ba71b3fe9f732a577e69ef01;p=oota-llvm.git Make sign extension work correctly for unusual bit widths. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36635 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index e29edff13b5..cbf480e8550 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -412,6 +412,29 @@ CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned, } } +#define IMPL_SIGN_EXTENSION(OpTy, Func) { \ + const IntegerType* IntTy = cast(OpTy); \ + unsigned BitWidth = IntTy->getBitWidth(); \ + if (BitWidth != 8 && BitWidth != 16 && BitWidth != 32 && \ + BitWidth != 64 && BitWidth != 128) { \ + const char * Suffix; \ + if (BitWidth <=32)\ + Suffix = "U"; \ + else \ + Suffix = "ULL"; \ + Out << "("; \ + Func; \ + Out << " & (1" << Suffix << " << " << BitWidth - 1 << " ) ? "; \ + Func; \ + Out << " | " << (~IntTy->getBitMask()) << Suffix << " : "; \ + Func; \ + Out << " & " << IntTy->getBitMask() << Suffix; \ + Out << ")";\ + } \ + else \ + Func; \ + } + // Pass the Type* and the variable name and this prints out the variable // declaration. // @@ -711,23 +734,39 @@ void CWriter::printConstant(Constant *CPV) { case Instruction::BitCast: Out << "("; printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType()); - if (CE->getOpcode() == Instruction::SExt && - CE->getOperand(0)->getType() == Type::Int1Ty) { - // Make sure we really sext from bool here by subtracting from 0 - Out << "0-"; - } - printConstant(CE->getOperand(0)); - if (CE->getType() == Type::Int1Ty && - (CE->getOpcode() == Instruction::Trunc || + if (CE->getOpcode() == Instruction::Trunc || CE->getOpcode() == Instruction::FPToUI || CE->getOpcode() == Instruction::FPToSI || - CE->getOpcode() == Instruction::PtrToInt)) { - // Make sure we really truncate to bool here by anding with 1 - Out << "&1u"; + CE->getOpcode() == Instruction::PtrToInt) { + if (const IntegerType* IntTy = dyn_cast(CE->getType())) { + uint64_t BitMask = IntTy->getBitMask(); + printConstant(CE->getOperand(0)); + Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL"); + } } - Out << ')'; + else if (CE->getOpcode() == Instruction::SExt && + CE->getOperand(0)->getType() == Type::Int1Ty) { + // Make sure we really sext from bool here by subtracting from 0 + Out << "0-"; + printConstant(CE->getOperand(0)); + } + else if (CE->getOpcode() == Instruction::SExt && + CE->getOperand(0)->getType()->getTypeID() == Type::IntegerTyID) { + IMPL_SIGN_EXTENSION(CE->getOperand(0)->getType(), + printConstant(CE->getOperand(0))); + } + else if (CE->getOpcode() == Instruction::ZExt && + CE->getOperand(0)->getType()->getTypeID() == Type::IntegerTyID){ + const IntegerType* IntTy = + cast(CE->getOperand(0)->getType()); + uint64_t BitMask = IntTy->getBitMask(); + writeOperand(CE->getOperand(0)); + Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL"); + } + else + printConstant(CE->getOperand(0)); + Out << ")"; return; - case Instruction::GetElementPtr: Out << "(&("; printIndexingExpression(CE->getOperand(0), gep_type_begin(CPV), @@ -1228,7 +1267,11 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) { Out << "(("; printSimpleType(Out, OpTy, castIsSigned); Out << ")"; - writeOperand(Operand); + if (castIsSigned && OpTy->getTypeID() == Type::IntegerTyID) { + IMPL_SIGN_EXTENSION(OpTy, writeOperand(Operand)); + } + else + writeOperand(Operand); Out << ")"; } else writeOperand(Operand); @@ -1253,7 +1296,9 @@ void CWriter::writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate switch (predicate) { default: // for eq and ne, it doesn't matter - break; + break; + case ICmpInst::ICMP_EQ: + case ICmpInst::ICMP_NE: case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_ULT: @@ -1278,10 +1323,25 @@ void CWriter::writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate else printType(Out, OpTy); // not integer, sign doesn't matter Out << ")"; - writeOperand(Operand); + if(castIsSigned && OpTy->getTypeID() == Type::IntegerTyID) { + IMPL_SIGN_EXTENSION(OpTy, writeOperand(Operand)); + } else { + writeOperand(Operand); + if(OpTy->getTypeID() == Type::IntegerTyID){ + const IntegerType * IntTy = cast(OpTy); + uint64_t BitMask = IntTy->getBitMask(); + Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL"); + } + } Out << ")"; - } else + } else { writeOperand(Operand); + if(OpTy->getTypeID() == Type::IntegerTyID){ + const IntegerType * IntTy = cast(OpTy); + uint64_t BitMask = IntTy->getBitMask(); + Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL"); + } + } } // generateCompilerSpecificCode - This is where we add conditional compilation @@ -2346,21 +2406,33 @@ void CWriter::visitCastInst(CastInst &I) { << getFloatBitCastField(I.getType()); } else { printCast(I.getOpcode(), SrcTy, DstTy); - if (I.getOpcode() == Instruction::SExt && SrcTy == Type::Int1Ty) { + if (I.getOpcode() == Instruction::Trunc || + I.getOpcode() == Instruction::FPToUI || + I.getOpcode() == Instruction::FPToSI || + I.getOpcode() == Instruction::PtrToInt) { + if (const IntegerType* IntTy = dyn_cast(DstTy)){ + uint64_t BitMask = IntTy->getBitMask(); + writeOperand(I.getOperand(0)); + Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL"); + } + } else if (I.getOpcode() == Instruction::SExt && SrcTy == Type::Int1Ty) { // Make sure we really get a sext from bool by subtracing the bool from 0 Out << "0-"; + writeOperand(I.getOperand(0)); + } else if (I.getOpcode() == Instruction::SExt && + SrcTy->getTypeID() == Type::IntegerTyID) { + IMPL_SIGN_EXTENSION(SrcTy, writeOperand(I.getOperand(0)) ); + } else if (I.getOpcode() == Instruction::ZExt && + SrcTy->getTypeID() == Type::IntegerTyID) { + const IntegerType* IntTy = cast(SrcTy); + uint64_t BitMask = IntTy->getBitMask(); + writeOperand(I.getOperand(0)); + Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL"); } - writeOperand(I.getOperand(0)); - if (DstTy == Type::Int1Ty && - (I.getOpcode() == Instruction::Trunc || - I.getOpcode() == Instruction::FPToUI || - I.getOpcode() == Instruction::FPToSI || - I.getOpcode() == Instruction::PtrToInt)) { - // Make sure we really get a trunc to bool by anding the operand with 1 - Out << "&1u"; - } + else + writeOperand(I.getOperand(0)); } - Out << ')'; + Out << ")"; } void CWriter::visitSelectInst(SelectInst &I) {