virtual_machine.hh 3.14 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef VM_VIRTUAL_MACHINE_HH
# define VM_VIRTUAL_MACHINE_HH

# include "misc/contract.hh"

# include "inst/program.hh"
# include "inst/visitor.hh"

# include "vm/cpu.hh"
# include "vm/memory.hh"

namespace vm
{
  
  class VirtualMachine:
    protected inst::ConstVisitor
  {
  public:
    VirtualMachine()
    {
      _program = 0;
    }


  public:
    void		load_program(inst::Program& program)
    {
      _program = &program;
      _memory.store(program.data_section());
    }

  public:
    void		execute(bool trace = false)
    {
      precondition(_program);

      const inst::TextSection& text_section = (*_program).text_section ();
      cpu.set_pc(text_section.get_offset(inst::Label("main")));

      _halt = false;
      while (!_halt)
	{
	  const inst::Inst&	ri = text_section[cpu.get_pc() / 4];
	  cpu.set_pc(cpu.get_pc() + 4);

	  if (trace)
	    std::cout << ri << std::endl;
	  ri.accept(*this);
	}
    }

  protected:
    virtual void	visit(const inst::Add& add);
    virtual void	visit(const inst::Addi& addi);
    virtual void	visit(const inst::Addu& addu);
    virtual void	visit(const inst::Addiu& addiu);
    virtual void	visit(const inst::Sub& sub);
    virtual void	visit(const inst::Subu& subu);

    virtual void	visit(const inst::Sll& sll);
    virtual void	visit(const inst::Slv& slv);

    virtual void	visit(const inst::Mul& mul);
    virtual void	visit(const inst::Div& div);
    virtual void	visit(const inst::Divu& divu);
    virtual void	visit(const inst::Remu& remu);

    virtual void	visit(const inst::Lb& lb);
    virtual void	visit(const inst::Lbu& Lbu);
    virtual void	visit(const inst::Lw& lw);
    virtual void	visit(const inst::Li& li);
    virtual void	visit(const inst::Sb& sb);
    virtual void	visit(const inst::Sw& sw);

    virtual void	visit(const inst::And& _and);
    virtual void	visit(const inst::Andi& andi);
    virtual void	visit(const inst::Or& _or);
    virtual void	visit(const inst::Ori& ori);
    virtual void	visit(const inst::Nor& nor);
    virtual void	visit(const inst::Xor& _xor);
    virtual void	visit(const inst::Xori& xori);

    virtual void	visit(const inst::Slt& slt);
    virtual void	visit(const inst::Slti& slti);
    virtual void	visit(const inst::Sltu&);
    virtual void	visit(const inst::Sltiu& sltiu);

    virtual void	visit(const inst::Jmp& jmp);
    virtual void	visit(const inst::Jr& jr);
    virtual void	visit(const inst::Jal& jal);
    virtual void	visit(const inst::Jalr& jalr);

    virtual void	visit(const inst::Beq& beq);
    virtual void	visit(const inst::Bne& bne);

    virtual void	visit(const inst::Bgez& bgez);
    virtual void	visit(const inst::Bgezal& bgezal);
    virtual void	visit(const inst::Bgtz& bgtz);

    virtual void	visit(const inst::Blez& blez);
    virtual void	visit(const inst::Bltz& bltz);
    virtual void	visit(const inst::Bltzal& bltzal);

    virtual void	visit(const inst::Syscall& sycall);

  protected:
    void		begin_scope()
    {
      cpu.begin_scope();
    }
    void		end_scope()
    {
      cpu.end_scope();
    }

  protected:
    bool		_halt;
  protected:
    Cpu			cpu;

    inst::Program*	_program;
    Memory		_memory;
  };

} // namespace vm

#endif // !VM_VIRTUAL_MACHINE_HH