llvm.org GIT mirror llvm / cee7ba3
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 Reid Spencer 13 years ago
1 changed file(s) with 103 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
411411 }
412412 }
413413
414 #define IMPL_SIGN_EXTENSION(OpTy, Func) { \
415 const IntegerType* IntTy = cast(OpTy); \
416 unsigned BitWidth = IntTy->getBitWidth(); \
417 if (BitWidth != 8 && BitWidth != 16 && BitWidth != 32 && \
418 BitWidth != 64 && BitWidth != 128) { \
419 const char * Suffix; \
420 if (BitWidth <=32)\
421 Suffix = "U"; \
422 else \
423 Suffix = "ULL"; \
424 Out << "("; \
425 Func; \
426 Out << " & (1" << Suffix << " << " << BitWidth - 1 << " ) ? "; \
427 Func; \
428 Out << " | " << (~IntTy->getBitMask()) << Suffix << " : "; \
429 Func; \
430 Out << " & " << IntTy->getBitMask() << Suffix; \
431 Out << ")";\
432 } \
433 else \
434 Func; \
435 }
436
414437 // Pass the Type* and the variable name and this prints out the variable
415438 // declaration.
416439 //
710733 case Instruction::BitCast:
711734 Out << "(";
712735 printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType());
713 if (CE->getOpcode() == Instruction::SExt &&
714 CE->getOperand(0)->getType() == Type::Int1Ty) {
736 if (CE->getOpcode() == Instruction::Trunc ||
737 CE->getOpcode() == Instruction::FPToUI ||
738 CE->getOpcode() == Instruction::FPToSI ||
739 CE->getOpcode() == Instruction::PtrToInt) {
740 if (const IntegerType* IntTy = dyn_cast(CE->getType())) {
741 uint64_t BitMask = IntTy->getBitMask();
742 printConstant(CE->getOperand(0));
743 Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
744 }
745 }
746 else if (CE->getOpcode() == Instruction::SExt &&
747 CE->getOperand(0)->getType() == Type::Int1Ty) {
715748 // Make sure we really sext from bool here by subtracting from 0
716749 Out << "0-";
750 printConstant(CE->getOperand(0));
717751 }
718 printConstant(CE->getOperand(0));
719 if (CE->getType() == Type::Int1Ty &&
720 (CE->getOpcode() == Instruction::Trunc ||
721 CE->getOpcode() == Instruction::FPToUI ||
722 CE->getOpcode() == Instruction::FPToSI ||
723 CE->getOpcode() == Instruction::PtrToInt)) {
724 // Make sure we really truncate to bool here by anding with 1
725 Out << "&1u";
726 }
727 Out << ')';
752 else if (CE->getOpcode() == Instruction::SExt &&
753 CE->getOperand(0)->getType()->getTypeID() == Type::IntegerTyID) {
754 IMPL_SIGN_EXTENSION(CE->getOperand(0)->getType(),
755 printConstant(CE->getOperand(0)));
756 }
757 else if (CE->getOpcode() == Instruction::ZExt &&
758 CE->getOperand(0)->getType()->getTypeID() == Type::IntegerTyID){
759 const IntegerType* IntTy =
760 cast(CE->getOperand(0)->getType());
761 uint64_t BitMask = IntTy->getBitMask();
762 writeOperand(CE->getOperand(0));
763 Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
764 }
765 else
766 printConstant(CE->getOperand(0));
767 Out << ")";
728768 return;
729
730769 case Instruction::GetElementPtr:
731770 Out << "(&(";
732771 printIndexingExpression(CE->getOperand(0), gep_type_begin(CPV),
12271266 Out << "((";
12281267 printSimpleType(Out, OpTy, castIsSigned);
12291268 Out << ")";
1230 writeOperand(Operand);
1269 if (castIsSigned && OpTy->getTypeID() == Type::IntegerTyID) {
1270 IMPL_SIGN_EXTENSION(OpTy, writeOperand(Operand));
1271 }
1272 else
1273 writeOperand(Operand);
12311274 Out << ")";
12321275 } else
12331276 writeOperand(Operand);
12521295 switch (predicate) {
12531296 default:
12541297 // for eq and ne, it doesn't matter
1255 break;
1298 break;
1299 case ICmpInst::ICMP_EQ:
1300 case ICmpInst::ICMP_NE:
12561301 case ICmpInst::ICMP_UGT:
12571302 case ICmpInst::ICMP_UGE:
12581303 case ICmpInst::ICMP_ULT:
12771322 else
12781323 printType(Out, OpTy); // not integer, sign doesn't matter
12791324 Out << ")";
1325 if(castIsSigned && OpTy->getTypeID() == Type::IntegerTyID) {
1326 IMPL_SIGN_EXTENSION(OpTy, writeOperand(Operand));
1327 } else {
1328 writeOperand(Operand);
1329 if(OpTy->getTypeID() == Type::IntegerTyID){
1330 const IntegerType * IntTy = cast(OpTy);
1331 uint64_t BitMask = IntTy->getBitMask();
1332 Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
1333 }
1334 }
1335 Out << ")";
1336 } else {
12801337 writeOperand(Operand);
1281 Out << ")";
1282 } else
1283 writeOperand(Operand);
1338 if(OpTy->getTypeID() == Type::IntegerTyID){
1339 const IntegerType * IntTy = cast(OpTy);
1340 uint64_t BitMask = IntTy->getBitMask();
1341 Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
1342 }
1343 }
12841344 }
12851345
12861346 // generateCompilerSpecificCode - This is where we add conditional compilation
23452405 << getFloatBitCastField(I.getType());
23462406 } else {
23472407 printCast(I.getOpcode(), SrcTy, DstTy);
2348 if (I.getOpcode() == Instruction::SExt && SrcTy == Type::Int1Ty) {
2408 if (I.getOpcode() == Instruction::Trunc ||
2409 I.getOpcode() == Instruction::FPToUI ||
2410 I.getOpcode() == Instruction::FPToSI ||
2411 I.getOpcode() == Instruction::PtrToInt) {
2412 if (const IntegerType* IntTy = dyn_cast(DstTy)){
2413 uint64_t BitMask = IntTy->getBitMask();
2414 writeOperand(I.getOperand(0));
2415 Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
2416 }
2417 } else if (I.getOpcode() == Instruction::SExt && SrcTy == Type::Int1Ty) {
23492418 // Make sure we really get a sext from bool by subtracing the bool from 0
23502419 Out << "0-";
2351 }
2352 writeOperand(I.getOperand(0));
2353 if (DstTy == Type::Int1Ty &&
2354 (I.getOpcode() == Instruction::Trunc ||
2355 I.getOpcode() == Instruction::FPToUI ||
2356 I.getOpcode() == Instruction::FPToSI ||
2357 I.getOpcode() == Instruction::PtrToInt)) {
2358 // Make sure we really get a trunc to bool by anding the operand with 1
2359 Out << "&1u";
2360 }
2361 }
2362 Out << ')';
2420 writeOperand(I.getOperand(0));
2421 } else if (I.getOpcode() == Instruction::SExt &&
2422 SrcTy->getTypeID() == Type::IntegerTyID) {
2423 IMPL_SIGN_EXTENSION(SrcTy, writeOperand(I.getOperand(0)) );
2424 } else if (I.getOpcode() == Instruction::ZExt &&
2425 SrcTy->getTypeID() == Type::IntegerTyID) {
2426 const IntegerType* IntTy = cast(SrcTy);
2427 uint64_t BitMask = IntTy->getBitMask();
2428 writeOperand(I.getOperand(0));
2429 Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
2430 }
2431 else
2432 writeOperand(I.getOperand(0));
2433 }
2434 Out << ")";
23632435 }
23642436
23652437 void CWriter::visitSelectInst(SelectInst &I) {