From 91f67630701b9c4e2d369b5ce8761c13d1a73eb8 Mon Sep 17 00:00:00 2001 From: Martin Perner Date: Mon, 1 Nov 2010 22:28:14 +0100 Subject: [PATCH] sim: added shift not extensiv tested --- 3a_asm/tst/shift.s | 9 +++ 3b_sim/ccpu.cpp | 10 +++ 3b_sim/ccpu.hpp | 5 +- 3c_disasm/instr/shift.cpp | 151 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 3a_asm/tst/shift.s create mode 100644 3c_disasm/instr/shift.cpp diff --git a/3a_asm/tst/shift.s b/3a_asm/tst/shift.s new file mode 100644 index 0000000..86f61e9 --- /dev/null +++ b/3a_asm/tst/shift.s @@ -0,0 +1,9 @@ +ldis r0, 1 +lls r0, r0, 1 +llsc r0, r0, 1 +lls r1, r0, 29 +lls r1, r1, 1 +llsc r0, r0, 30 +lrsc r2, r2, 5 +ars r2, r2, 5 +ars r1, r1, 5 diff --git a/3b_sim/ccpu.cpp b/3b_sim/ccpu.cpp index 4974fcc..fb480f4 100644 --- a/3b_sim/ccpu.cpp +++ b/3b_sim/ccpu.cpp @@ -124,6 +124,16 @@ void CCpu::updateFlags(CDatd val, CDat a, CDat b) { this->m_O = (this->m_S != v); } +void CCpu::updateCarry(bool c) +{ + this->m_C = c; +} + +bool CCpu::getCarry() +{ + return this->m_C; +} + void CCpu::updateFlags(bool z, bool o, bool c, bool s) { this->m_Z = z; diff --git a/3b_sim/ccpu.hpp b/3b_sim/ccpu.hpp index 24f6f31..0dd8b1b 100644 --- a/3b_sim/ccpu.hpp +++ b/3b_sim/ccpu.hpp @@ -45,7 +45,10 @@ class CCpu { void updateFlags(CDatd, CDat, CDat); /* will change all flags */ void updateFlags(bool z, bool o, bool c, bool s); - + /* will change carry */ + void updateCarry(bool c); + + bool getCarry(); bool conditionMet(short); diff --git a/3c_disasm/instr/shift.cpp b/3c_disasm/instr/shift.cpp new file mode 100644 index 0000000..e5a5245 --- /dev/null +++ b/3c_disasm/instr/shift.cpp @@ -0,0 +1,151 @@ +#include "../Iinstr.hpp" + +class Cshift : public Iinstr { + char m_typ; + public: + Cshift(); + 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 Cshift(); +} + +Iinstr* Cshift::getNew() +{ + return new Cshift(); +} +/** + * 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; +} + +Cshift::Cshift() : m_typ(0) +{ + opcode = B5(01010); + name = "shift"; +} + +void Cshift::evalInstr() +{ + this->m_d = argbits[0]; + this->m_c = argbits[1]; + argbits >>= 2; + + dynamic_bitset<> type = argbits; + type.resize(2); + this->m_typ = type.to_ulong(); + + switch(this->m_typ) { + case 1: + cerr << "INVALID shift type, using logic left shift!" << endl; + this->m_typ = 0; + case 0: + this->name = "lls"; + break; + case 2: + this->name = "lrs"; + break; + case 3: + this->name = "ars"; + break; + default: + cerr << "What have you done? 2 bits that have more than 4 values?!" << endl; + } + + argbits >>= 8; + dynamic_bitset<> immb = argbits; + immb.resize(5); + this->m_imm = immb.to_ulong(); + argbits >>= 5; + m_ra = this->getRegister(argbits); + argbits >>= 4; + m_rd = this->getRegister(argbits); +} + +void Cshift::execInstr() +{ + CDatd val = this->m_cpu->getRegister(m_ra); + switch(this->m_typ) { + case 0: + case 1: +// this->name = "lls"; + for(unsigned int i = 0; i < m_imm; i++) { + val = val << 1; + } + //carry + if(m_c) { + this->m_cpu->updateCarry(((val >> BIT_LEN) & 0x1) != 0); + } + break; + case 2: +// this->name = "lrs"; + { + bool carry = this->m_cpu->getCarry(); + for(unsigned int i = 0; i < m_imm; i++) { + val = val >> 1; + + //carry! + //if user wants carry, and carry is set + if(this->m_c && carry) { + //set highest bit 1 + val |= (CDat)(1<<(BIT_LEN-1)); + } + else { + //set highest bit 0 + val &= (~(1<<(BIT_LEN-1))); + } + } + } + break; + case 3: +// this->name = "ars"; + //>> is a ars, but val is CDatd => we have to set the MSB manually + { + bool msb = (val & (1<<(BIT_LEN-1)) >> (BIT_LEN-1)); + for(unsigned int i = 0; i < m_imm; i++) { + val = val >> 1; + if(msb) { + //set highest bit 1 + val |= (CDat)(1<<(BIT_LEN-1)); + } + else { + //set highest bit 0 + val &= (~(1<<(BIT_LEN-1))); + } + } + } + break; + default: + cerr << "What have you done? 2 bits that have more than 4 values?!" << endl; + } + this->m_cpu->setRegister(m_rd, val); +} + +std::string Cshift::toString() +{ + stringstream op; + op << this->getName(); + if(m_c) op << "C"; + if(m_d) op << "D"; + + op << this->getConditionFlag(); + op << " r" << m_rd << ", r" << m_ra << ", " << m_imm; + return op.str(); +} -- 2.25.1