1 //===-- EmitBytecodeToAssembly.cpp - Emit bytecode to Sparc .s File --------==//
3 // This file implements the pass that writes LLVM bytecode as data to a sparc
4 // assembly file. The bytecode gets assembled into a special bytecode section
5 // of the executable for use at runtime later.
7 //===----------------------------------------------------------------------===//
9 #include "SparcInternals.h"
10 #include "llvm/Pass.h"
11 #include "llvm/Bytecode/Writer.h"
18 // sparcasmbuf - stream buf for encoding output bytes as .byte directives for
19 // the sparc assembler.
21 class sparcasmbuf : public std::streambuf {
22 std::ostream &BaseStr;
24 typedef char char_type;
26 typedef std::streampos pos_type;
27 typedef std::streamoff off_type;
29 sparcasmbuf(std::ostream &On) : BaseStr(On) {}
31 virtual int_type overflow(int_type C) {
33 BaseStr << "\t.byte " << C << "\n"; // Output C;
39 // osparcasmstream - Define an ostream implementation that uses a sparcasmbuf
40 // as the underlying streambuf to write the data to. This streambuf formats
41 // the output as .byte directives for sparc output.
43 class osparcasmstream : public std::ostream {
46 typedef char char_type;
48 typedef std::streampos pos_type;
49 typedef std::streamoff off_type;
51 explicit osparcasmstream(std::ostream &On) : std::ostream(&sb), sb(On) { }
53 sparcasmbuf *rdbuf() const {
54 return const_cast<sparcasmbuf*>(&sb);
58 static void writePrologue (std::ostream &Out, const std::string &comment,
59 const std::string &symName) {
61 // Output a comment describing the object.
62 Out << "!" << comment << "\n";
63 // Switch the current section to .rodata in the assembly output:
64 Out << "\t.section \".rodata\"\n\t.align 8\n";
65 // Output a global symbol naming the object:
66 Out << "\t.global " << symName << "\n";
67 Out << "\t.type " << symName << ",#object\n";
68 Out << symName << ":\n";
71 static void writeEpilogue (std::ostream &Out, const std::string &symName) {
73 // Output a local symbol marking the end of the object:
74 Out << ".end_" << symName << ":\n";
75 // Output size directive giving the size of the object:
76 Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
80 // SparcBytecodeWriter - Write bytecode out to a stream that is sparc'ified
81 class SparcBytecodeWriter : public Pass {
84 SparcBytecodeWriter(std::ostream &out) : Out(out) {}
86 const char *getPassName() const { return "Emit Bytecode to Sparc Assembly";}
88 virtual bool run(Module &M) {
89 // Write an object containing the bytecode to the SPARC assembly stream
90 writePrologue (Out, "LLVM BYTECODE OUTPUT", "LLVMBytecode");
91 osparcasmstream OS(Out);
92 WriteBytecodeToFile(&M, OS);
93 writeEpilogue (Out, "LLVMBytecode");
95 // Write an object containing its length as an integer to the
96 // SPARC assembly stream
97 writePrologue (Out, "LLVM BYTECODE LENGTH", "llvm_length");
98 Out <<"\t.word\t.end_LLVMBytecode-LLVMBytecode\n";
99 writeEpilogue (Out, "llvm_length");
104 } // end anonymous namespace
106 Pass *UltraSparc::getBytecodeAsmPrinterPass(std::ostream &Out) {
107 return new SparcBytecodeWriter(Out);