From 12d2a7c14a42e01b6caf2a097db32404a403d213 Mon Sep 17 00:00:00 2001 From: Martin Perner Date: Sat, 30 Oct 2010 14:01:34 +0200 Subject: [PATCH] disasm/sim: changed interface, branch => br, features++ --- 2_isa/misc.ptex | 2 +- 3b_sim/CInstrFactory.cpp | 1 + 3b_sim/CInstrFactory.hpp | 1 + 3b_sim/Iinstr.hpp | 1 + 3b_sim/ccpu.cpp | 129 ++++++++++++++++++++++++++++++++-- 3b_sim/ccpu.hpp | 29 ++++++-- 3b_sim/cdat.hpp | 4 +- 3b_sim/cmem.cpp | 11 +-- 3b_sim/cmem.hpp | 9 ++- 3b_sim/cpmem.cpp | 53 ++++++++++++++ 3b_sim/cpmem.hpp | 37 ++++++++++ 3b_sim/disasm.cpp | 1 + 3b_sim/disasm.h | 1 + 3b_sim/instr | 1 + 3b_sim/sim.cpp | 114 ++++++++++++++++++++---------- 3b_sim/uint32_from_hex.hpp | 1 + 3c_disasm/CInstrFactory.cpp | 17 +++++ 3c_disasm/CInstrFactory.hpp | 1 + 3c_disasm/Iinstr.hpp | 22 +++++- 3c_disasm/dasm.cpp | 15 +--- 3c_disasm/disasm.cpp | 14 ++-- 3c_disasm/disasm.h | 19 +---- 3c_disasm/instr/add.cpp | 10 ++- 3c_disasm/instr/addi.cpp | 9 +++ 3c_disasm/instr/branch.cpp | 32 ++++++++- 3c_disasm/instr/ldi.cpp | 6 ++ 3c_disasm/instr/ldw.cpp | 10 +++ 3c_disasm/instr/subi.cpp | 8 +++ 3c_disasm/uint32_from_hex.hpp | 19 +++++ 29 files changed, 477 insertions(+), 100 deletions(-) create mode 120000 3b_sim/CInstrFactory.cpp create mode 120000 3b_sim/CInstrFactory.hpp create mode 120000 3b_sim/Iinstr.hpp create mode 100644 3b_sim/cpmem.cpp create mode 100644 3b_sim/cpmem.hpp create mode 120000 3b_sim/disasm.cpp create mode 120000 3b_sim/disasm.h create mode 120000 3b_sim/instr create mode 120000 3b_sim/uint32_from_hex.hpp create mode 100644 3c_disasm/uint32_from_hex.hpp diff --git a/2_isa/misc.ptex b/2_isa/misc.ptex index 9ba12d8..9a1d553 100644 --- a/2_isa/misc.ptex +++ b/2_isa/misc.ptex @@ -1,7 +1,7 @@ ins ('32', 'jumpop', 'Branch/ret operation', '4 | 5 | 16 | 3 | 2 | 1 | 1', 'Conditions | OpCode (10110) | Immediate | - | Type | +/- | S', 'This instruction should be used with it\'s aliases branch, call, ret and reti. No flags will be affected by this instructions.','','', -'branch-Branch relative-4/00|call-Branch relative and save pc to stack-4/01|ret-Return to adress on stack-4/10|ret-Return from interrupt to adress on stack-4/11'); +'br-Branch relative-4/00|call-Branch relative and save pc to stack-4/01|ret-Return to adress on stack-4/10|ret-Return from interrupt to adress on stack-4/11'); ins ('32', 'branchreg', 'Branch; jump to value of reg', '4 | 5 | 4 | 16 | 1 | 1 | 1', 'Conditions | OpCode (10111) | Register A | - | Type | +/- | -', diff --git a/3b_sim/CInstrFactory.cpp b/3b_sim/CInstrFactory.cpp new file mode 120000 index 0000000..6a2330e --- /dev/null +++ b/3b_sim/CInstrFactory.cpp @@ -0,0 +1 @@ +../3c_disasm/CInstrFactory.cpp \ No newline at end of file diff --git a/3b_sim/CInstrFactory.hpp b/3b_sim/CInstrFactory.hpp new file mode 120000 index 0000000..016e9b2 --- /dev/null +++ b/3b_sim/CInstrFactory.hpp @@ -0,0 +1 @@ +../3c_disasm/CInstrFactory.hpp \ No newline at end of file diff --git a/3b_sim/Iinstr.hpp b/3b_sim/Iinstr.hpp new file mode 120000 index 0000000..c150d4e --- /dev/null +++ b/3b_sim/Iinstr.hpp @@ -0,0 +1 @@ +../3c_disasm/Iinstr.hpp \ No newline at end of file diff --git a/3b_sim/ccpu.cpp b/3b_sim/ccpu.cpp index 3ad97fb..3fee875 100644 --- a/3b_sim/ccpu.cpp +++ b/3b_sim/ccpu.cpp @@ -8,28 +8,143 @@ void CCpu::tick() { + // signal extensions + // Todo + m_pc = m_pc_next; m_pc_next += 4; + Iinstr* instr = this->getProg(m_pc); + if(instr == NULL) { + throw string("Out of Instructions!"); + } + if(this->conditionMet(instr->getCondition())) { + instr->execInstr(); + } +} + +bool CCpu::conditionMet(short cond) +{ + switch(cond) { + case NOT_EQUAL: + return !this->m_Z; + break; + case EQUAL: + return this->m_Z; + break; + case NOT_OVERFLOW: + return !this->m_O; + break; + case OVER_FLOW: + return this->m_O; + break; + case NOT_CARRY: + return !this->m_C; + break; + case CARRY: + return this->m_C; + break; + case NOT_SIGNED: + return !this->m_S; + break; + case SIGNED: + return this->m_S; + break; + case ABOVE: + return (!this->m_C && !this->m_Z); + break; + case BELOW_EQ: + return (this->m_C || this->m_Z); + break; + case GREATER_EQ: + return (this->m_S == this->m_O); + break; + case LESS: + return (this->m_S != this->m_O); + break; + case GREATER: + return (!this->m_Z && (this->m_S == this->m_O)); + break; + case LESS_EQ: + return (!this->m_Z || (this->m_S != this->m_O)); + break; + case ALWAYS: + return true; + break; + case NEVER: + return false; + break; + default: + cerr << "What did you do? more than 16 values in 5 bits?!" << endl; + return false; + } + +} + +CDat CCpu::getCurPC() const +{ + return m_pc; } -CDat CCpu::getNextPC() const +void CCpu::setNextPC(CDat val) { - return m_pc_next; + m_pc_next = val; } +void CCpu::updateFlags(CDat val) { + this->m_Z = (val == 0); + this->m_S = ((val >> (BIT_LEN-1)) & 0x1); + this->m_C = false; + this->m_O = false; +} + +void CCpu::updateFlags(bool z, bool o, bool c, bool s) +{ + this->m_Z = z; + this->m_O = o; + this->m_C = c; + this->m_S = s; +} + +CDat CCpu::getRegister(const int addr) const +{ + return m_reg.get(addr); +} -// CDat getRegister(const short) const {}; -// void setRegister(const short, CDat&) {}; +void CCpu::setRegister(const int addr, CDat data) +{ + m_reg.set(addr, data); +} -// CDat getRAM(const short) const {}; -// void setRAM(const short, CDat&) {}; +CDat CCpu::getRAM(const int addr) const +{ + return m_ram.get(addr); +} +void CCpu::setRAM(const int addr, CDat data) +{ + m_ram.set(addr, data); +} void CCpu::setProg(int addr, Iinstr* instr) { m_prog.set(addr, instr); } -CCpu::CCpu() : m_pc(0), m_pc_next(0), m_regfile(0), m_ram(0), m_prog(0) +Iinstr* CCpu::getProg(const int addr) const +{ + return m_prog.get(addr); +} + +int CCpu::getStack() const +{ + return this->m_stack; +} + +void CCpu::setStack(const int val) +{ + this->m_stack = val; +} + +CCpu::CCpu(int regs, int ram, int prog) : m_Z(false), m_S(false), m_C(false), m_O(false), m_pc(0), m_pc_next(0), m_reg(regs), m_ram(ram), m_prog(prog), m_stack(0) { } diff --git a/3b_sim/ccpu.hpp b/3b_sim/ccpu.hpp index 89867ef..e428f63 100644 --- a/3b_sim/ccpu.hpp +++ b/3b_sim/ccpu.hpp @@ -1,36 +1,51 @@ - - #ifndef __CPU__H__ #define __CPU__H__ #include "cdat.hpp" #include "cmem.hpp" #include "cpmem.hpp" + +class Iinstr; + #include "Iinstr.hpp" + class CCpu { private: + bool m_Z, m_S, m_C, m_O; + CDat m_pc, m_pc_next; - CMem m_regfile, m_ram; + CMem m_reg, m_ram; CPMem m_prog; + CDat m_stack; + public: void registerExtension() {}; void tick(); CDat getRegister(const int) const; - void setRegister(const int, CDat&); + void setRegister(const int, CDat); CDat getRAM(const int) const; - void setRAM(const int, CDat&); + void setRAM(const int, CDat); Iinstr* getProg(const int) const; void setProg(const int, Iinstr*); - CDat getNextPC() const; + CDat getCurPC() const; + void setNextPC(CDat); + + void updateFlags(CDat); + void updateFlags(bool z, bool o, bool c, bool s); + + bool conditionMet(short); + + int getStack() const; + void setStack(const int); - CCpu(); + CCpu(int,int,int); }; diff --git a/3b_sim/cdat.hpp b/3b_sim/cdat.hpp index e318aff..e9f88f6 100644 --- a/3b_sim/cdat.hpp +++ b/3b_sim/cdat.hpp @@ -6,5 +6,7 @@ typedef int CDat; -static_assert(sizeof(CDat) == 4, "The size of the datatype for int is NOT 4 bytes (32 Bit!)"); +#define BIT_LEN 32 + +//static_assert(sizeof(CDat) == 4, "The size of the datatype for int is NOT 4 bytes (32 Bit!)"); #endif diff --git a/3b_sim/cmem.cpp b/3b_sim/cmem.cpp index 90886a2..22c80e6 100644 --- a/3b_sim/cmem.cpp +++ b/3b_sim/cmem.cpp @@ -2,7 +2,7 @@ using namespace std; -template +template void CMem::set(const MEMORY_ADDRESS address, const T& data) { if(address >= MAX_MEMORY) { @@ -23,13 +23,16 @@ void CMem::set(const MEMORY_ADDRESS address, const T& data) m_memory.erase(iter); } -template -void CMem::get(const MEMORY_ADDRESS address, T& value) const +template +T CMem::get(const MEMORY_ADDRESS address) const { if(address >= MAX_MEMORY) { stringstream error; error << "memoryaddress " << address << " out of range"; throw out_of_range(error.str()); } - value = m_memory[address]; + return m_memory[address]; } + + +template class CMem; diff --git a/3b_sim/cmem.hpp b/3b_sim/cmem.hpp index 195fe6c..d5cd593 100644 --- a/3b_sim/cmem.hpp +++ b/3b_sim/cmem.hpp @@ -5,13 +5,15 @@ #include #include + typedef int MEMORY_ADDRESS; + /** * Name: CMem * Purpose: Class representing the memory of our emulated machine */ -template +template class CMem { private: @@ -19,11 +21,8 @@ private: const int MAX_MEMORY; std::vector m_memory; public: - //wert aus referenz auslesen und in vetor speichern (index zugriff!) - //address 0 ist ProgramCounter void set(const MEMORY_ADDRESS address, const T& data); - //retuniert referenz eines cdat objekts mit dem Wert von address - void get(const MEMORY_ADDRESS address, T& data) const; + T get(const MEMORY_ADDRESS address) const; CMem(int size) : MAX_MEMORY(size), m_memory(size) {}; }; diff --git a/3b_sim/cpmem.cpp b/3b_sim/cpmem.cpp new file mode 100644 index 0000000..31205e6 --- /dev/null +++ b/3b_sim/cpmem.cpp @@ -0,0 +1,53 @@ + +//i'm sorry +//pervert forwarding +//didn't know (or was to lazy) to find another fix +#define __CPU__H__ +class CCpu; + +#include "cpmem.hpp" + +using namespace std; + +template +void CPMem::set(const MEMORY_ADDRESS address, const T data) +{ + if(address >= MAX_MEMORY) { + stringstream error; + error << "memoryaddress " << address << " out of range"; + throw out_of_range(error.str()); + } + + MEMORY_ADDRESS temp = address; + auto iter = m_memory.begin(); + while(temp > 0) { + ++iter; + temp--; + } + + iter = m_memory.insert(iter, data); + ++iter; + m_memory.erase(iter); +} + +template +T CPMem::get(const MEMORY_ADDRESS address) const +{ + if(address >= MAX_MEMORY) { + stringstream error; + error << "memoryaddress " << address << " out of range"; + throw out_of_range(error.str()); + } + return m_memory[address]; +} + +template +CPMem::~CPMem() +{ + for(auto iter = m_memory.begin(); iter != m_memory.end(); ++iter) { + delete (*iter); + } +} + + +template class CPMem; diff --git a/3b_sim/cpmem.hpp b/3b_sim/cpmem.hpp new file mode 100644 index 0000000..fd09f3c --- /dev/null +++ b/3b_sim/cpmem.hpp @@ -0,0 +1,37 @@ +#ifndef __CPMEM_H__ +#define __CPMEM_H__ + +template +class CPMem; + +#include "cdat.hpp" +#include +#include +#include + +#include "Iinstr.hpp" + +typedef int MEMORY_ADDRESS; + +/** + * Name: CMem + * Purpose: Class representing the memory of our emulated machine + */ +template +class CPMem +{ +private: + //MAX_MEMORY-1 zugreifbare Speicherzellen + const int MAX_MEMORY; + std::vector m_memory; +public: + //wert aus referenz auslesen und in vetor speichern (index zugriff!) + //address 0 ist ProgramCounter + void set(const MEMORY_ADDRESS address, const T data); + //retuniert referenz eines cdat objekts mit dem Wert von address + T get(const MEMORY_ADDRESS address) const; + CPMem(int size) : MAX_MEMORY(size), m_memory(size, NULL) {}; + ~CPMem(); +}; + +#endif diff --git a/3b_sim/disasm.cpp b/3b_sim/disasm.cpp new file mode 120000 index 0000000..4aeda7f --- /dev/null +++ b/3b_sim/disasm.cpp @@ -0,0 +1 @@ +../3c_disasm/disasm.cpp \ No newline at end of file diff --git a/3b_sim/disasm.h b/3b_sim/disasm.h new file mode 120000 index 0000000..d38dcdb --- /dev/null +++ b/3b_sim/disasm.h @@ -0,0 +1 @@ +../3c_disasm/disasm.h \ No newline at end of file diff --git a/3b_sim/instr b/3b_sim/instr new file mode 120000 index 0000000..b58fe4c --- /dev/null +++ b/3b_sim/instr @@ -0,0 +1 @@ +../3c_disasm/instr \ No newline at end of file diff --git a/3b_sim/sim.cpp b/3b_sim/sim.cpp index ae5b16b..9d2fb5a 100644 --- a/3b_sim/sim.cpp +++ b/3b_sim/sim.cpp @@ -9,6 +9,9 @@ #include "disasm.h" #include "ccpu.hpp" #include "CInstrFactory.hpp" +#include "uint32_from_hex.hpp" + +CCpu* Iinstr::m_cpu; using boost::lexical_cast; using boost::bad_lexical_cast; @@ -82,7 +85,9 @@ int main(int argc, char* argv[]) } - CCpu cpu; + CCpu cpu(16,1000,1000); + + Iinstr::setCPU(&cpu); std::string str = ""; @@ -108,61 +113,98 @@ int main(int argc, char* argv[]) cout << endl; } switch(type) { - case 2: + case 0: if(count == 1) { - cout << "; "; + try { + addr = lexical_cast(*tok_iter); + } + catch(bad_lexical_cast& e) { + cerr << e.what() << endl; + exit(EXIT_FAILURE); + } } - cout << *tok_iter; - break; - case 3: - if((*tok_iter).size() > 0) { - if(count > 1) { - cout << endl; + else if(count == 2) { + try { + CDat data = lexical_cast(*tok_iter); + cpu.setRAM(addr, data); + } + catch(bad_lexical_cast& e) { + cerr << e.what() << endl; + exit(EXIT_FAILURE); } - cout << *tok_iter << ":"; } break; case 1: if(count == 1) { - out << "[0x" << *tok_iter << "]: "; - addr = lexical_cast(*tok_iter); - } - else if(count == 2) { - cpu.setProg(addr, 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; + try { + addr = lexical_cast(*tok_iter); } - cout << out.str(); - } - else if(count == 5) { - if((*tok_iter).size() > 0) { - cout << " ;"; + catch(bad_lexical_cast& e) { + cerr << e.what() << endl; + exit(EXIT_FAILURE); } } - - if(count >= 5) { - cout << *tok_iter; + else if(count == 2) { + Iinstr *pi = disasm.decode(*tok_iter); + cpu.setProg(addr, pi); } break; + case 2: + case 3: + cerr << "ignoring labels and comments for now" << endl; 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; + + + for(int i = 0; i <= 32; i += 4) { + Iinstr *pinstr = cpu.getProg(i); + if(pinstr != NULL) { + cout << i << " : " << std::hex << i << std::dec << " " << pinstr->toString() << endl; + } + else { + cout << "Null at " << i << " : " << std::hex << i << endl; + } + } + + for(int i = 0; i <= 32; i += 4) { + CDat data = cpu.getRAM(i); + cout << i << " : " << std::hex << i << std::dec << " " << data << endl; + } + + cpu.setRegister(1, 4); + cpu.setRegister(2, 0); + cpu.setRAM(0,5); + cpu.setRAM(4,50); + cpu.setRAM(8,32); + cpu.setRAM(12,45); + + // following: job of the bootloader + //set stackpointer + cpu.setStack(500); + //set return to nowhere for ret + cpu.setRAM(500,50); + + for(int i = 0; ; i++) { + try { + cpu.tick(); + cout << " reg0: " << cpu.getRegister(0) << " reg1: " << cpu.getRegister(1); + cout << " reg2: " << cpu.getRegister(2) << " reg3: " << cpu.getRegister(3); + cout << " reg4: " << cpu.getRegister(4) << " reg5: " << cpu.getRegister(5); + cout << endl << endl; + + } + catch(string& e) { + cerr << e << endl; + break; + } + } + return EXIT_SUCCESS; } diff --git a/3b_sim/uint32_from_hex.hpp b/3b_sim/uint32_from_hex.hpp new file mode 120000 index 0000000..7f140c3 --- /dev/null +++ b/3b_sim/uint32_from_hex.hpp @@ -0,0 +1 @@ +../3c_disasm/uint32_from_hex.hpp \ No newline at end of file diff --git a/3c_disasm/CInstrFactory.cpp b/3c_disasm/CInstrFactory.cpp index b3aed27..56c37fd 100644 --- a/3c_disasm/CInstrFactory.cpp +++ b/3c_disasm/CInstrFactory.cpp @@ -116,6 +116,23 @@ size_t CInstrFactory::getNumFiles() return m_files.size(); } +void CInstrFactory::loadLibsIntoMap(map& instr, string dir) +{ +#ifdef DEBUG + cout << "Loaded " << this->searchLibsInDir(dir) << " Libraryfiles" << endl; +#else + this->searchLibsInDir(dir); +#endif + while(this->getNumFiles() >= 1) { + Iinstr* pinstr = this->getNextInstr(); + instr.insert(make_pair(pinstr->getOpcode(),pinstr)); +#ifdef DEBUG + cout << "found: " << pinstr->getName() << " its opcode is : " << pinstr->getOpcode() << endl; +#endif + } +} + + /** * Name: ~CInstrFactory * Purpose: Destructor of the Object diff --git a/3c_disasm/CInstrFactory.hpp b/3c_disasm/CInstrFactory.hpp index 7a1c342..55fc449 100644 --- a/3c_disasm/CInstrFactory.hpp +++ b/3c_disasm/CInstrFactory.hpp @@ -38,6 +38,7 @@ public: Iinstr* getNextInstr(); size_t getNumFiles(); size_t searchLibsInDir(std::string dir); + void loadLibsIntoMap(map& instr, string dir); CInstrFactory() : m_libStore(), m_files() {}; ~CInstrFactory(); }; diff --git a/3c_disasm/Iinstr.hpp b/3c_disasm/Iinstr.hpp index d590dc7..416db47 100644 --- a/3c_disasm/Iinstr.hpp +++ b/3c_disasm/Iinstr.hpp @@ -1,10 +1,15 @@ +#ifndef __IINSTR_I_ +#define __IINSTR_I_ + #include #include #include #include -#ifndef __IINSTR_I_ -#define __IINSTR_I_ +class CCpu; + +#include "ccpu.hpp" + /* concept from https://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f */ #define to_HEX__(x) 0x##x##LU @@ -16,6 +21,7 @@ +((x & 0xF0000UL) ? 16 : 0) #define B5(x) ((unsigned char)to_B5__(to_HEX__(x))) +/* end concept */ using namespace std; using namespace boost; @@ -107,7 +113,12 @@ class Iinstr { return bits.to_ulong(); } + static CCpu* m_cpu; + public: + + static void setCPU(CCpu* cpu) { m_cpu = cpu; } + virtual ~Iinstr() {} virtual short getOpcode() { return this->opcode; } virtual std::string getName() { return this->name; } @@ -115,6 +126,11 @@ class Iinstr { virtual void evalInstr() = 0; virtual void execInstr() = 0; virtual std::string toString() = 0; + virtual Iinstr* getNew() = 0; + + short getCondition() { + return m_cond; + } void decodeCondition(short condition) { if(condition >= 0 && condition <= 15) { @@ -126,6 +142,7 @@ class Iinstr { } protected: + std::string getConditionFlag() { stringstream cond; @@ -185,4 +202,5 @@ class Iinstr { return cond.str(); } }; + #endif diff --git a/3c_disasm/dasm.cpp b/3c_disasm/dasm.cpp index 08796f1..177da6e 100644 --- a/3c_disasm/dasm.cpp +++ b/3c_disasm/dasm.cpp @@ -69,18 +69,7 @@ int main(int argc, char* argv[]) 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 - } + instrFab.loadLibsIntoMap(instr, dir); } catch(std::bad_alloc& e) { cerr << progName << ": bad_alloc caught " << e.what() << endl; @@ -131,7 +120,7 @@ int main(int argc, char* argv[]) out << "[0x" << *tok_iter << "]: "; } else if(count == 2) { - out << disasm.decode(*tok_iter); + out << disasm.decodeToString(*tok_iter); } else if(count == 3) { //code saved in hex-file diff --git a/3c_disasm/disasm.cpp b/3c_disasm/disasm.cpp index b389d03..0c6c5f0 100644 --- a/3c_disasm/disasm.cpp +++ b/3c_disasm/disasm.cpp @@ -4,7 +4,7 @@ using namespace boost; -std::string disasm::decode(std::string str) +Iinstr* disasm::decode(std::string str) { /* we need 0x prefix */ string hex = "0x"; @@ -30,19 +30,25 @@ std::string disasm::decode(std::string str) instr->decodeCondition(condition.to_ulong()); instr->loadBits(args); instr->evalInstr(); - return instr->toString(); + return instr; } catch(std::string &e) { cerr << " Error: " << e << endl; } - return ""; + return NULL; +} + +std::string disasm::decodeToString(std::string str) +{ + return this->decode(str)->toString(); } Iinstr* disasm::decodeOpcode(short opcode) { auto iter = instrs.find(opcode); if(iter != instrs.end()) { - return iter->second; + Iinstr* p = (iter->second)->getNew(); + return p; } else { stringstream err; diff --git a/3c_disasm/disasm.h b/3c_disasm/disasm.h index 908a3ee..078bd17 100644 --- a/3c_disasm/disasm.h +++ b/3c_disasm/disasm.h @@ -2,6 +2,7 @@ #include #include +#include "uint32_from_hex.hpp" #include "Iinstr.hpp" using namespace std; @@ -10,27 +11,13 @@ 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); + Iinstr* decode(std::string); + std::string decodeToString(std::string str); }; diff --git a/3c_disasm/instr/add.cpp b/3c_disasm/instr/add.cpp index 7cdf820..f196794 100644 --- a/3c_disasm/instr/add.cpp +++ b/3c_disasm/instr/add.cpp @@ -6,6 +6,7 @@ class Cadd : public Iinstr { void evalInstr(); void execInstr(); std::string toString(); + Iinstr* getNew(); }; /** @@ -19,6 +20,10 @@ extern "C" Iinstr* create_instruction() { return new Cadd(); } +Iinstr* Cadd::getNew() { + return new Cadd(); +} + /** * Name: destroy_instruction * Purpose: if compiled as shared library, this functions destoys the @@ -53,7 +58,10 @@ void Cadd::evalInstr() void Cadd::execInstr() { - cout << "should exec" << this->toString() << endl; + cout << "should exec " << this->toString() << endl; + CDat val = this->m_cpu->getRegister(m_ra) + this->m_cpu->getRegister(m_rb); + this->m_cpu->setRegister(m_rd, val); + this->m_cpu->updateFlags(val); } std::string Cadd::toString() diff --git a/3c_disasm/instr/addi.cpp b/3c_disasm/instr/addi.cpp index 2ccdc04..bb10a08 100644 --- a/3c_disasm/instr/addi.cpp +++ b/3c_disasm/instr/addi.cpp @@ -6,6 +6,7 @@ class Caddi : public Iinstr { void evalInstr(); void execInstr(); std::string toString(); + Iinstr* getNew(); }; /** @@ -19,6 +20,11 @@ extern "C" Iinstr* create_instruction() { return new Caddi(); } +Iinstr* Caddi::getNew() { + return new Caddi(); +} + + /** * Name: destroy_instruction * Purpose: if compiled as shared library, this functions destoys the @@ -57,6 +63,9 @@ void Caddi::evalInstr() void Caddi::execInstr() { cout << "should exec " << this->toString() << endl; + CDat reg = this->m_cpu->getRegister(m_ra) + this->m_imm; + this->m_cpu->setRegister(m_rd, reg); + this->m_cpu->updateFlags(reg); } std::string Caddi::toString() diff --git a/3c_disasm/instr/branch.cpp b/3c_disasm/instr/branch.cpp index 37682d7..90a56cb 100644 --- a/3c_disasm/instr/branch.cpp +++ b/3c_disasm/instr/branch.cpp @@ -9,6 +9,7 @@ class Cbranch : public Iinstr { void evalInstr(); void execInstr(); std::string toString(); + Iinstr* getNew(); }; /** @@ -22,6 +23,10 @@ extern "C" Iinstr* create_instruction() { return new Cbranch(); } +Iinstr* Cbranch::getNew() +{ + return new Cbranch(); +} /** * Name: destroy_instruction * Purpose: if compiled as shared library, this functions destoys the @@ -50,9 +55,9 @@ void Cbranch::evalInstr() type.resize(2); this->m_typ = type.to_ulong(); - switch(m_typ) { + switch(this->m_typ) { case 0: - this->name = "branch"; + this->name = "br"; break; case 1: this->name = "call"; @@ -77,7 +82,28 @@ void Cbranch::evalInstr() void Cbranch::execInstr() { - cout << "should exec" << this->toString() << endl; + cout << "should exec " << this->toString() << endl; + CDat pc = this->m_cpu->getCurPC(); + switch(this->m_typ) { + case 1: + { + CDat sp = this->m_cpu->getStack(); + this->m_cpu->setRAM(sp, pc); + sp -= 4; + this->m_cpu->setStack(sp); + } + case 0: + this->m_cpu->setNextPC(pc+this->m_imm); + break; + case 2: + case 3: + this->m_cpu->setNextPC(this->m_cpu->getRAM(this->m_cpu->getStack())); + this->m_cpu->setStack(this->m_cpu->getStack()+4); + break; + default: + // nothing + this->m_cpu->setNextPC(400); + } } std::string Cbranch::toString() diff --git a/3c_disasm/instr/ldi.cpp b/3c_disasm/instr/ldi.cpp index 2c523a1..98e72ca 100644 --- a/3c_disasm/instr/ldi.cpp +++ b/3c_disasm/instr/ldi.cpp @@ -7,6 +7,7 @@ class Cldi : public Iinstr { void evalInstr(); void execInstr(); std::string toString(); + Iinstr* getNew(); }; /** @@ -20,6 +21,10 @@ extern "C" Iinstr* create_instruction() { return new Cldi(); } +Iinstr* Cldi::getNew() +{ + return new Cldi(); +} /** * Name: destroy_instruction * Purpose: if compiled as shared library, this functions destoys the @@ -54,6 +59,7 @@ void Cldi::evalInstr() void Cldi::execInstr() { cout << "should exec " << this->toString() << endl; + this->m_cpu->setRegister(this->m_rd, this->m_imm); } std::string Cldi::toString() diff --git a/3c_disasm/instr/ldw.cpp b/3c_disasm/instr/ldw.cpp index b77450c..354e23f 100644 --- a/3c_disasm/instr/ldw.cpp +++ b/3c_disasm/instr/ldw.cpp @@ -7,6 +7,7 @@ class Cldw : public Iinstr { void evalInstr(); void execInstr(); std::string toString(); + Iinstr* getNew(); }; /** @@ -20,6 +21,11 @@ extern "C" Iinstr* create_instruction() { return new Cldw(); } +Iinstr* Cldw::getNew() +{ + return new Cldw(); +} + /** * Name: destroy_instruction * Purpose: if compiled as shared library, this functions destoys the @@ -55,6 +61,10 @@ void Cldw::evalInstr() void Cldw::execInstr() { cout << "should exec " << this->toString() << endl; + CDat val = this->m_cpu->getRegister(this->m_ra); + val += m_imm; + val = this->m_cpu->getRAM(val); + this->m_cpu->setRegister(this->m_rd,val); } std::string Cldw::toString() diff --git a/3c_disasm/instr/subi.cpp b/3c_disasm/instr/subi.cpp index a988f81..8a90ae8 100644 --- a/3c_disasm/instr/subi.cpp +++ b/3c_disasm/instr/subi.cpp @@ -6,6 +6,7 @@ class Csubi : public Iinstr { void evalInstr(); void execInstr(); std::string toString(); + Iinstr* getNew(); }; /** @@ -19,6 +20,10 @@ extern "C" Iinstr* create_instruction() { return new Csubi(); } +Iinstr* Csubi::getNew() { + return new Csubi(); +} + /** * Name: destroy_instruction * Purpose: if compiled as shared library, this functions destoys the @@ -57,6 +62,9 @@ void Csubi::evalInstr() void Csubi::execInstr() { cout << "should exec " << this->toString() << endl; + CDat reg = this->m_cpu->getRegister(m_ra) - this->m_imm; + this->m_cpu->setRegister(m_rd, reg); + this->m_cpu->updateFlags(reg); } std::string Csubi::toString() diff --git a/3c_disasm/uint32_from_hex.hpp b/3c_disasm/uint32_from_hex.hpp new file mode 100644 index 0000000..cea3537 --- /dev/null +++ b/3c_disasm/uint32_from_hex.hpp @@ -0,0 +1,19 @@ +#ifndef __UINT32_FROM_HEX_H__ +#define __UINT32_FROM_HEX_H__ + +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; + } +}; + +#endif -- 2.25.1