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