- // Combines expressions
- inline std::string ConstantArithExprToString(const ConstantExpr* CE,
- const TargetMachine &TM,
- const std::string &op) {
- return "(" + valToExprString(CE->getOperand(0), TM) + op
- + valToExprString(CE->getOperand(1), TM) + ")";
- }
-
- /// ConstantExprToString() - Convert a ConstantExpr to an asm expression
- /// and return this as a string.
- ///
- std::string ConstantExprToString(const ConstantExpr* CE,
- const TargetMachine& target);
-
- /// valToExprString - Helper function for ConstantExprToString().
- /// Appends result to argument string S.
- ///
- std::string valToExprString(const Value* V, const TargetMachine& target);
- };
-} // End anonymous namespace
-
-
-/// Print a single constant value.
-///
-void AsmPrinter::printSingleConstantValue(const Constant* CV) {
- assert(CV->getType() != Type::VoidTy &&
- CV->getType() != Type::LabelTy &&
- "Unexpected type for Constant");
-
- assert((!isa<ConstantArray>(CV) && ! isa<ConstantStruct>(CV))
- && "Aggregate types should be handled outside this function");
-
- toAsm << "\t" << TypeToDataDirective(CV->getType()) << "\t";
-
- if (const GlobalValue* GV = dyn_cast<GlobalValue>(CV)) {
- toAsm << getID(GV) << "\n";
- } else if (isa<ConstantPointerNull>(CV)) {
- // Null pointer value
- toAsm << "0\n";
- } else if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV)) {
- // Constant expression built from operators, constants, and symbolic addrs
- toAsm << ConstantExprToString(CE, Target) << "\n";
- } else if (CV->getType()->isPrimitiveType()) {
- // Check primitive types last
- if (CV->getType()->isFloatingPoint()) {
- // FP Constants are printed as integer constants to avoid losing
- // precision...
- double Val = cast<ConstantFP>(CV)->getValue();
- if (CV->getType() == Type::FloatTy) {
- float FVal = (float)Val;
- char *ProxyPtr = (char*)&FVal; // Abide by C TBAA rules
- toAsm << *(unsigned int*)ProxyPtr;
- } else if (CV->getType() == Type::DoubleTy) {
- char *ProxyPtr = (char*)&Val; // Abide by C TBAA rules
- toAsm << *(uint64_t*)ProxyPtr;
- } else {
- assert(0 && "Unknown floating point type!");
- }
-
- toAsm << "\t! " << CV->getType()->getDescription()
- << " value: " << Val << "\n";
- } else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
- toAsm << (int)CB->getValue() << "\n";
- } else {
- WriteAsOperand(toAsm, CV, false, false) << "\n";
- }
- } else {
- assert(0 && "Unknown elementary type for constant");
- }
-}
-
-/// Print a constant value or values (it may be an aggregate).
-/// Uses printSingleConstantValue() to print each individual value.
-///
-void AsmPrinter::printConstantValueOnly(const Constant* CV,
- int numPadBytesAfter) {
- if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
- if (CVA->isString()) {
- // print the string alone and return
- toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
- } else {
- // Not a string. Print the values in successive locations
- for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i)
- printConstantValueOnly(CVA->getOperand(i));
- }
- } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
- // Print the fields in successive locations. Pad to align if needed!
- const StructLayout *cvsLayout =
- Target.getTargetData().getStructLayout(CVS->getType());
- unsigned sizeSoFar = 0;
- for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) {
- const Constant* field = CVS->getOperand(i);
-
- // Check if padding is needed and insert one or more 0s.
- unsigned fieldSize =
- Target.getTargetData().getTypeSize(field->getType());
- int padSize = ((i == e-1? cvsLayout->StructSize
- : cvsLayout->MemberOffsets[i+1])
- - cvsLayout->MemberOffsets[i]) - fieldSize;
- sizeSoFar += (fieldSize + padSize);
-
- // Now print the actual field value
- printConstantValueOnly(field, padSize);
- }
- assert(sizeSoFar == cvsLayout->StructSize &&
- "Layout of constant struct may be incorrect!");
- } else if (isa<ConstantAggregateZero>(CV)) {
- PrintZeroBytesToPad(Target.getTargetData().getTypeSize(CV->getType()));
- } else
- printSingleConstantValue(CV);
-
- if (numPadBytesAfter)
- PrintZeroBytesToPad(numPadBytesAfter);
-}
-
-/// ConstantExprToString() - Convert a ConstantExpr to an asm expression
-/// and return this as a string.
-///
-std::string AsmPrinter::ConstantExprToString(const ConstantExpr* CE,
- const TargetMachine& target) {
- std::string S;
- switch(CE->getOpcode()) {
- case Instruction::GetElementPtr:
- { // generate a symbolic expression for the byte address
- const Value* ptrVal = CE->getOperand(0);
- std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
- const TargetData &TD = target.getTargetData();
- S += "(" + valToExprString(ptrVal, target) + ") + ("
- + utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")";
- break;
- }
-
- case Instruction::Cast:
- // Support only non-converting casts for now, i.e., a no-op.
- // This assertion is not a complete check.
- assert(target.getTargetData().getTypeSize(CE->getType()) ==
- target.getTargetData().getTypeSize(CE->getOperand(0)->getType()));
- S += "(" + valToExprString(CE->getOperand(0), target) + ")";
- break;
-
- case Instruction::Add:
- S += ConstantArithExprToString(CE, target, ") + (");
- break;
-
- case Instruction::Sub:
- S += ConstantArithExprToString(CE, target, ") - (");
- break;
-
- case Instruction::Mul:
- S += ConstantArithExprToString(CE, target, ") * (");
- break;
-
- case Instruction::Div:
- S += ConstantArithExprToString(CE, target, ") / (");
- break;
-
- case Instruction::Rem:
- S += ConstantArithExprToString(CE, target, ") % (");
- break;
-
- case Instruction::And:
- // Logical && for booleans; bitwise & otherwise
- S += ConstantArithExprToString(CE, target,
- ((CE->getType() == Type::BoolTy)? ") && (" : ") & ("));
- break;
-
- case Instruction::Or:
- // Logical || for booleans; bitwise | otherwise
- S += ConstantArithExprToString(CE, target,
- ((CE->getType() == Type::BoolTy)? ") || (" : ") | ("));
- break;
-
- case Instruction::Xor:
- // Bitwise ^ for all types
- S += ConstantArithExprToString(CE, target, ") ^ (");
- break;
-
- default:
- assert(0 && "Unsupported operator in ConstantExprToString()");
- break;
- }
-
- return S;
-}
-
-/// valToExprString - Helper function for ConstantExprToString().
-/// Appends result to argument string S.
-///
-std::string AsmPrinter::valToExprString(const Value* V,
- const TargetMachine& target) {
- std::string S;
- bool failed = false;
- if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
- S += getID(GV);
- } else if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known
- if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV))
- S += std::string(CB == ConstantBool::True ? "1" : "0");
- else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV))
- S += itostr(CI->getValue());
- else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
- S += utostr(CI->getValue());
- else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
- S += ftostr(CFP->getValue());
- else if (isa<ConstantPointerNull>(CV))
- S += "0";
- else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV))
- S += ConstantExprToString(CE, target);
- else
- failed = true;
- } else
- failed = true;
-
- if (failed) {
- assert(0 && "Cannot convert value to string");
- S += "<illegal-value>";
- }
- return S;
-}
-
-
-//===----------------------------------------------------------------------===//
-// SparcV9AsmPrinter Code
-//===----------------------------------------------------------------------===//
-
-namespace {
-
- struct SparcV9AsmPrinter : public FunctionPass, public AsmPrinter {
- inline SparcV9AsmPrinter(std::ostream &os, const TargetMachine &t)
- : AsmPrinter(os, t) {}
-
- const Function *currFunction;
-
- const char *getPassName() const {
- return "Output SparcV9 Assembly for Functions";
- }
-
- virtual bool doInitialization(Module &M) {
- startModule(M);
- return false;
- }
-
- virtual bool runOnFunction(Function &F) {
- currFunction = &F;
- emitFunction(F);