blob: 26332ca30109e6d97a79506b5f7790a217a75bbe [file] [log] [blame]
Brian Gaeke3ca4fcc2004-04-25 07:04:49 +00001//===-- EmitBytecodeToAssembly.cpp - Emit bytecode to SparcV9 .s File ------==//
John Criswellb576c942003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattner9530a6f2002-02-11 22:35:46 +00009//
10// This file implements the pass that writes LLVM bytecode as data to a sparc
11// assembly file. The bytecode gets assembled into a special bytecode section
12// of the executable for use at runtime later.
13//
14//===----------------------------------------------------------------------===//
15
Brian Gaekee3d68072004-02-25 18:44:15 +000016#include "SparcV9Internals.h"
Chris Lattnerd50b6712002-04-28 20:40:59 +000017#include "llvm/Pass.h"
Chris Lattner9530a6f2002-02-11 22:35:46 +000018#include "llvm/Bytecode/Writer.h"
Vikram S. Adve9ee9d712002-03-03 20:46:32 +000019#include <iostream>
Chris Lattnerb12914b2004-09-20 04:48:05 +000020using namespace llvm;
Chris Lattner9530a6f2002-02-11 22:35:46 +000021
22namespace {
23
24 // sparcasmbuf - stream buf for encoding output bytes as .byte directives for
25 // the sparc assembler.
26 //
Anand Shukla3ee2ea82002-07-21 09:35:01 +000027 class sparcasmbuf : public std::streambuf {
Chris Lattner9530a6f2002-02-11 22:35:46 +000028 std::ostream &BaseStr;
29 public:
Chris Lattner49b8a9c2002-02-24 23:02:40 +000030 typedef char char_type;
31 typedef int int_type;
32 typedef std::streampos pos_type;
33 typedef std::streamoff off_type;
Chris Lattner9530a6f2002-02-11 22:35:46 +000034
35 sparcasmbuf(std::ostream &On) : BaseStr(On) {}
36
37 virtual int_type overflow(int_type C) {
38 if (C != EOF)
39 BaseStr << "\t.byte " << C << "\n"; // Output C;
40 return C;
41 }
42 };
43
44
45 // osparcasmstream - Define an ostream implementation that uses a sparcasmbuf
46 // as the underlying streambuf to write the data to. This streambuf formats
47 // the output as .byte directives for sparc output.
48 //
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000049 class osparcasmstream : public std::ostream {
Chris Lattner9530a6f2002-02-11 22:35:46 +000050 sparcasmbuf sb;
51 public:
Chris Lattner49b8a9c2002-02-24 23:02:40 +000052 typedef char char_type;
53 typedef int int_type;
54 typedef std::streampos pos_type;
55 typedef std::streamoff off_type;
Chris Lattner9530a6f2002-02-11 22:35:46 +000056
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000057 explicit osparcasmstream(std::ostream &On) : std::ostream(&sb), sb(On) { }
Chris Lattner9530a6f2002-02-11 22:35:46 +000058
59 sparcasmbuf *rdbuf() const {
60 return const_cast<sparcasmbuf*>(&sb);
61 }
62 };
63
Brian Gaekebb7cd972003-09-18 17:37:14 +000064 static void writePrologue (std::ostream &Out, const std::string &comment,
65 const std::string &symName) {
66 // Prologue:
67 // Output a comment describing the object.
68 Out << "!" << comment << "\n";
69 // Switch the current section to .rodata in the assembly output:
70 Out << "\t.section \".rodata\"\n\t.align 8\n";
71 // Output a global symbol naming the object:
72 Out << "\t.global " << symName << "\n";
73 Out << "\t.type " << symName << ",#object\n";
74 Out << symName << ":\n";
75 }
76
77 static void writeEpilogue (std::ostream &Out, const std::string &symName) {
78 // Epilogue:
79 // Output a local symbol marking the end of the object:
80 Out << ".end_" << symName << ":\n";
81 // Output size directive giving the size of the object:
82 Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
83 << "\n";
84 }
85
Brian Gaekee3d68072004-02-25 18:44:15 +000086 // SparcV9BytecodeWriter - Write bytecode out to a stream that is sparc'ified
Chris Lattnerb12914b2004-09-20 04:48:05 +000087 class SparcV9BytecodeWriter : public ModulePass {
Chris Lattner9530a6f2002-02-11 22:35:46 +000088 std::ostream &Out;
89 public:
Brian Gaekee3d68072004-02-25 18:44:15 +000090 SparcV9BytecodeWriter(std::ostream &out) : Out(out) {}
Chris Lattner9530a6f2002-02-11 22:35:46 +000091
Brian Gaekee3d68072004-02-25 18:44:15 +000092 const char *getPassName() const { return "Emit Bytecode to SparcV9 Assembly";}
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000093
Chris Lattnerb12914b2004-09-20 04:48:05 +000094 virtual bool runOnModule(Module &M) {
Brian Gaekebb7cd972003-09-18 17:37:14 +000095 // Write an object containing the bytecode to the SPARC assembly stream
96 writePrologue (Out, "LLVM BYTECODE OUTPUT", "LLVMBytecode");
Mehwish Nagda0009c2e2002-07-25 17:22:48 +000097 osparcasmstream OS(Out);
Chris Lattner0b12b5f2002-06-25 16:13:21 +000098 WriteBytecodeToFile(&M, OS);
Brian Gaekebb7cd972003-09-18 17:37:14 +000099 writeEpilogue (Out, "LLVMBytecode");
Chris Lattner9530a6f2002-02-11 22:35:46 +0000100
Brian Gaekebb7cd972003-09-18 17:37:14 +0000101 // Write an object containing its length as an integer to the
102 // SPARC assembly stream
103 writePrologue (Out, "LLVM BYTECODE LENGTH", "llvm_length");
Mehwish Nagda0009c2e2002-07-25 17:22:48 +0000104 Out <<"\t.word\t.end_LLVMBytecode-LLVMBytecode\n";
Brian Gaekebb7cd972003-09-18 17:37:14 +0000105 writeEpilogue (Out, "llvm_length");
106
Chris Lattner9530a6f2002-02-11 22:35:46 +0000107 return false;
108 }
109 };
110} // end anonymous namespace
111
Chris Lattnerb12914b2004-09-20 04:48:05 +0000112ModulePass *llvm::createBytecodeAsmPrinterPass(std::ostream &Out) {
Brian Gaekee3d68072004-02-25 18:44:15 +0000113 return new SparcV9BytecodeWriter(Out);
Chris Lattner9530a6f2002-02-11 22:35:46 +0000114}
Brian Gaeked0fde302003-11-11 22:41:34 +0000115