blob: 3ca8b1658236aafee61d68a3c081cf300ab4c26c [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>
Anand Shukla3ee2ea82002-07-21 09:35:01 +000013#include <sstream>
14#include <string>
15using std::ostream;
Chris Lattner9530a6f2002-02-11 22:35:46 +000016
17namespace {
18
19 // sparcasmbuf - stream buf for encoding output bytes as .byte directives for
20 // the sparc assembler.
21 //
Anand Shukla3ee2ea82002-07-21 09:35:01 +000022 class sparcasmbuf : public std::streambuf {
Chris Lattner9530a6f2002-02-11 22:35:46 +000023 std::ostream &BaseStr;
24 public:
Chris Lattner49b8a9c2002-02-24 23:02:40 +000025 typedef char char_type;
26 typedef int int_type;
27 typedef std::streampos pos_type;
28 typedef std::streamoff off_type;
Chris Lattner9530a6f2002-02-11 22:35:46 +000029
30 sparcasmbuf(std::ostream &On) : BaseStr(On) {}
31
32 virtual int_type overflow(int_type C) {
33 if (C != EOF)
34 BaseStr << "\t.byte " << C << "\n"; // Output C;
35 return C;
36 }
37 };
38
39
40 // osparcasmstream - Define an ostream implementation that uses a sparcasmbuf
41 // as the underlying streambuf to write the data to. This streambuf formats
42 // the output as .byte directives for sparc output.
43 //
44 class osparcasmstream : public ostream {
45 sparcasmbuf sb;
46 public:
Chris Lattner49b8a9c2002-02-24 23:02:40 +000047 typedef char char_type;
48 typedef int int_type;
49 typedef std::streampos pos_type;
50 typedef std::streamoff off_type;
Chris Lattner9530a6f2002-02-11 22:35:46 +000051
52 explicit osparcasmstream(ostream &On) : ostream(&sb), sb(On) { }
53
54 sparcasmbuf *rdbuf() const {
55 return const_cast<sparcasmbuf*>(&sb);
56 }
57 };
58
59 // SparcBytecodeWriter - Write bytecode out to a stream that is sparc'ified
60 class SparcBytecodeWriter : public Pass {
61 std::ostream &Out;
62 public:
63 SparcBytecodeWriter(std::ostream &out) : Out(out) {}
64
Chris Lattner96c466b2002-04-29 14:57:45 +000065 const char *getPassName() const { return "Emit Bytecode to Sparc Assembly";}
66
Chris Lattner0b12b5f2002-06-25 16:13:21 +000067 virtual bool run(Module &M) {
Chris Lattner9530a6f2002-02-11 22:35:46 +000068 // Write bytecode out to the sparc assembly stream
Anand Shukla3ee2ea82002-07-21 09:35:01 +000069
Chris Lattner9530a6f2002-02-11 22:35:46 +000070 Out << "\n\n!LLVM BYTECODE OUTPUT\n\t.section \".rodata\"\n\t.align 8\n";
71 Out << "\t.global LLVMBytecode\n\t.type LLVMBytecode,#object\n";
72 Out << "LLVMBytecode:\n";
Anand Shukla3ee2ea82002-07-21 09:35:01 +000073 //changed --anand, to get the size of bytecode
74 std::ostringstream Ostr;
75 osparcasmstream OS(Ostr);
Chris Lattner0b12b5f2002-06-25 16:13:21 +000076 WriteBytecodeToFile(&M, OS);
Chris Lattner9530a6f2002-02-11 22:35:46 +000077
Anand Shukla3ee2ea82002-07-21 09:35:01 +000078 //compute length: count number of "."
79 std::string myString=Ostr.str();
80 int llvm_len=0;
81 for(std::string::iterator si=myString.begin(), se=myString.end(); si!=se; si++)
82 if(*si == '.')
83 llvm_len++;
84
85 //now put Ostr into Out
86 //count no of
87 Out<<Ostr.str();
Chris Lattner9530a6f2002-02-11 22:35:46 +000088 Out << ".end_LLVMBytecode:\n";
89 Out << "\t.size LLVMBytecode, .end_LLVMBytecode-LLVMBytecode\n\n";
Anand Shukla3ee2ea82002-07-21 09:35:01 +000090
91 Out <<"\n\n!LLVM BYTECODE Length\n\t.section \".data\",#alloc,#write\n\t.global llvm_length\n\t.align 4\n\t.type llvm_length,#object\n\t.size llvm_length,4\nllvm_length:\n\t.word "<<llvm_len<<"\n";
Chris Lattner9530a6f2002-02-11 22:35:46 +000092 return false;
93 }
94 };
95} // end anonymous namespace
96
97Pass *UltraSparc::getEmitBytecodeToAsmPass(std::ostream &Out) {
98 return new SparcBytecodeWriter(Out);
99}