LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

EmitBytecodeToAssembly.cpp

Go to the documentation of this file.
00001 //===-- EmitBytecodeToAssembly.cpp - Emit bytecode to SparcV9 .s File ------==//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the pass that writes LLVM bytecode as data to a sparc
00011 // assembly file.  The bytecode gets assembled into a special bytecode section
00012 // of the executable for use at runtime later.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #include "SparcV9Internals.h"
00017 #include "llvm/Pass.h"
00018 #include "llvm/Bytecode/Writer.h"
00019 #include <iostream>
00020 using namespace llvm;
00021 
00022 namespace {
00023 
00024   // sparcasmbuf - stream buf for encoding output bytes as .byte directives for
00025   // the sparc assembler.
00026   //
00027   class sparcasmbuf : public std::streambuf {
00028     std::ostream &BaseStr;
00029   public:
00030     typedef char           char_type;
00031     typedef int            int_type;
00032     typedef std::streampos pos_type;
00033     typedef std::streamoff off_type;
00034     
00035     sparcasmbuf(std::ostream &On) : BaseStr(On) {}
00036 
00037     virtual int_type overflow(int_type C) {
00038       if (C != EOF)
00039         BaseStr << "\t.byte " << C << "\n"; // Output C;
00040       return C;
00041     }
00042   };
00043 
00044 
00045   // osparcasmstream - Define an ostream implementation that uses a sparcasmbuf
00046   // as the underlying streambuf to write the data to.  This streambuf formats
00047   // the output as .byte directives for sparc output.
00048   //
00049   class osparcasmstream : public std::ostream {
00050     sparcasmbuf sb;
00051   public:
00052     typedef char           char_type;
00053     typedef int            int_type;
00054     typedef std::streampos pos_type;
00055     typedef std::streamoff off_type;
00056 
00057     explicit osparcasmstream(std::ostream &On) : std::ostream(&sb), sb(On) { }
00058 
00059     sparcasmbuf *rdbuf() const {
00060       return const_cast<sparcasmbuf*>(&sb);
00061     }
00062   };
00063 
00064   static void writePrologue (std::ostream &Out, const std::string &comment,
00065            const std::string &symName) {
00066     // Prologue:
00067     // Output a comment describing the object.
00068     Out << "!" << comment << "\n";   
00069     // Switch the current section to .rodata in the assembly output:
00070     Out << "\t.section \".rodata\"\n\t.align 8\n";  
00071     // Output a global symbol naming the object:
00072     Out << "\t.global " << symName << "\n";    
00073     Out << "\t.type " << symName << ",#object\n"; 
00074     Out << symName << ":\n"; 
00075   }
00076 
00077   static void writeEpilogue (std::ostream &Out, const std::string &symName) {
00078     // Epilogue:
00079     // Output a local symbol marking the end of the object:
00080     Out << ".end_" << symName << ":\n";    
00081     // Output size directive giving the size of the object:
00082     Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
00083   << "\n";
00084   }
00085 
00086   // SparcV9BytecodeWriter - Write bytecode out to a stream that is sparc'ified
00087   class SparcV9BytecodeWriter : public ModulePass {
00088     std::ostream &Out;
00089   public:
00090     SparcV9BytecodeWriter(std::ostream &out) : Out(out) {}
00091 
00092     const char *getPassName() const { return "Emit Bytecode to SparcV9 Assembly";}
00093     
00094     virtual bool runOnModule(Module &M) {
00095       // Write an object containing the bytecode to the SPARC assembly stream
00096       writePrologue (Out, "LLVM BYTECODE OUTPUT", "LLVMBytecode");
00097       osparcasmstream OS(Out);
00098       WriteBytecodeToFile(&M, OS);
00099       writeEpilogue (Out, "LLVMBytecode");
00100 
00101       // Write an object containing its length as an integer to the
00102       // SPARC assembly stream
00103       writePrologue (Out, "LLVM BYTECODE LENGTH", "llvm_length");
00104       Out <<"\t.word\t.end_LLVMBytecode-LLVMBytecode\n"; 
00105       writeEpilogue (Out, "llvm_length");
00106 
00107       return false;
00108     }
00109   };
00110 }  // end anonymous namespace
00111 
00112 ModulePass *llvm::createBytecodeAsmPrinterPass(std::ostream &Out) {
00113   return new SparcV9BytecodeWriter(Out);
00114 }
00115