From b5f15e1e75a5027fc4eb3d27b0542cb3324ed3a9 Mon Sep 17 00:00:00 2001 From: Martin Perner Date: Thu, 28 Oct 2010 21:06:50 +0200 Subject: [PATCH] disasm: alpha version really basic, but runs on sample file --- 3_asmsim/sum.dthex | 4 +- 3c_disasm/CInstrFactory.cpp | 134 +++++++++++++++++++++++++ 3c_disasm/CInstrFactory.hpp | 45 +++++++++ 3c_disasm/Iinstr.hpp | 188 ++++++++++++++++++++++++++++++++++++ 3c_disasm/Makefile | 34 +++++++ 3c_disasm/Makefile.flags | 6 ++ 3c_disasm/dasm.cpp | 171 ++++++++++++++++++++++++++++++++ 3c_disasm/disasm.cpp | 52 ++++++++++ 3c_disasm/disasm.h | 36 +++++++ 3c_disasm/instr/Makefile | 24 +++++ 3c_disasm/instr/add.cpp | 69 +++++++++++++ 3c_disasm/instr/addi.cpp | 74 ++++++++++++++ 3c_disasm/instr/branch.cpp | 95 ++++++++++++++++++ 3c_disasm/instr/ldi.cpp | 70 ++++++++++++++ 3c_disasm/instr/ldw.cpp | 68 +++++++++++++ 3c_disasm/instr/subi.cpp | 74 ++++++++++++++ 16 files changed, 1142 insertions(+), 2 deletions(-) create mode 100644 3c_disasm/CInstrFactory.cpp create mode 100644 3c_disasm/CInstrFactory.hpp create mode 100644 3c_disasm/Iinstr.hpp create mode 100644 3c_disasm/Makefile create mode 100644 3c_disasm/Makefile.flags create mode 100644 3c_disasm/dasm.cpp create mode 100644 3c_disasm/disasm.cpp create mode 100644 3c_disasm/disasm.h create mode 100644 3c_disasm/instr/Makefile create mode 100644 3c_disasm/instr/add.cpp create mode 100644 3c_disasm/instr/addi.cpp create mode 100644 3c_disasm/instr/branch.cpp create mode 100644 3c_disasm/instr/ldi.cpp create mode 100644 3c_disasm/instr/ldw.cpp create mode 100644 3c_disasm/instr/subi.cpp diff --git a/3_asmsim/sum.dthex b/3_asmsim/sum.dthex index 31ad135..0ccc6a3 100644 --- a/3_asmsim/sum.dthex +++ b/3_asmsim/sum.dthex @@ -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 index 0000000..b3aed27 --- /dev/null +++ b/3c_disasm/CInstrFactory.cpp @@ -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 index 0000000..7a1c342 --- /dev/null +++ b/3c_disasm/CInstrFactory.hpp @@ -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 + +#include +#include +#include +#include +#include + +#include +#include + +#include + +/** + * Name: CInstructionFactory + * Purpose: Factory for creating commands from shared libraries + */ +class CInstrFactory { +private: + std::map m_libStore; + std::vector 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 index 0000000..95b5229 --- /dev/null +++ b/3c_disasm/Iinstr.hpp @@ -0,0 +1,188 @@ +#include +#include +#include +#include + +#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 index 0000000..35b6ff5 --- /dev/null +++ b/3c_disasm/Makefile @@ -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 index 0000000..1284653 --- /dev/null +++ b/3c_disasm/Makefile.flags @@ -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 index 0000000..08796f1 --- /dev/null +++ b/3c_disasm/dasm.cpp @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include +#include +#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(), "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() << endl; +#endif + inFile.open(vm["file"].as(), ios::in); + if(!inFile) { + cerr << "Error opening file " << vm["file"].as() << 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 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 sep(";", "", boost::keep_empty_tokens); + boost::tokenizer > 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(*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 index 0000000..b389d03 --- /dev/null +++ b/3c_disasm/disasm.cpp @@ -0,0 +1,52 @@ +#include +#include +#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(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 index 0000000..908a3ee --- /dev/null +++ b/3c_disasm/disasm.h @@ -0,0 +1,36 @@ +#include +#include +#include + +#include "Iinstr.hpp" + +using namespace std; + +class disasm { + + private: + std::map 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 map) : instrs(map) {}; + std::string decode(std::string); +}; + diff --git a/3c_disasm/instr/Makefile b/3c_disasm/instr/Makefile new file mode 100644 index 0000000..95cc252 --- /dev/null +++ b/3c_disasm/instr/Makefile @@ -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 index 0000000..7cdf820 --- /dev/null +++ b/3c_disasm/instr/add.cpp @@ -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 index 0000000..2ccdc04 --- /dev/null +++ b/3c_disasm/instr/addi.cpp @@ -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 index 0000000..37682d7 --- /dev/null +++ b/3c_disasm/instr/branch.cpp @@ -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 index 0000000..2c523a1 --- /dev/null +++ b/3c_disasm/instr/ldi.cpp @@ -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 index 0000000..b77450c --- /dev/null +++ b/3c_disasm/instr/ldw.cpp @@ -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 index 0000000..a988f81 --- /dev/null +++ b/3c_disasm/instr/subi.cpp @@ -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(); +} -- 2.25.1