[llvm-commits] [SignlessTypes] CVS: llvm/lib/Target/CBackend/Writer.cpp
Reid Spencer
reid at x10sys.com
Wed Oct 25 18:58:36 PDT 2006
Changes in directory llvm/lib/Target/CBackend:
Writer.cpp updated: 1.272.2.6 -> 1.272.2.7
---
Log message:
Round 2 of DIV updates.
---
Diffs of the changes: (+152 -4)
Writer.cpp | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 152 insertions(+), 4 deletions(-)
Index: llvm/lib/Target/CBackend/Writer.cpp
diff -u llvm/lib/Target/CBackend/Writer.cpp:1.272.2.6 llvm/lib/Target/CBackend/Writer.cpp:1.272.2.7
--- llvm/lib/Target/CBackend/Writer.cpp:1.272.2.6 Mon Oct 23 13:13:27 2006
+++ llvm/lib/Target/CBackend/Writer.cpp Wed Oct 25 20:58:05 2006
@@ -121,6 +121,8 @@
void writeOperand(Value *Operand);
void writeOperandInternal(Value *Operand);
+ void writeOperandWithCast(Value* Operand, unsigned Opcode);
+ bool writeInstructionCast(const Instruction &I);
private :
void lowerIntrinsics(Function &F);
@@ -136,6 +138,8 @@
void printLoop(Loop *L);
void printConstant(Constant *CPV);
+ void printConstantWithCast(Constant *CPV, unsigned Opcode);
+ bool printConstExprCast(const ConstantExpr *CE);
void printConstantArray(ConstantArray *CPA);
void printConstantPacked(ConstantPacked *CP);
@@ -604,7 +608,8 @@
case Instruction::Shl:
case Instruction::Shr:
Out << '(';
- printConstant(CE->getOperand(0));
+ bool NeedsClosingParens = printConstExprCast(CE);
+ printConstantWithCast(CE->getOperand(0), CE->getOpcode());
switch (CE->getOpcode()) {
case Instruction::Add: Out << " + "; break;
case Instruction::Sub: Out << " - "; break;
@@ -628,7 +633,9 @@
case Instruction::Shr: Out << " >> "; break;
default: assert(0 && "Illegal opcode here!");
}
- printConstant(CE->getOperand(1));
+ printConstantWithCast(CE->getOperand(1), CE->getOpcode());
+ if (NeedsClosingParens)
+ Out << "))";
Out << ')';
return;
@@ -813,6 +820,71 @@
}
}
+// Some constant expressions need to be casted back to the original types
+// because their operands were casted to the expected type. This function takes
+// care of detecting that case and printing the cast for the ConstantExpr.
+bool CWriter::printConstExprCast(const ConstantExpr* CE) {
+ bool Result = false;
+ const Type* Ty = CE->getOperand(0)->getType();
+ switch (CE->getOpcode()) {
+ case Instruction::UDiv: Result = Ty->isSigned(); break;
+ case Instruction::SDiv: Result = Ty->isUnsigned(); break;
+ default: break;
+ }
+ if (Result) {
+ Out << "((";
+ printType(Out, Ty);
+ Out << ")(";
+ }
+ return Result;
+}
+
+// Print a constant assuming that it is the operand for a given Opcode. The
+// opcodes that care about sign need to cast their operands to the expected
+// type before the operation proceeds. This function does the casting.
+void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
+
+ // Extract the operand's type, we'll need it.
+ const Type* OpTy = CPV->getType();
+
+ // Indicate whether to do the cast or not.
+ bool shouldCast = false;
+
+ // Based on the Opcode for which this Constant is being written, determine
+ // the new type to which the operand should be casted by setting the value
+ // of OpTy. If we change OpTy, also set shouldCast to true.
+ switch (Opcode) {
+ default:
+ // for most instructions, it doesn't matter
+ break;
+ case Instruction::UDiv:
+ // For UDiv to have unsigned operands
+ if (OpTy->isSigned()) {
+ OpTy = OpTy->getUnsignedVersion();
+ shouldCast = true;
+ }
+ break;
+ case Instruction::SDiv:
+ if (OpTy->isUnsigned()) {
+ OpTy = OpTy->getSignedVersion();
+ shouldCast = true;
+ }
+ break;
+ }
+
+ // Write out the casted constnat if we should, otherwise just write the
+ // operand.
+ if (shouldCast) {
+ Out << "((";
+ printType(Out, OpTy);
+ Out << ")";
+ printConstant(CPV);
+ Out << ")";
+ } else
+ writeOperand(CPV);
+
+}
+
void CWriter::writeOperandInternal(Value *Operand) {
if (Instruction *I = dyn_cast<Instruction>(Operand))
if (isInlinableInst(*I) && !isDirectAlloca(I)) {
@@ -841,6 +913,72 @@
Out << ')';
}
+// Some instructions need to have their result value casted back to the
+// original types because their operands were casted to the expected type.
+// This function takes care of detecting that case and printing the cast
+// for the Instruction.
+bool CWriter::writeInstructionCast(const Instruction &I) {
+ bool Result = false;
+ const Type* Ty = I.getOperand(0)->getType();
+ switch (I.getOpcode()) {
+ case Instruction::UDiv: Result = Ty->isSigned(); break;
+ case Instruction::SDiv: Result = Ty->isUnsigned(); break;
+ default: break;
+ }
+ if (Result) {
+ Out << "((";
+ printType(Out, Ty);
+ Out << ")(";
+ }
+ return Result;
+}
+
+// Write the operand with a cast to another type based on the Opcode being used.
+// This will be used in cases where an instruction has specific type
+// requirements (usually signedness) for its operands.
+void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
+
+ // Extract the operand's type, we'll need it.
+ const Type* OpTy = Operand->getType();
+
+ // Indicate whether to do the cast or not.
+ bool shouldCast = false;
+
+ // Based on the Opcode for which this Operand is being written, determine
+ // the new type to which the operand should be casted by setting the value
+ // of OpTy. If we change OpTy, also set shouldCast to true.
+ switch (Opcode) {
+ default:
+ // for most instructions, it doesn't matter
+ break;
+ case Instruction::UDiv:
+ // For UDiv to have unsigned operands
+ if (OpTy->isSigned()) {
+ OpTy = OpTy->getUnsignedVersion();
+ shouldCast = true;
+ }
+ break;
+ case Instruction::SDiv:
+ if (OpTy->isUnsigned()) {
+ OpTy = OpTy->getSignedVersion();
+ shouldCast = true;
+ }
+ break;
+ }
+
+ // Write out the casted operand if we should, otherwise just write the
+ // operand.
+ if (shouldCast) {
+ Out << "((";
+ printType(Out, OpTy);
+ Out << ")";
+ writeOperand(Operand);
+ Out << ")";
+ } else
+ writeOperand(Operand);
+
+}
+
// generateCompilerSpecificCode - This is where we add conditional compilation
// directives to cater to specific compilers as need be.
//
@@ -1651,7 +1789,15 @@
writeOperand(I.getOperand(1));
Out << ")";
} else {
- writeOperand(I.getOperand(0));
+
+ // Write out the cast of the instruction's value back to the proper type
+ // if necessary.
+ bool NeedsClosingParens = writeInstructionCast(I);
+
+ // Certain instructions require the operand to be forced to a specific type
+ // so we use writeOperandWithCast here instead of writeOperand. Similarly
+ // below for operand 1
+ writeOperandWithCast(I.getOperand(0), I.getOpcode());
switch (I.getOpcode()) {
case Instruction::Add: Out << " + "; break;
@@ -1677,7 +1823,9 @@
default: std::cerr << "Invalid operator type!" << I; abort();
}
- writeOperand(I.getOperand(1));
+ writeOperandWithCast(I.getOperand(1), I.getOpcode());
+ if (NeedsClosingParens)
+ Out << "))";
}
if (needsCast) {
More information about the llvm-commits
mailing list