[llvm-commits] CVS: llvm/lib/Target/CBackend/CBackend.cpp
Reid Spencer
reid at x10sys.com
Tue May 1 19:17:59 PDT 2007
Changes in directory llvm/lib/Target/CBackend:
CBackend.cpp updated: 1.339 -> 1.340
---
Log message:
Make sign extension work correctly for unusual bit widths.
---
Diffs of the changes: (+100 -28)
CBackend.cpp | 128 ++++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 100 insertions(+), 28 deletions(-)
Index: llvm/lib/Target/CBackend/CBackend.cpp
diff -u llvm/lib/Target/CBackend/CBackend.cpp:1.339 llvm/lib/Target/CBackend/CBackend.cpp:1.340
--- llvm/lib/Target/CBackend/CBackend.cpp:1.339 Tue May 1 16:15:46 2007
+++ llvm/lib/Target/CBackend/CBackend.cpp Tue May 1 21:17:41 2007
@@ -412,6 +412,29 @@
}
}
+#define IMPL_SIGN_EXTENSION(OpTy, Func) { \
+ const IntegerType* IntTy = cast<IntegerType>(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 @@
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<IntegerType>(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<IntegerType>(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 @@
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 @@
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 @@
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<IntegerType>(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<IntegerType>(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 @@
<< 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<IntegerType>(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<IntegerType>(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) {
More information about the llvm-commits
mailing list