blob: 379639c0c559abcda5367e0f15fa47fa38b5cd02 [file] [log] [blame]
Chris Lattner9530a6f2002-02-11 22:35:46 +00001//===-- EmitBytecodeToAssembly.cpp - Emit bytecode to Sparc .s File --------==//
2//
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.
6//
7//===----------------------------------------------------------------------===//
8
9#include "SparcInternals.h"
Chris Lattnerd50b6712002-04-28 20:40:59 +000010#include "llvm/Pass.h"
Chris Lattner9530a6f2002-02-11 22:35:46 +000011#include "llvm/Bytecode/Writer.h"
Vikram S. Adve9ee9d712002-03-03 20:46:32 +000012#include <iostream>
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000013
Anand Shukla3ee2ea82002-07-21 09:35:01 +000014using std::ostream;
Chris Lattner9530a6f2002-02-11 22:35:46 +000015
16namespace {
17
18 // sparcasmbuf - stream buf for encoding output bytes as .byte directives for
19 // the sparc assembler.
20 //
Anand Shukla3ee2ea82002-07-21 09:35:01 +000021 class sparcasmbuf : public std::streambuf {
Chris Lattner9530a6f2002-02-11 22:35:46 +000022 std::ostream &BaseStr;
23 public:
Chris Lattner49b8a9c2002-02-24 23:02:40 +000024 typedef char char_type;
25 typedef int int_type;
26 typedef std::streampos pos_type;
27 typedef std::streamoff off_type;
Chris Lattner9530a6f2002-02-11 22:35:46 +000028
29 sparcasmbuf(std::ostream &On) : BaseStr(On) {}
30
31 virtual int_type overflow(int_type C) {
32 if (C != EOF)
33 BaseStr << "\t.byte " << C << "\n"; // Output C;
34 return C;
35 }
36 };
37
38
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.
42 //
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000043 class osparcasmstream : public std::ostream {
Chris Lattner9530a6f2002-02-11 22:35:46 +000044 sparcasmbuf sb;
45 public:
Chris Lattner49b8a9c2002-02-24 23:02:40 +000046 typedef char char_type;
47 typedef int int_type;
48 typedef std::streampos pos_type;
49 typedef std::streamoff off_type;
Chris Lattner9530a6f2002-02-11 22:35:46 +000050
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000051 explicit osparcasmstream(std::ostream &On) : std::ostream(&sb), sb(On) { }
Chris Lattner9530a6f2002-02-11 22:35:46 +000052
53 sparcasmbuf *rdbuf() const {
54 return const_cast<sparcasmbuf*>(&sb);
55 }
56 };
57
Brian Gaekebb7cd972003-09-18 17:37:14 +000058 static void writePrologue (std::ostream &Out, const std::string &comment,
59 const std::string &symName) {
60 // Prologue:
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";
69 }
70
71 static void writeEpilogue (std::ostream &Out, const std::string &symName) {
72 // Epilogue:
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
77 << "\n";
78 }
79
Chris Lattner9530a6f2002-02-11 22:35:46 +000080 // SparcBytecodeWriter - Write bytecode out to a stream that is sparc'ified
81 class SparcBytecodeWriter : public Pass {
82 std::ostream &Out;
83 public:
84 SparcBytecodeWriter(std::ostream &out) : Out(out) {}
85
Chris Lattner96c466b2002-04-29 14:57:45 +000086 const char *getPassName() const { return "Emit Bytecode to Sparc Assembly";}
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000087
Chris Lattner0b12b5f2002-06-25 16:13:21 +000088 virtual bool run(Module &M) {
Brian Gaekebb7cd972003-09-18 17:37:14 +000089 // Write an object containing the bytecode to the SPARC assembly stream
90 writePrologue (Out, "LLVM BYTECODE OUTPUT", "LLVMBytecode");
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000091 osparcasmstream OS(Out);
Chris Lattner0b12b5f2002-06-25 16:13:21 +000092 WriteBytecodeToFile(&M, OS);
Brian Gaekebb7cd972003-09-18 17:37:14 +000093 writeEpilogue (Out, "LLVMBytecode");
Chris Lattner9530a6f2002-02-11 22:35:46 +000094
Brian Gaekebb7cd972003-09-18 17:37:14 +000095 // Write an object containing its length as an integer to the
96 // SPARC assembly stream
97 writePrologue (Out, "LLVM BYTECODE LENGTH", "llvm_length");
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000098 Out <<"\t.word\t.end_LLVMBytecode-LLVMBytecode\n";
Brian Gaekebb7cd972003-09-18 17:37:14 +000099 writeEpilogue (Out, "llvm_length");
100
Chris Lattner9530a6f2002-02-11 22:35:46 +0000101 return false;
102 }
103 };
104} // end anonymous namespace
105
Brian Gaekebb7cd972003-09-18 17:37:14 +0000106Pass *UltraSparc::getBytecodeAsmPrinterPass(std::ostream &Out) {
Chris Lattner9530a6f2002-02-11 22:35:46 +0000107 return new SparcBytecodeWriter(Out);
108}