From 79a8ce96e5f987dfc89f3e8bdd262a9d78f50ed6 Mon Sep 17 00:00:00 2001 From: Martin Perner Date: Wed, 3 Nov 2010 19:43:57 +0100 Subject: [PATCH] sim: added [st|ld]x --- 3b_sim/.gitignore | 1 + 3b_sim/sim.cpp | 5 ++- 3c_disasm/Iinstr.hpp | 24 +++++++++++-- 3c_disasm/dasm.cpp | 1 + 3c_disasm/disasm.cpp | 7 +++- 3c_disasm/disasm.h | 8 +++++ 3c_disasm/instr/ldx.cpp | 77 +++++++++++++++++++++++++++++++++++++++++ 3c_disasm/instr/stx.cpp | 77 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 195 insertions(+), 5 deletions(-) create mode 100644 3c_disasm/instr/ldx.cpp create mode 100644 3c_disasm/instr/stx.cpp diff --git a/3b_sim/.gitignore b/3b_sim/.gitignore index 6eedf3a..e260184 100644 --- a/3b_sim/.gitignore +++ b/3b_sim/.gitignore @@ -1,4 +1,5 @@ *.o *.so *.d +*.dthex sim diff --git a/3b_sim/sim.cpp b/3b_sim/sim.cpp index 0343ede..1fd3834 100644 --- a/3b_sim/sim.cpp +++ b/3b_sim/sim.cpp @@ -68,6 +68,7 @@ class CHelpExec void close_prog(const std::vector &); CCpu* Iinstr::m_cpu; +disasm* Iinstr::m_disasm; CCpu* global_cpu = NULL; @@ -480,12 +481,14 @@ int main(int argc, char* argv[]) Iinstr::setCPU(&cpu); + disasm disasm(instr); + + Iinstr::setDisasm(&disasm); std::string str = ""; int addr = 0; 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); diff --git a/3c_disasm/Iinstr.hpp b/3c_disasm/Iinstr.hpp index d94c88f..2cc17df 100644 --- a/3c_disasm/Iinstr.hpp +++ b/3c_disasm/Iinstr.hpp @@ -10,6 +10,10 @@ class CCpu; #include "ccpu.hpp" +class disasm; + +#include "disasm.h" + /* concept from https://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f */ #define to_HEX__(x) 0x##x##LU @@ -54,7 +58,8 @@ class Iinstr { CDat 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) {} + CDat hexdump; + 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), hexdump(0) {} CDat generate16ImmFill(const CDat value) const { CDat i = value; @@ -114,20 +119,24 @@ class Iinstr { } static CCpu* m_cpu; + static disasm* m_disasm; public: static void setCPU(CCpu* cpu) { m_cpu = cpu; } + static void setDisasm(disasm* dasm) { m_disasm = dasm; } 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 loadBits(boost::dynamic_bitset<> bits) { argbits = bits; this->constructHex(); } virtual void evalInstr() = 0; virtual void execInstr() = 0; virtual std::string toString() = 0; virtual Iinstr* getNew() = 0; - + + unsigned long toNum() { return this->hexdump; } + short getCondition() { return m_cond; } @@ -143,6 +152,15 @@ class Iinstr { protected: + void constructHex() + { + hexdump = this->m_cond; + hexdump <<= 5; + hexdump += this->opcode; + hexdump <<= 23; + hexdump += this->argbits.to_ulong(); + } + std::string getConditionFlag() { stringstream cond; diff --git a/3c_disasm/dasm.cpp b/3c_disasm/dasm.cpp index a11d4f5..2546441 100644 --- a/3c_disasm/dasm.cpp +++ b/3c_disasm/dasm.cpp @@ -22,6 +22,7 @@ std::string progName; CCpu* Iinstr::m_cpu; +disasm* Iinstr::m_disasm; int main(int argc, char* argv[]) { diff --git a/3c_disasm/disasm.cpp b/3c_disasm/disasm.cpp index 0c6c5f0..c117bb0 100644 --- a/3c_disasm/disasm.cpp +++ b/3c_disasm/disasm.cpp @@ -10,8 +10,13 @@ Iinstr* disasm::decode(std::string str) string hex = "0x"; hex.append(str); - unsigned int val = lexical_cast(hex); + CDat val = lexical_cast(hex); + return this->decodeNum(val); +} + +Iinstr* disasm::decodeNum(CDat val) +{ dynamic_bitset<> bits(32,val), opcode(32,val), condition(9), args(32); args = opcode; diff --git a/3c_disasm/disasm.h b/3c_disasm/disasm.h index 078bd17..403e38d 100644 --- a/3c_disasm/disasm.h +++ b/3c_disasm/disasm.h @@ -1,8 +1,14 @@ +#ifndef __DISASM_H__ +#define __DISASM_H__ + #include #include #include #include "uint32_from_hex.hpp" + +class Iinstr; + #include "Iinstr.hpp" using namespace std; @@ -18,6 +24,8 @@ class disasm { public: disasm(std::map map) : instrs(map) {}; Iinstr* decode(std::string); + Iinstr* decodeNum(CDat); std::string decodeToString(std::string str); }; +#endif diff --git a/3c_disasm/instr/ldx.cpp b/3c_disasm/instr/ldx.cpp new file mode 100644 index 0000000..b978bd5 --- /dev/null +++ b/3c_disasm/instr/ldx.cpp @@ -0,0 +1,77 @@ +#include "../Iinstr.hpp" + + +class Cldx : public Iinstr { + public: + Cldx(); + void evalInstr(); + void execInstr(); + std::string toString(); + Iinstr* getNew(); +}; + +/** + * 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 Cldx(); +} + +Iinstr* Cldx::getNew() +{ + return new Cldx(); +} + +/** + * 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; +} + +Cldx::Cldx() +{ + opcode = B5(10100); + name = "ldx"; +} + +void Cldx::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 Cldx::execInstr() +{ + //cout << "should exec " << this->toString() << endl; + CDat val = this->m_cpu->getRegister(this->m_ra); + val += m_imm; + this->m_cpu->setRegister(this->m_rd, this->m_cpu->getProg(val)->toNum()); +} + +std::string Cldx::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/stx.cpp b/3c_disasm/instr/stx.cpp new file mode 100644 index 0000000..9f5058e --- /dev/null +++ b/3c_disasm/instr/stx.cpp @@ -0,0 +1,77 @@ +#include "../Iinstr.hpp" + + +class Cstx : public Iinstr { + public: + Cstx(); + void evalInstr(); + void execInstr(); + std::string toString(); + Iinstr* getNew(); +}; + +/** + * 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 Cstx(); +} + +Iinstr* Cstx::getNew() +{ + return new Cstx(); +} + +/** + * 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; +} + +Cstx::Cstx() +{ + opcode = B5(10101); + name = "stx"; +} + +void Cstx::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 Cstx::execInstr() +{ + //cout << "should exec " << this->toString() << endl; + CDat val = this->m_cpu->getRegister(this->m_ra); + val += m_imm; + this->m_cpu->setProg(val, m_disasm->decodeNum(this->m_cpu->getRegister(this->m_rd))); +} + +std::string Cstx::toString() +{ + stringstream op; + op << this->getName(); + + op << this->getConditionFlag() << " r" << m_rd << ", " << m_imm << "(r" << m_ra << ")"; + + return op.str(); +} -- 2.25.1