sim: brr fix, interrupt
[calu.git] / 3c_disasm / instr / branchreg.cpp
1 #include "../Iinstr.hpp"
2
3 class Cbranchreg : public Iinstr {
4         private:
5                 bool m_taken;
6                 char m_typ;
7         public:
8                 Cbranchreg();
9                 void evalInstr();
10                 void execInstr();
11                 std::string toString();
12                 Iinstr* getNew();
13 };
14
15 /**
16  * Name:      create_instruction
17  * Purpose:   if compiled as shared library, this functions creates the 
18               instruction object
19
20  * Returns:   pointer to instruction object
21  */
22 extern "C" Iinstr* create_instruction() {
23     return new Cbranchreg();
24 }
25
26 Iinstr* Cbranchreg::getNew()
27 {
28         return new Cbranchreg();
29 }
30 /**
31  * Name:      destroy_instruction
32  * Purpose:   if compiled as shared library, this functions destoys the 
33               instruction object
34
35  * Parameter: IInstruction - the instruction object to delete
36  */
37 extern "C" void destroy_instruction(Iinstr* p) {
38     delete p;
39 }
40
41 Cbranchreg::Cbranchreg() : m_taken(1), m_typ(0)
42 {
43         opcode = B5(10111);
44         name = "branchreg";
45 }
46
47 void Cbranchreg::evalInstr()
48 {
49         argbits >>= 2;
50
51         dynamic_bitset<> type = argbits;
52         type.resize(1);
53         this->m_typ = type.to_ulong();
54
55         switch(this->m_typ) {
56                 case 0:
57                         this->name = "brr";
58                         break;
59                 case 1:
60                         this->name = "callr";
61                         break;
62                 default:
63                         cerr << "What have you done? 1 bits that have more than 2 values?!" << endl;
64         }
65
66         argbits >>= 17;
67         m_rd = this->getRegister(argbits);
68 }
69
70 void Cbranchreg::execInstr()
71 {
72         //cout << "should exec " << this->toString() << endl;
73         CDat pc = this->m_cpu->getRegister(this->m_rd);
74         pc *= 4; //komisch fix?
75
76         if(this->m_typ == 1) {
77                 CDat sp = this->m_cpu->getStack();
78                 sp -= 4;
79                 this->m_cpu->setRAM(sp, this->m_cpu->getNextPC());
80                 this->m_cpu->setStack(sp);
81         }
82         this->m_cpu->setNextPC(pc);
83 }
84
85 std::string Cbranchreg::toString()
86 {
87         stringstream op;
88         op << this->getName();
89
90         op << this->getConditionFlag();
91         op << " r" << m_rd;
92         return op.str();
93 }