0cb75facc2420342e0d02e9f8d197aceb7da389f
[calu.git] / 3c_disasm / disasm.cpp
1 #include <boost/lexical_cast.hpp>
2 #include <boost/dynamic_bitset.hpp>
3 #include "disasm.h"
4
5 using namespace boost;
6
7 Iinstr* disasm::decode(std::string str)
8 {
9         /* we need 0x prefix */
10         string hex = "0x";
11         hex.append(str);
12
13         CDat val =  lexical_cast<uint32_from_hex>(hex);
14         return this->decodeNum(val);
15 }
16
17
18 Iinstr* disasm::decodeNum(CDat val)
19 {
20         dynamic_bitset<> bits(32,val), opcode(32,val), condition(9), args(32);
21
22         args = opcode;
23         args.resize(23);
24
25         opcode >>= 23;
26         condition = opcode;
27         opcode.resize(5);
28
29         condition >>= 5;
30         condition.resize(4);
31
32         //cout << "<" << hex << "> is in int  " << val << "\t is binary " << bits << " opcode?" << opcode << " condition " << condition << endl;
33         try {
34                 Iinstr* instr = decodeOpcode(opcode.to_ulong());
35                 instr->decodeCondition(condition.to_ulong());
36                 instr->loadBits(args);
37                 instr->evalInstr();
38                 return instr;
39         }
40         catch(std::string &e) {
41                 cerr << " Error: " << e << endl;
42         }
43         return NULL;
44 }
45
46 std::string disasm::decodeToString(std::string str)
47 {
48         return this->decode(str)->toString();
49 }
50
51 Iinstr* disasm::decodeOpcode(short opcode)
52 {
53         auto iter = instrs.find(opcode);
54         if(iter != instrs.end()) {
55                 Iinstr* p = (iter->second)->getNew();
56                 return p;
57         }
58         else {
59                 stringstream err;
60                 err << "opcode not found. in was " << opcode  << endl;
61                 throw err.str();
62         }
63 }