disasm: changed interface / fixed Makefile
[calu.git] / 3c_disasm / Iinstr.hpp
1 #include <string>
2 #include <boost/dynamic_bitset.hpp>
3 #include <iostream>
4 #include <sstream>
5
6 #ifndef __IINSTR_I_
7 #define __IINSTR_I_
8
9 /* concept from https://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f */
10 #define to_HEX__(x) 0x##x##LU
11
12 #define to_B5__(x) ((x & 0x0000FUL) ?  1 : 0) \
13                   +((x & 0x000F0UL) ?  2 : 0) \
14                   +((x & 0x00F00UL) ?  4 : 0) \
15                   +((x & 0x0F000UL) ?  8 : 0) \
16                   +((x & 0xF0000UL) ? 16 : 0) 
17
18 #define B5(x) ((unsigned char)to_B5__(to_HEX__(x)))
19
20 using namespace std;
21 using namespace boost;
22
23 enum CONDITIONS {
24         NOT_EQUAL = 0,
25         EQUAL = 1,
26         NOT_OVERFLOW =2,
27         OVER_FLOW = 3,
28         NOT_CARRY = 4,
29         CARRY = 5,
30         NOT_SIGNED = 6,
31         SIGNED = 7,
32         ABOVE = 8,
33         BELOW_EQ = 9,
34         GREATER_EQ = 10,
35         LESS = 11,
36         GREATER = 12,
37         LESS_EQ = 13,
38         ALWAYS = 14,
39         NEVER = 15
40 };
41
42 class Iinstr {
43         protected:
44                 short opcode;
45                 std::string name;
46                 short m_ra, m_rb, m_rd;
47                 bool m_c, m_d, m_hl, m_f, m_s;
48                 int m_imm;
49                 short m_cond;
50                 boost::dynamic_bitset<> argbits;
51                 Iinstr() : opcode(0), name(""), m_ra(0), m_rb(0), m_rd(0), m_c(0), m_d(0), m_hl(0), m_f(0), m_s(0), m_imm(0), m_cond(ALWAYS), argbits(32) {}
52
53                 int generate16ImmFill(const int value) const {
54                         int i = value;
55                         if(m_hl == true && m_f == true) {
56                                 i <<= 16;
57                                 i |= 0x0000FFFF;
58                         }
59                         else if(m_hl == true && m_f == false) {
60                                 i <<= 16;
61                                 i &= 0xFFFF0000;
62                         }
63                         else if(m_hl == false && m_f == true) {
64                                 i |= 0xFFFF0000;
65                         }
66                         else {
67                                 i &= 0x0000FFFF;
68                         }
69
70                         return i; 
71                 }
72
73                 int generate16ImmSign(const int value) const {
74                         int i = value;
75                         if(m_hl == true) {
76                                 i <<= 16;
77                         }
78                         else if(m_s == true && (i & 0x8000) != 0) {
79                                         i |= 0xFFFF0000;
80                         }
81
82                         return i; 
83                 }
84
85                 int generate12ImmSign(const int value) const {
86                         int i = value;
87                         if(m_s == true && (i & 0x0800) != 0) {
88                                         i |= 0xFFFFF000;
89                         }
90
91                         return i; 
92                 }
93
94                 int generate15ImmSign(const int value) const {
95                         int i = value;
96                         if(m_s == true && (i & 0x4000) != 0) {
97                                         i |= 0xFFFF8000;
98                         }
99
100                         return i; 
101                 }
102
103
104
105                 int getRegister(boost::dynamic_bitset<> bits) {
106                         bits.resize(4);
107                         return bits.to_ulong();
108                 }
109
110         public:
111                 virtual ~Iinstr() {}
112                 virtual short getOpcode() { return this->opcode; }
113                 virtual std::string getName() { return this->name; }
114                 virtual void loadBits(boost::dynamic_bitset<> bits) { argbits = bits; }
115                 virtual void evalInstr() = 0;
116                 virtual void execInstr() = 0;
117                 virtual std::string toString() = 0;
118
119                 void decodeCondition(short condition) {
120                         if(condition >= 0 && condition <= 15) {
121                                 m_cond = condition;
122                         }
123                         else {
124                                 throw std::string("Invalid Condition!");
125                         }
126                 }
127
128         protected:
129                 std::string getConditionFlag()
130                 {
131                         stringstream cond;
132                         switch(m_cond) {
133                                 case NOT_EQUAL:
134                                         cond << "{nq,nz}";
135                                         break;
136                                 case EQUAL:
137                                         cond << "{eq,zs}";
138                                         break;
139                                 case NOT_OVERFLOW:
140                                         cond << "no";
141                                         break;
142                                 case OVER_FLOW:
143                                         cond << "ov";
144                                         break;
145                                 case NOT_CARRY:
146                                         cond << "{nc,ae}";
147                                         break;
148                                 case CARRY:
149                                         cond << "{cs,bl}";
150                                         break;
151                                 case NOT_SIGNED:
152                                         cond << "{ns,nn}";
153                                         break;
154                                 case SIGNED:
155                                         cond << "{ss,ns}";
156                                         break;
157                                 case ABOVE:
158                                         cond << "ab";
159                                         break;
160                                 case BELOW_EQ:
161                                         cond << "be";
162                                         break;
163                                 case GREATER_EQ:
164                                         cond << "ge";
165                                         break;
166                                 case LESS:
167                                         cond << "lt";
168                                         break;
169                                 case GREATER:
170                                         cond << "gt";
171                                         break;
172                                 case LESS_EQ:
173                                         cond << "le";
174                                         break;
175                                 case ALWAYS:
176                                         cond << "";
177                                         break;
178                                 case NEVER:
179                                         cond << "nv";
180                                         break;
181                                 default:
182                                         cerr << "What did you do? more than 16 values in 5 bits?!" << endl;
183                         }
184
185                         return cond.str();
186                 }
187 };
188 #endif