Initial implementation of the asmprinter base class
authorChris Lattner <sabre@nondot.org>
Mon, 16 Aug 2004 23:15:22 +0000 (23:15 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 16 Aug 2004 23:15:22 +0000 (23:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15838 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h [new file with mode: 0644]
lib/CodeGen/AsmPrinter.cpp [new file with mode: 0644]

diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
new file mode 100644 (file)
index 0000000..932343d
--- /dev/null
@@ -0,0 +1,65 @@
+//===-- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework --------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This class is intended to be used as a base class for target-specific
+// asmwriters.  This class primarily takes care of printing global constants,
+// which are printed in a very similar way across all targets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ASMPRINTER_H
+#define LLVM_CODEGEN_ASMPRINTER_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+  class Constant;
+  class Mangler;
+
+  class AsmPrinter : public MachineFunctionPass {
+  protected:
+    /// Output stream on which we're printing assembly code.
+    ///
+    std::ostream &O;
+
+    /// Target machine description.
+    ///
+    TargetMachine &TM;
+
+    /// Name-mangler for global names.
+    ///
+    Mangler *Mang;
+
+    /// Cache of mangled name for current function. This is recalculated at the
+    /// beginning of each call to runOnMachineFunction().
+    ///
+    std::string CurrentFnName;
+
+    AsmPrinter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { }
+
+    /// doInitialization - Set up the AsmPrinter when we are working on a new
+    /// module.  If your pass overrides this, it must make sure to explicitly
+    /// call this implementation.
+    bool doInitialization(Module &M);
+
+    /// doFinalization - Shut down the asmprinter.  If you override this in your
+    /// pass, you must make sure to call it explicitly.
+    bool doFinalization(Module &M);
+
+    /// setupMachineFunction - This should be called when a new MachineFunction
+    /// is being processed from runOnMachineFunction.
+    void setupMachineFunction(MachineFunction &MF);
+
+    /// emitConstantValueOnly - Print out the specified constant, without a
+    /// storage class.  Only constants of first-class type are allowed here.
+    void emitConstantValueOnly(const Constant *CV);
+  };
+}
+
+#endif
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp
new file mode 100644 (file)
index 0000000..1e104fc
--- /dev/null
@@ -0,0 +1,110 @@
+//===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the AsmPrinter class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/Constants.h"
+#include "llvm/Instruction.h"
+#include "llvm/Support/Mangler.h"
+#include "llvm/Target/TargetMachine.h"
+using namespace llvm;
+
+bool AsmPrinter::doInitialization(Module &M) {
+  Mang = new Mangler(M);
+  return false;
+}
+
+bool AsmPrinter::doFinalization(Module &M) {
+  delete Mang; Mang = 0;
+  return false;
+}
+
+void AsmPrinter::setupMachineFunction(MachineFunction &MF) {
+  // What's my mangled name?
+  CurrentFnName = Mang->getValueName((Value*)MF.getFunction());
+
+}
+
+
+
+// Print out the specified constant, without a storage class.  Only the
+// constants valid in constant expressions can occur here.
+void AsmPrinter::emitConstantValueOnly(const Constant *CV) {
+  if (CV->isNullValue())
+    O << "0";
+  else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
+    assert(CB == ConstantBool::True);
+    O << "1";
+  } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV))
+    if (((CI->getValue() << 32) >> 32) == CI->getValue())
+      O << CI->getValue();
+    else
+      O << (unsigned long long)CI->getValue();
+  else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
+    O << CI->getValue();
+  else if (isa<GlobalValue>((Value*)CV))
+    // This is a constant address for a global variable or function.  Use the
+    // name of the variable or function as the address value.
+    O << Mang->getValueName(CV);
+  else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
+    const TargetData &TD = TM.getTargetData();
+    switch(CE->getOpcode()) {
+    case Instruction::GetElementPtr: {
+      // generate a symbolic expression for the byte address
+      const Constant *ptrVal = CE->getOperand(0);
+      std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
+      if (unsigned Offset = TD.getIndexedOffset(ptrVal->getType(), idxVec)) {
+        O << "(";
+        emitConstantValueOnly(ptrVal);
+        O << ") + " << Offset;
+      } else {
+        emitConstantValueOnly(ptrVal);
+      }
+      break;
+    }
+    case Instruction::Cast: {
+      // Support only non-converting or widening casts for now, that is, ones
+      // that do not involve a change in value.  This assertion is really gross,
+      // and may not even be a complete check.
+      Constant *Op = CE->getOperand(0);
+      const Type *OpTy = Op->getType(), *Ty = CE->getType();
+
+      // Remember, kids, pointers can be losslessly converted back and forth
+      // into 32-bit or wider integers, regardless of signedness. :-P
+      assert(((isa<PointerType>(OpTy)
+               && (Ty == Type::LongTy || Ty == Type::ULongTy
+                   || Ty == Type::IntTy || Ty == Type::UIntTy))
+              || (isa<PointerType>(Ty)
+                  && (OpTy == Type::LongTy || OpTy == Type::ULongTy
+                      || OpTy == Type::IntTy || OpTy == Type::UIntTy))
+              || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy))
+                   && OpTy->isLosslesslyConvertibleTo(Ty))))
+             && "FIXME: Don't yet support this kind of constant cast expr");
+      O << "(";
+      emitConstantValueOnly(Op);
+      O << ")";
+      break;
+    }
+    case Instruction::Add:
+      O << "(";
+      emitConstantValueOnly(CE->getOperand(0));
+      O << ") + (";
+      emitConstantValueOnly(CE->getOperand(1));
+      O << ")";
+      break;
+    default:
+      assert(0 && "Unsupported operator!");
+    }
+  } else {
+    assert(0 && "Unknown constant value!");
+  }
+}