disasm: alpha version
[calu.git] / 3c_disasm / Iinstr.hpp
diff --git a/3c_disasm/Iinstr.hpp b/3c_disasm/Iinstr.hpp
new file mode 100644 (file)
index 0000000..95b5229
--- /dev/null
@@ -0,0 +1,188 @@
+#include <string>
+#include <boost/dynamic_bitset.hpp>
+#include <iostream>
+#include <sstream>
+
+#ifndef __IINSTR_I_
+#define __IINSTR_I_
+
+/* concept from https://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f */
+#define to_HEX__(x) 0x##x##LU
+
+#define to_B5__(x) ((x & 0x0000FUL) ?  1 : 0) \
+                  +((x & 0x000F0UL) ?  2 : 0) \
+                  +((x & 0x00F00UL) ?  4 : 0) \
+                  +((x & 0x0F000UL) ?  8 : 0) \
+                  +((x & 0xF0000UL) ? 16 : 0) 
+
+#define B5(x) ((unsigned char)to_B5__(to_HEX__(x)))
+
+using namespace std;
+using namespace boost;
+
+enum CONDITIONS {
+       NOT_EQUAL = 0,
+       EQUAL = 1,
+       NOT_OVERFLOW =2,
+       OVER_FLOW = 3,
+       NOT_CARRY = 4,
+       CARRY = 5,
+       NOT_SIGNED = 6,
+       SIGNED = 7,
+       ABOVE = 8,
+       BELOW_EQ = 9,
+       GREATER_EQ = 10,
+       LESS = 11,
+       GREATER = 12,
+       LESS_EQ = 13,
+       ALWAYS = 14,
+       NEVER = 15
+};
+
+class Iinstr {
+       protected:
+               short opcode;
+               std::string name;
+               short m_ra, m_rb, m_rd;
+               bool m_c, m_d, m_hl, m_f, m_s;
+               int m_imm;
+               short m_cond;
+               boost::dynamic_bitset<> argbits;
+               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) {}
+
+               int generate16ImmFill(const int value) { 
+                       int i = value;
+                       if(m_hl == true && m_f == true) {
+                               i <<= 16;
+                               i |= 0x0000FFFF;
+                       }
+                       else if(m_hl == true && m_f == false) {
+                               i <<= 16;
+                               i &= 0xFFFF0000;
+                       }
+                       else if(m_hl == false && m_f == true) {
+                               i |= 0xFFFF0000;
+                       }
+                       else {
+                               i &= 0x0000FFFF;
+                       }
+
+                       return i; 
+               }
+
+               int generate16ImmSign(const int value) { 
+                       int i = value;
+                       if(m_hl == true) {
+                               i <<= 16;
+                       }
+                       else if(m_s == true && (i & 0x8000) != 0) {
+                                       i |= 0xFFFF0000;
+                       }
+
+                       return i; 
+               }
+
+               int generate12ImmSign(const int value) { 
+                       int i = value;
+                       if(m_s == true && (i & 0x0800) != 0) {
+                                       i |= 0xFFFFF000;
+                       }
+
+                       return i; 
+               }
+
+               int generate15ImmSign(const int value) { 
+                       int i = value;
+                       if(m_s == true && (i & 0x4000) != 0) {
+                                       i |= 0xFFFF8000;
+                       }
+
+                       return i; 
+               }
+
+
+
+               int getRegister(boost::dynamic_bitset<> bits) {
+                       bits.resize(4);
+                       return bits.to_ulong();
+               }
+
+       public:
+               virtual ~Iinstr() {}
+               virtual short getOpcode() { return this->opcode; }
+               virtual std::string getName() { return this->name; }
+               virtual void loadBits(boost::dynamic_bitset<> bits) { argbits = bits; }
+               virtual void evalInstr() = 0;
+               virtual void execInstr() = 0;
+               virtual std::string toString() = 0;
+
+               void decodeCondition(short condition) {
+                       if(condition >= 0 && condition <= 15) {
+                               m_cond = condition;
+                       }
+                       else {
+                               throw std::string("Invalid Condition!");
+                       }
+               }
+
+       protected:
+               std::string getConditionFlag()
+               {
+                       stringstream cond;
+                       switch(m_cond) {
+                               case NOT_EQUAL:
+                                       cond << "{nq,nz}";
+                                       break;
+                               case EQUAL:
+                                       cond << "{eq,zs}";
+                                       break;
+                               case NOT_OVERFLOW:
+                                       cond << "no";
+                                       break;
+                               case OVER_FLOW:
+                                       cond << "ov";
+                                       break;
+                               case NOT_CARRY:
+                                       cond << "{nc,ae}";
+                                       break;
+                               case CARRY:
+                                       cond << "{cs,bl}";
+                                       break;
+                               case NOT_SIGNED:
+                                       cond << "{ns,nn}";
+                                       break;
+                               case SIGNED:
+                                       cond << "{ss,ns}";
+                                       break;
+                               case ABOVE:
+                                       cond << "ab";
+                                       break;
+                               case BELOW_EQ:
+                                       cond << "be";
+                                       break;
+                               case GREATER_EQ:
+                                       cond << "ge";
+                                       break;
+                               case LESS:
+                                       cond << "lt";
+                                       break;
+                               case GREATER:
+                                       cond << "gt";
+                                       break;
+                               case LESS_EQ:
+                                       cond << "le";
+                                       break;
+                               case ALWAYS:
+                                       cond << "";
+                                       break;
+                               case NEVER:
+                                       cond << "nv";
+                                       break;
+                               default:
+                                       cerr << "What did you do? more than 16 values in 5 bits?!" << endl;
+                       }
+
+                       return cond.str();
+               }
+};
+#endif