disasm: alpha version
authorMartin Perner <martin@perner.cc>
Thu, 28 Oct 2010 19:06:50 +0000 (21:06 +0200)
committerMartin Perner <martin@perner.cc>
Fri, 29 Oct 2010 13:24:53 +0000 (15:24 +0200)
really basic, but runs on sample file

16 files changed:
3_asmsim/sum.dthex
3c_disasm/CInstrFactory.cpp [new file with mode: 0644]
3c_disasm/CInstrFactory.hpp [new file with mode: 0644]
3c_disasm/Iinstr.hpp [new file with mode: 0644]
3c_disasm/Makefile [new file with mode: 0644]
3c_disasm/Makefile.flags [new file with mode: 0644]
3c_disasm/dasm.cpp [new file with mode: 0644]
3c_disasm/disasm.cpp [new file with mode: 0644]
3c_disasm/disasm.h [new file with mode: 0644]
3c_disasm/instr/Makefile [new file with mode: 0644]
3c_disasm/instr/add.cpp [new file with mode: 0644]
3c_disasm/instr/addi.cpp [new file with mode: 0644]
3c_disasm/instr/branch.cpp [new file with mode: 0644]
3c_disasm/instr/ldi.cpp [new file with mode: 0644]
3c_disasm/instr/ldw.cpp [new file with mode: 0644]
3c_disasm/instr/subi.cpp [new file with mode: 0644]

index 31ad13502f65c531e1b9921956f9f3b3bf506f6e..0ccc6a342640d833e82f50171a56f745bfc517e6 100644 (file)
@@ -11,8 +11,8 @@
 2;load arr data
 1;0000000C;E7210000;ldw r4, 0(r2);;
 2;sum += arr[i];
-1;00000010;E0012000;add r0, r0, r4;;
+1;00000010;E0002000;add r0, r0, r4;;
 1;00000014;E1110020;addi r2,r2, 4;;
-1;00000018;E1998020;subi r3,r3, 1;;
+1;00000018;E1998008;subi r3,r3, 1;;
 1;0000001C;0B7FF801;branchnz+ loop;;
 1;00000020;EB000008;ret;;
