LLVM API Documentation
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