#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(); }