diff --git a/3c_disasm/CInstrFactory.cpp b/3c_disasm/CInstrFactory.cpp
new file mode 100644 (file)
index 0000000..b3aed27
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Name:     CInstrFactory
+ * Author:   Martin Perner, 0725782, 535
+ * E-Mail:   e0725782@student.tuwien.ac.at
+ * Purpose:  Factory for creating Instruction from shared libraries
+ * Date:     29.04.2009
+ */
+
+#include "CInstrFactory.hpp"
+
+using namespace std;
+
+/**
+ * Name:    loadFromLib
+ * Purpose: loads a command from the given library file
+
+ * Parameter: std::string lib  location of the library file
+
+ * Preconditions:  lib references to a valid library
+ */
+Iinstr* CInstrFactory::loadFromLib(string lib)
+{
+       Iinstr* (*create_instruction)();
+
+       // load a Instruction from library
+       void* instruction = dlopen(lib.c_str(), RTLD_LAZY);
+       if (!instruction) {
+               cerr << "Cannot load library: " << dlerror() << endl;
+               exit(EXIT_FAILURE);
+       }
+
+       // load the symbols
+       void* create = dlsym(instruction, "create_instruction");
+       void* destroy = dlsym(instruction, "destroy_instruction");
+
+       if (!create || !destroy) {
+               cerr << "Cannot load symbols: " << dlerror() << endl;
+               dlclose(instruction);
+               exit(EXIT_FAILURE);
+       }
+
+       memcpy(&create_instruction, &create, sizeof(create)); 
+
+       Iinstr* instructionPointer = create_instruction();
+
+       m_libStore.insert(make_pair(instruction, instructionPointer));
+
+       return instructionPointer;
+}
+
+/**
+ * Name:    getNextInstruction
+ * Purpose: returns a pointer to a command
+
+ * Returns: Pointer to the loaded command
+
+ * Throw:  string
+ * Preconditions:  a command is left to load
+ */
+Iinstr* CInstrFactory::getNextInstr()
+{
+       if(m_files.size() >= 1) {
+               Iinstr* instruction;
+               instruction = loadFromLib(m_files[0]);
+               m_files.erase(m_files.begin());
+               return instruction;
+       }
+       else {
+               throw string("No more instruction left!");
+       }
+}
+
+
+/**
+ * Name:    searchLibsInDir
+ * Purpose: finds librarys in the given directory
+
+ * Returns: number of found librarays
+
+ * Parameters: std::string dir  Directory where the libraries are located
+ * Throw:  string
+ * Postconditions: all files with a trailing '.so' are ready to be used
+ */
+size_t CInstrFactory::searchLibsInDir(string dir)
+{
+       DIR *dp;
+
+       if((dp  = opendir(dir.c_str())) == NULL) {
+               stringstream errmsg;
+               errmsg << "Error(" << errno << ") opening " << dir << endl;
+               throw errmsg.str();
+       }
+       struct dirent *dirp;
+       while ((dirp = readdir(dp)) != NULL) {
+               string file = dirp->d_name;
+               if(file.size() >= 3) {
+                       file = file.substr(file.size()-3);
+                       std::transform(file.begin(), file.end(), file.begin(), ::tolower);
+                       if(file == ".so") {
+                               m_files.push_back(dir+"/"+string(dirp->d_name));
+                       }
+               }
+       }
+       closedir(dp);
+       return m_files.size();
+}
+
+/**
+ * Name:    getNumFiles
+ * Purpose: returns the number of librarys left
+
+ * Returns: size_t number of files left
+ */
+size_t CInstrFactory::getNumFiles()
+{
+       return m_files.size();
+}
+
+/**
+ * Name:    ~CInstrFactory
+ * Purpose: Destructor of the Object
+ */
+CInstrFactory::~CInstrFactory()
+{
+       void (*destroy_instruction)(Iinstr*);
+
+       while(!m_libStore.empty()) {
+               void* destroy = dlsym(m_libStore.begin()->first, "destroy_instruction");
+               memcpy(&destroy_instruction, &destroy, sizeof(destroy)); 
+               destroy_instruction(m_libStore.begin()->second);
+               dlclose(m_libStore.begin()->first);
+               m_libStore.erase(m_libStore.begin());
+       }
+}
diff --git a/3c_disasm/CInstrFactory.hpp b/3c_disasm/CInstrFactory.hpp
new file mode 100644 (file)
index 0000000..7a1c342
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Name:     CInstructionFactory
+ * Author:   Martin Perner, 0725782, 535
+ * E-Mail:   e0725782@student.tuwien.ac.at
+ * Purpose:  Factory for creating commands from shared libraries
+ * Date:     29.04.2009
+ */
+
+#ifndef __CINSTRUCTIONFACTORY_H__
+#define __CINSTRUCTIONFACTORY_H__
+
+#include "Iinstr.hpp"
+
+#include <string.h>
+
+#include <iostream>
+#include <sstream>
+#include <map>
+#include <vector>
+#include <algorithm>
+
+#include <dlfcn.h>
+#include <errno.h>
+
+#include <dirent.h>
+
+/**
+ * Name:    CInstructionFactory
+ * Purpose: Factory for creating commands from shared libraries
+ */
+class CInstrFactory {
+private:
+       std::map<void*, Iinstr*> m_libStore;
+       std::vector<std::string> m_files;
+
+       Iinstr* loadFromLib(std::string lib);
+public:
+       Iinstr* getNextInstr();
+       size_t getNumFiles();
+       size_t searchLibsInDir(std::string dir);
+       CInstrFactory() : m_libStore(), m_files() {};
+       ~CInstrFactory();
+};
+
+#endif
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
diff --git a/3c_disasm/Makefile b/3c_disasm/Makefile
new file mode 100644 (file)
index 0000000..35b6ff5
--- /dev/null
@@ -0,0 +1,34 @@
+-include Makefile.flags
+
+sources = disasm.cpp dasm.cpp CInstrFactory.cpp
+
+PROG=dasm
+
+.PHONY:all
+all: libs $(PROG)
+
+$(PROG): $(sources:.cpp=.o)
+       $(CC) $(CPPFLAGS) $(CPPPROGOPT) -o $(PROG) $(sources:.cpp=.o)
+
+-include $(sources:.cpp=.d)
+.PHONY: libs
+libs:   
+       $(MAKE) -C instr all
+
+$(sources):
+       $(CC) $(CPPFLAGS) -c  -o ${@:.cpp=.o} ${@}
+
+.PHONY:clean
+clean:  
+       rm -rf $(PROG) $(sources:.cpp=.o) $(sources:.cpp=.d)
+       $(MAKE) -C instr clean
+
+.PHONY: run
+run: $(PROG)
+       ./$(PROG) sum.dthex
+
+%.d: %.cpp
+       @set -e; rm -f $@; \
+       $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
+       sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+       rm -f $@.$$$$
diff --git a/3c_disasm/Makefile.flags b/3c_disasm/Makefile.flags
new file mode 100644 (file)
index 0000000..1284653
--- /dev/null
@@ -0,0 +1,6 @@
+CC := ccache g++
+
+CPPFLAGS = -g3 -O2 -std=c++0x -Wnon-virtual-dtor -Weffc++ -pedantic -Werror -Wall -Wextra -W -Wshadow -fno-common -pedantic-errors -Wpointer-arith -Wcast-qual -Wcast-align -Woverloaded-virtual -Wswitch-default -Wempty-body -Wlogical-op
+
+CPPPROGOPT=-rdynamic -ldl -lboost_program_options
+CPPLIBOPT=-shared
diff --git a/3c_disasm/dasm.cpp b/3c_disasm/dasm.cpp
new file mode 100644 (file)
index 0000000..08796f1
--- /dev/null
@@ -0,0 +1,171 @@
+#include <iostream>
+#include <fstream>
+#include <boost/tokenizer.hpp>
+#include <boost/program_options.hpp>
+#include <boost/lexical_cast.hpp>
+#include <string>
+#include <map>
+#include "disasm.h"
+
+#include "CInstrFactory.hpp"
+
+using boost::lexical_cast;
+using boost::bad_lexical_cast;
+
+using namespace std;
+
+using namespace boost::program_options;
+namespace po = boost::program_options;
+
+std::string progName;
+
+int main(int argc, char* argv[])
+{
+       progName = argv[0];
+       ifstream inFile;
+       try {
+               po::options_description desc("Allowed options");
+               desc.add_options()
+               ("help,h","produce help message")
+               ("file,f",value<string>(), "input file")
+               ;
+
+               po::positional_options_description p;
+               p.add("file",1);
+
+               po::variables_map vm;
+               po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
+               po::notify(vm);
+
+               if(vm.count("help")) {
+                       cout << desc << endl;
+                       return EXIT_FAILURE;
+               }
+
+               if(vm.count("file")) {
+#ifdef DEBUG 
+                       cout << "going to open file " << vm["file"].as<string>() << endl;
+#endif
+                       inFile.open(vm["file"].as<string>(), ios::in);
+                       if(!inFile) {
+                               cerr << "Error opening file " << vm["file"].as<string>() << endl;
+                               return EXIT_FAILURE;
+                       }
+               }
+               else {
+                       cout << "not input file given!" << endl << endl;
+                       cout << desc << endl;
+                       return EXIT_FAILURE;
+               }
+       }
+       catch(std::exception& ex) {
+               cout << ex.what() << endl;
+       }
+
+
+       string dir = "./instr/";
+
+       map<short, Iinstr*> instr;
+
+       CInstrFactory instrFab;
+       try {
+#ifdef DEBUG
+               cout << "Loaded " << instrFab.searchLibsInDir(dir) << " Libraryfiles" << endl;
+#else
+               instrFab.searchLibsInDir(dir);
+#endif
+               while(instrFab.getNumFiles() >= 1) {
+                       Iinstr* pinstr = instrFab.getNextInstr();
+                       instr.insert(make_pair(pinstr->getOpcode(),pinstr));
+#ifdef DEBUG
+                       cout << "found: " << instr->getName() << " its opcode is : " << instr->getOpcode() << endl;
+#endif
+               }
+       }
+       catch(std::bad_alloc& e) {
+               cerr << progName << ": bad_alloc caught " << e.what() << endl;
+               exit(EXIT_FAILURE); 
+       }
+
+
+
+
+       std::string str = "";
+       boost::char_separator<char> sep(";", "", boost::keep_empty_tokens);
+       boost::tokenizer<boost::char_separator<char> > tokens(str, sep);
+       disasm disasm(instr);
+       while(getline(inFile, str)) {
+               int count = 0;
+               tokens.assign(str);
+               stringstream out;
+               int type = 0;
+               for(auto tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
+                       if(tok_iter == tokens.begin()) {
+                               try {
+                                       type = lexical_cast<int>(*tok_iter);
+                                       count++;
+                                       continue;
+                               }
+                               catch(bad_lexical_cast &) {
+                                       break;
+                               }
+                               cout << endl;
+                       }
+                       switch(type) {
+                               case 2:
+                                       if(count == 1) {
+                                               cout << "; ";
+                                       }
+                                       cout << *tok_iter;
+                                       break;
+                               case 3:
+                                       if((*tok_iter).size() > 0) {
+                                               if(count > 1) {
+                                                       cout << endl;
+                                               }
+                                               cout << *tok_iter << ":";
+                                       }
+                                       break;
+                               case 1:
+                                       if(count == 1) {
+                                               out << "[0x" << *tok_iter << "]: ";
+                                       }
+                                       else if(count == 2) {
+                                               out << disasm.decode(*tok_iter);
+                                       }
+                                       else if(count == 3) {
+                                               //code saved in hex-file
+                                               //cout << *tok_iter ;
+                                       }
+                                       else if(count == 4) {
+                                               /* label */
+                                               if((*tok_iter).size() > 0) {
+                                                       cout << *tok_iter << ":" << endl;
+                                               }
+                                               cout << out.str();
+                                       }
+                                       else if(count == 5) {
+                                               if((*tok_iter).size() > 0) {
+                                                       cout << " ;";
+                                               }
+                                       }
+
+                                       if(count >= 5) {
+                                               cout << *tok_iter;
+                                       }
+                                       break;
+                               default:
+                                       cerr << "i was to lazy to implement the other format types for now" << endl;
+                       }
+                       count++;
+               }
+               if(type == 1 && count <= 4) {
+                       cout << out.str();
+               }
+               cout << endl;
+       }
+       inFile.close();
+
+       cout << endl;
+       return EXIT_SUCCESS;
+}
diff --git a/3c_disasm/disasm.cpp b/3c_disasm/disasm.cpp
new file mode 100644 (file)
index 0000000..b389d03
--- /dev/null
@@ -0,0 +1,52 @@
+#include <boost/lexical_cast.hpp>
+#include <boost/dynamic_bitset.hpp>
+#include "disasm.h"
+
+using namespace boost;
+
+std::string disasm::decode(std::string str)
+{
+       /* we need 0x prefix */
+       string hex = "0x";
+       hex.append(str);
+
+       unsigned int val =  lexical_cast<uint32_from_hex>(hex);
+
+       dynamic_bitset<> bits(32,val), opcode(32,val), condition(9), args(32);
+
+       args = opcode;
+       args.resize(23);
+
+       opcode >>= 23;
+       condition = opcode;
+       opcode.resize(5);
+
+       condition >>= 5;
+       condition.resize(4);
+
+       //cout << "<" << hex << "> is in int  " << val << "\t is binary " << bits << " opcode?" << opcode << " condition " << condition << endl;
+       try {
+               Iinstr* instr = decodeOpcode(opcode.to_ulong());
+               instr->decodeCondition(condition.to_ulong());
+               instr->loadBits(args);
+               instr->evalInstr();
+               return instr->toString();
+       }
+       catch(std::string &e) {
+               cerr << " Error: " << e << endl;
+       }
+       return "";
+}
+
+Iinstr* disasm::decodeOpcode(short opcode)
+{
+       auto iter = instrs.find(opcode);
+       if(iter != instrs.end()) {
+               return iter->second;
+       }
+       else {
+               stringstream err;
+               err << "opcode not found" << endl;
+               throw err.str();
+       }
+}
diff --git a/3c_disasm/disasm.h b/3c_disasm/disasm.h
new file mode 100644 (file)
index 0000000..908a3ee
--- /dev/null
@@ -0,0 +1,36 @@
+#include <iostream>
+#include <string>
+#include <map>
+
+#include "Iinstr.hpp"
+
+using namespace std;
+
+class disasm {
+
+       private:
+               std::map<short,Iinstr*> instrs;
+       class uint32_from_hex   // For use with boost::lexical_cast
+       {
+               typedef unsigned int uint32;
+               uint32 value;
+               public:
+                       operator uint32() const {
+                               return value;
+                       }
+                       friend std::istream& operator>>(std::istream& in, uint32_from_hex& outValue)
+                       {
+                               in >> std::hex >> outValue.value;
+                               return in;
+                       }
+       };
+
+       protected:
+               void decodeCondition(short);
+               Iinstr* decodeOpcode(short);
+
+       public:
+               disasm(std::map<short,Iinstr*> map) : instrs(map) {};
+               std::string decode(std::string);
+};
+
diff --git a/3c_disasm/instr/Makefile b/3c_disasm/instr/Makefile
new file mode 100644 (file)
index 0000000..95cc252
--- /dev/null
@@ -0,0 +1,24 @@
+-include ../Makefile.flags
+
+libs := $(wildcard *.cpp)
+
+.PHONY:all
+all: $(libs:.cpp=.so)
+
+-include $(libs:.cpp=.d)
+
+
+$(libs:.cpp=.so): ${@:.so=.d}
+       $(CC) -fPIC -I../ -c  -o ${@:.so=.o} ${@:.so=.cpp}
+       $(CC) $(CPPLIBOPT) -Wl,-soname,${@} -o ${@} ${@:.so=.o}
+
+.PHONY:clean
+clean:
+       rm -rf $(libs:.cpp=.so) $(libs:.cpp=.o) $(libs:.cpp=.d)
+
+%.d: %.cpp
+       @set -e; rm -f $@; \
+       $(CC) -I.. -MM $(CPPFLAGS) $< > $@.$$$$; \
+       sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+       rm -f $@.$$$$
+
diff --git a/3c_disasm/instr/add.cpp b/3c_disasm/instr/add.cpp
new file mode 100644 (file)
index 0000000..7cdf820
--- /dev/null
@@ -0,0 +1,69 @@
+#include "../Iinstr.hpp"
+
+class Cadd : public Iinstr {
+       public:
+               Cadd();
+               void evalInstr();
+               void execInstr();
+               std::string toString();
+};
+
+/**
+ * Name:      create_instruction
+ * Purpose:   if compiled as shared library, this functions creates the 
+              instruction object
+
+ * Returns:   pointer to instruction object
+ */
+extern "C" Iinstr* create_instruction() {
+    return new Cadd();
+}
+
+/**
+ * Name:      destroy_instruction
+ * Purpose:   if compiled as shared library, this functions destoys the 
+              instruction object
+
+ * Parameter: IInstruction - the instruction object to delete
+ */
+extern "C" void destroy_instruction(Iinstr* p) {
+    delete p;
+}
+
+Cadd::Cadd()
+{
+       opcode = B5(00000);
+       name = "add";
+}
+
+void Cadd::evalInstr()
+{
+       this->m_d = argbits[0];
+       this->m_c = argbits[1];
+       
+       argbits >>= 11;
+       m_rb = this->getRegister(argbits);
+
+       argbits >>= 4;
+       m_ra = this->getRegister(argbits);
+
+       argbits >>= 4;
+       m_rd = this->getRegister(argbits);
+}
+
+void Cadd::execInstr()
+{
+       cout << "should exec" << this->toString() << endl;
+}
+
+std::string Cadd::toString()
+{
+       stringstream op;
+       op << this->getName();
+
+       if(m_d) op << 'D';
+       if(m_c) op << 'C';
+
+       op << " r" << m_rd << ", r" << m_ra << ", r" << m_rb;
+       return op.str();
+}
diff --git a/3c_disasm/instr/addi.cpp b/3c_disasm/instr/addi.cpp
new file mode 100644 (file)
index 0000000..2ccdc04
--- /dev/null
@@ -0,0 +1,74 @@
+#include "../Iinstr.hpp"
+
+class Caddi : public Iinstr {
+       public:
+               Caddi();
+               void evalInstr();
+               void execInstr();
+               std::string toString();
+};
+
+/**
+ * Name:      create_instruction
+ * Purpose:   if compiled as shared library, this functions creates the 
+              instruction object
+
+ * Returns:   pointer to instruction object
+ */
+extern "C" Iinstr* create_instruction() {
+    return new Caddi();
+}
+
+/**
+ * Name:      destroy_instruction
+ * Purpose:   if compiled as shared library, this functions destoys the 
+              instruction object
+
+ * Parameter: IInstruction - the instruction object to delete
+ */
+extern "C" void destroy_instruction(Iinstr* p) {
+    delete p;
+}
+
+Caddi::Caddi()
+{
+       opcode = B5(00010);
+       name = "addi";
+}
+
+void Caddi::evalInstr()
+{
+       this->m_s = argbits[2];
+       this->m_c = argbits[1];
+       this->m_d = argbits[0];
+
+       argbits >>= 3;
+       dynamic_bitset<> immb = argbits;
+       immb.resize(12);
+       this->m_imm = this->generate12ImmSign(immb.to_ulong());
+
+       argbits >>= 12;
+       m_ra = this->getRegister(argbits);
+
+       argbits >>= 4;
+       m_rd = this->getRegister(argbits);
+}
+
+void Caddi::execInstr()
+{
+       cout << "should exec " << this->toString() << endl;
+}
+
+std::string Caddi::toString()
+{
+       stringstream op;
+       op << this->getName();
+
+       if(m_d) op << 'D';
+       if(m_s) op << 'S';
+       if(m_c) op << 'C';
+
+       op << this->getConditionFlag() << " r" << m_rd << ", r" << m_ra << ", " << m_imm;
+
+       return op.str();
+}
diff --git a/3c_disasm/instr/branch.cpp b/3c_disasm/instr/branch.cpp
new file mode 100644 (file)
index 0000000..37682d7
--- /dev/null
@@ -0,0 +1,95 @@
+#include "../Iinstr.hpp"
+
+class Cbranch : public Iinstr {
+       private:
+               bool m_taken;
+               char m_typ;
+       public:
+               Cbranch();
+               void evalInstr();
+               void execInstr();
+               std::string toString();
+};
+
+/**
+ * Name:      create_instruction
+ * Purpose:   if compiled as shared library, this functions creates the 
+              instruction object
+
+ * Returns:   pointer to instruction object
+ */
+extern "C" Iinstr* create_instruction() {
+    return new Cbranch();
+}
+
+/**
+ * Name:      destroy_instruction
+ * Purpose:   if compiled as shared library, this functions destoys the 
+              instruction object
+
+ * Parameter: IInstruction - the instruction object to delete
+ */
+extern "C" void destroy_instruction(Iinstr* p) {
+    delete p;
+}
+
+Cbranch::Cbranch() : m_taken(1), m_typ(0)
+{
+       opcode = B5(10110);
+       name = "branch";
+}
+
+void Cbranch::evalInstr()
+{
+       this->m_s = argbits[0];
+       this->m_taken = argbits[1];
+
+       argbits >>= 2;
+
+       dynamic_bitset<> type = argbits;
+       type.resize(2);
+       this->m_typ = type.to_ulong();
+
+       switch(m_typ) {
+               case 0:
+                       this->name = "branch";
+                       break;
+               case 1:
+                       this->name = "call";
+                       break;
+               case 2:
+                       this->name = "ret";
+                       break;
+               case 3:
+                       this->name = "reti";
+                       break;
+               default:
+                       cerr << "What have you done? 2 bits that have more than 4 values?!" << endl;
+       }
+
+       argbits >>= 5;
+
+       dynamic_bitset<> immb = argbits;
+       immb.resize(16);
+       this->m_imm = this->generate16ImmSign(immb.to_ulong());
+
+}
+
+void Cbranch::execInstr()
+{
+       cout << "should exec" << this->toString() << endl;
+}
+
+std::string Cbranch::toString()
+{
+       stringstream op;
+       op << this->getName();
+
+       if(m_s) op << 'S';
+
+       op << this->getConditionFlag() << (m_taken ? '+' : '-');
+       if(m_typ < 2) {
+               op << " 0x" << std::hex << m_imm << "(" << std::dec << m_imm << ")";
+       }
+       return op.str();
+}
diff --git a/3c_disasm/instr/ldi.cpp b/3c_disasm/instr/ldi.cpp
new file mode 100644 (file)
index 0000000..2c523a1
--- /dev/null
@@ -0,0 +1,70 @@
+#include "../Iinstr.hpp"
+
+
+class Cldi : public Iinstr {
+       public:
+               Cldi();
+               void evalInstr();
+               void execInstr();
+               std::string toString();
+};
+
+/**
+ * Name:      create_instruction
+ * Purpose:   if compiled as shared library, this functions creates the 
+              instruction object
+
+ * Returns:   pointer to instruction object
+ */
+extern "C" Iinstr* create_instruction() {
+    return new Cldi();
+}
+
+/**
+ * Name:      destroy_instruction
+ * Purpose:   if compiled as shared library, this functions destoys the 
+              instruction object
+
+ * Parameter: IInstruction - the instruction object to delete
+ */
+extern "C" void destroy_instruction(Iinstr* p) {
+    delete p;
+}
+
+Cldi::Cldi()
+{
+       opcode = B5(11010);
+       name = "ldi";
+}
+
+void Cldi::evalInstr()
+{
+       this->m_s = argbits[2];
+       this->m_hl = argbits[1];
+
+       argbits >>= 3;
+       dynamic_bitset<> immb = argbits;
+       immb.resize(16);
+       this->m_imm = this->generate16ImmSign(immb.to_ulong());
+
+       argbits >>= 16;
+       m_rd = this->getRegister(argbits);
+}
+
+void Cldi::execInstr()
+{
+       cout << "should exec " << this->toString() << endl;
+}
+
+std::string Cldi::toString()
+{
+       stringstream op;
+       op << this->getName();
+
+       if(m_hl) op << 'H';
+       if(m_s) op << 'S';
+
+       op << this->getConditionFlag() << " r" << m_rd << ", " << m_imm;
+
+       return op.str();
+}
diff --git a/3c_disasm/instr/ldw.cpp b/3c_disasm/instr/ldw.cpp
new file mode 100644 (file)
index 0000000..b77450c
--- /dev/null
@@ -0,0 +1,68 @@
+#include "../Iinstr.hpp"
+
+
+class Cldw : public Iinstr {
+       public:
+               Cldw();
+               void evalInstr();
+               void execInstr();
+               std::string toString();
+};
+
+/**
+ * Name:      create_instruction
+ * Purpose:   if compiled as shared library, this functions creates the 
+              instruction object
+
+ * Returns:   pointer to instruction object
+ */
+extern "C" Iinstr* create_instruction() {
+    return new Cldw();
+}
+
+/**
+ * Name:      destroy_instruction
+ * Purpose:   if compiled as shared library, this functions destoys the 
+              instruction object
+
+ * Parameter: IInstruction - the instruction object to delete
+ */
+extern "C" void destroy_instruction(Iinstr* p) {
+    delete p;
+}
+
+Cldw::Cldw()
+{
+       opcode = B5(01110);
+       name = "ldw";
+}
+
+void Cldw::evalInstr()
+{
+       this->m_s = true;
+
+       dynamic_bitset<> immb = argbits;
+       immb.resize(15);
+       this->m_imm = this->generate15ImmSign(immb.to_ulong());
+
+       argbits >>= 15;
+       m_ra = this->getRegister(argbits);
+       argbits >>= 4;
+       m_rd = this->getRegister(argbits);
+
+}
+
+void Cldw::execInstr()
+{
+       cout << "should exec " << this->toString() << endl;
+}
+
+std::string Cldw::toString()
+{
+       stringstream op;
+       op << this->getName();
+
+       op << this->getConditionFlag() << " r" << m_rd << ", " << m_imm << "(r" <<  m_ra << ")";
+
+       return op.str();
+}
diff --git a/3c_disasm/instr/subi.cpp b/3c_disasm/instr/subi.cpp
new file mode 100644 (file)
index 0000000..a988f81
--- /dev/null
@@ -0,0 +1,74 @@
+#include "../Iinstr.hpp"
+
+class Csubi : public Iinstr {
+       public:
+               Csubi();
+               void evalInstr();
+               void execInstr();
+               std::string toString();
+};
+
+/**
+ * Name:      create_instruction
+ * Purpose:   if compiled as shared library, this functions creates the 
+              instruction object
+
+ * Returns:   pointer to instruction object
+ */
+extern "C" Iinstr* create_instruction() {
+    return new Csubi();
+}
+
+/**
+ * Name:      destroy_instruction
+ * Purpose:   if compiled as shared library, this functions destoys the 
+              instruction object
+
+ * Parameter: IInstruction - the instruction object to delete
+ */
+extern "C" void destroy_instruction(Iinstr* p) {
+    delete p;
+}
+
+Csubi::Csubi()
+{
+       opcode = B5(00011);
+       name = "subi";
+}
+
+void Csubi::evalInstr()
+{
+       this->m_s = argbits[2];
+       this->m_c = argbits[1];
+       this->m_d = argbits[0];
+
+       argbits >>= 3;
+       dynamic_bitset<> immb = argbits;
+       immb.resize(12);
+       this->m_imm = this->generate12ImmSign(immb.to_ulong());
+
+       argbits >>= 12;
+       m_ra = this->getRegister(argbits);
+
+       argbits >>= 4;
+       m_rd = this->getRegister(argbits);
+}
+
+void Csubi::execInstr()
+{
+       cout << "should exec " << this->toString() << endl;
+}
+
+std::string Csubi::toString()
+{
+       stringstream op;
+       op << this->getName();
+
+       if(m_d) op << 'D';
+       if(m_s) op << 'S';
+       if(m_c) op << 'C';
+
+       op << this->getConditionFlag() << " r" << m_rd << ", r" << m_ra << ", " << m_imm;
+
+       return op.str();
+}