copyleft: gplv3 added and set repo to public
[calu.git] / 3c_disasm / disasm.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 <boost/lexical_cast.hpp>
23 #include <boost/dynamic_bitset.hpp>
24 #include "disasm.h"
25
26 using namespace boost;
27
28 Iinstr* disasm::decode(std::string str)
29 {
30         /* we need 0x prefix */
31         string hex = "0x";
32         hex.append(str);
33
34         CDat val =  lexical_cast<uint32_from_hex>(hex);
35         return this->decodeNum(val);
36 }
37
38
39 Iinstr* disasm::decodeNum(CDat val)
40 {
41         dynamic_bitset<> bits(32,val), opcode(32,val), condition(9), args(32);
42
43         args = opcode;
44         args.resize(23);
45
46         opcode >>= 23;
47         condition = opcode;
48         opcode.resize(5);
49
50         condition >>= 5;
51         condition.resize(4);
52
53         //cout << "<" << hex << "> is in int  " << val << "\t is binary " << bits << " opcode?" << opcode << " condition " << condition << endl;
54         try {
55                 Iinstr* instr = decodeOpcode(opcode.to_ulong());
56                 instr->decodeCondition(condition.to_ulong());
57                 instr->loadBits(args);
58                 instr->evalInstr();
59                 return instr;
60         }
61         catch(std::string &e) {
62                 cerr << " Error: " << e << endl;
63         }
64         return NULL;
65 }
66
67 std::string disasm::decodeToString(std::string str)
68 {
69         return this->decode(str)->toString();
70 }
71
72 Iinstr* disasm::decodeOpcode(short opcode)
73 {
74         auto iter = instrs.find(opcode);
75         if(iter != instrs.end()) {
76                 Iinstr* p = (iter->second)->getNew();
77                 return p;
78         }
79         else {
80                 stringstream err;
81                 err << "opcode not found. in was " << opcode  << endl;
82                 throw err.str();
83         }
84 }