copyleft: gplv3 added and set repo to public
[calu.git] / 3c_disasm / dasm.cpp
1 /*   `Deep Thought', a softcore CPU implemented on a FPGA
2
3     Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4     Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5     Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6     Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7     Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
8
9     This program is free software: you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation, either version 3 of the License, or
12     (at your option) any later version.
13
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18
19     You should have received a copy of the GNU General Public License
20     along with this program.  If not, see <http://www.gnu.org/licenses/>. */
21
22 #include <iostream>
23 #include <fstream>
24 #include <boost/tokenizer.hpp>
25 #include <boost/program_options.hpp>
26 #include <boost/lexical_cast.hpp>
27 #include <string>
28 #include <map>
29 #include "disasm.h"
30
31
32 #include "CInstrFactory.hpp"
33
34 using boost::lexical_cast;
35 using boost::bad_lexical_cast;
36
37 using namespace std;
38
39 using namespace boost::program_options;
40 namespace po = boost::program_options;
41
42 std::string progName;
43
44
45 CCpu* Iinstr::m_cpu;
46 disasm* Iinstr::m_disasm;
47
48 int main(int argc, char* argv[])
49 {
50         progName = argv[0];
51         ifstream inFile;
52         try {
53                 po::options_description desc("Allowed options");
54                 desc.add_options()
55                 ("help,h","produce help message")
56                 ("file,f",value<string>(), "input file")
57                 ;
58
59                 po::positional_options_description p;
60                 p.add("file",1);
61
62                 po::variables_map vm;
63                 po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
64                 po::notify(vm);
65
66                 if(vm.count("help")) {
67                         cout << desc << endl;
68                         return EXIT_FAILURE;
69                 }
70
71                 if(vm.count("file")) {
72 #ifdef DEBUG 
73                         cout << "going to open file " << vm["file"].as<string>() << endl;
74 #endif
75                         inFile.open(vm["file"].as<string>(), ios::in);
76                         if(!inFile) {
77                                 cerr << "Error opening file " << vm["file"].as<string>() << endl;
78                                 return EXIT_FAILURE;
79                         }
80                 }
81                 else {
82                         cout << "not input file given!" << endl << endl;
83                         cout << desc << endl;
84                         return EXIT_FAILURE;
85                 }
86         }
87         catch(std::exception& ex) {
88                 cout << ex.what() << endl;
89         }
90
91
92         string dir = "./instr/";
93
94         map<short, Iinstr*> instr;
95
96         CInstrFactory instrFab;
97         try {
98                 instrFab.loadLibsIntoMap(instr, dir);
99         }
100         catch(std::bad_alloc& e) {
101                 cerr << progName << ": bad_alloc caught " << e.what() << endl;
102                 exit(EXIT_FAILURE); 
103         }
104
105
106
107
108         std::string str = "";
109         boost::char_separator<char> sep(";", "", boost::keep_empty_tokens);
110         boost::tokenizer<boost::char_separator<char> > tokens(str, sep);
111         disasm disasm(instr);
112         while(getline(inFile, str)) {
113                 int count = 0;
114                 tokens.assign(str);
115                 stringstream out;
116                 int type = 0;
117                 for(auto tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
118                         if(tok_iter == tokens.begin()) {
119                                 try {
120                                         type = lexical_cast<int>(*tok_iter);
121                                         count++;
122                                         continue;
123                                 }
124                                 catch(bad_lexical_cast &) {
125                                         break;
126                                 }
127                                 cout << endl;
128                         }
129                         switch(type) {
130                                 case 2:
131                                         if(count == 1) {
132                                                 cout << "; ";
133                                         }
134                                         cout << *tok_iter;
135                                         break;
136                                 case 3:
137                                         if((*tok_iter).size() > 0) {
138                                                 if(count > 1) {
139                                                         cout << endl;
140                                                 }
141                                                 cout << *tok_iter << ":";
142                                         }
143                                         break;
144                                 case 1:
145                                         if(count == 1) {
146                                                 out << "[0x" << *tok_iter << "]: ";
147                                         }
148                                         else if(count == 2) {
149                                                 out << disasm.decodeToString(*tok_iter);
150                                         }
151                                         else if(count == 3) {
152                                                 //code saved in hex-file
153                                                 //cout << *tok_iter ;
154                                         }
155                                         else if(count == 4) {
156                                                 /* label */
157                                                 if((*tok_iter).size() > 0) {
158                                                         cout << *tok_iter << ":" << endl;
159                                                 }
160                                                 cout << out.str();
161                                         }
162                                         else if(count == 5) {
163                                                 if((*tok_iter).size() > 0) {
164                                                         cout << " ;";
165                                                 }
166                                         }
167
168                                         if(count >= 5) {
169                                                 cout << *tok_iter;
170                                         }
171                                         break;
172                                 default:
173                                         cerr << "i was to lazy to implement the other format types for now" << endl;
174                         }
175                         count++;
176                 }
177                 if(type == 1 && count <= 4) {
178                         cout << out.str();
179                 }
180                 cout << endl;
181         }
182         inFile.close();
183
184         cout << endl;
185         return EXIT_SUCCESS;
186 }