virtual_machine.cc 2.56 KB
Newer Older
Benoit Perrot's avatar
Benoit Perrot committed
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
//
// This file is part of Nolimips, a MIPS simulator with unlimited registers
// Copyright (C) 2003, 2004 Benoit Perrot <benoit@lrde.epita.fr>
//
// Nolimips is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Nolimips is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#include "vm/virtual_machine.hh"

namespace vm
{

  void
  VirtualMachine::reset()
  {
Benoit Perrot's avatar
Benoit Perrot committed
27
28
29
30
    memory_.reset();
    mmu_.reset();
    cp0_.reset();
    cpu_.reset();
Benoit Perrot's avatar
Benoit Perrot committed
31
32
33
34
35
  }

  void
  VirtualMachine::load_program(const inst::Program &program)
  {
Benoit Perrot's avatar
Benoit Perrot committed
36
37
    reset();

Benoit Perrot's avatar
Benoit Perrot committed
38
39
40
41
42
43
    if (! program.text_section ().has_label(inst::Label("main")))
      {
	std::cerr << "No `main' label in assembly file." << std::endl;
	exit_set(exit_runtime);
	return;
      }
Benoit Perrot's avatar
Benoit Perrot committed
44
    main_offset_ = program.text_section().get_offset(inst::Label("main"));
Benoit Perrot's avatar
Benoit Perrot committed
45
46
47
48
49
50
51
    mmu_.data_store(program.data_section());
    mmu_.inst_store(program.text_section());
  }

  void
  VirtualMachine::execute()
  {
Benoit Perrot's avatar
Benoit Perrot committed
52
53
54
    // FIXME: VirtualMachine::reset()?
    cp0_.reset();
    cpu_.reset();
Benoit Perrot's avatar
Benoit Perrot committed
55

Benoit Perrot's avatar
Benoit Perrot committed
56
57
    // FIXME: precondition on loaded program
    cpu_.set_pc(main_offset_);
Benoit Perrot's avatar
Benoit Perrot committed
58
    while (! (cpu_.get_halt() || cp0_.fatal_exception()))
Benoit Perrot's avatar
Benoit Perrot committed
59
60
61
62
63
64
65
66
67
      {
	cpu_.step();
	cp0_.set_count(cp0_.get_count() + 1);
      }
  }

  void
  VirtualMachine::execute(bool trace_p)
  {
Benoit Perrot's avatar
Benoit Perrot committed
68
69
70
71
    // FIXME: VirtualMachine::reset()?
    cp0_.reset();
    cpu_.reset();

Benoit Perrot's avatar
Benoit Perrot committed
72
73
74
    if (status_ == stop)
      return;

Benoit Perrot's avatar
Benoit Perrot committed
75
    cpu_.set_pc(main_offset_);
Benoit Perrot's avatar
Benoit Perrot committed
76
77
78
79
80
    cpu_.set_trace(trace_p);
    while (status_ == run)
      {
	cpu_.step();
	cp0_.set_count(cp0_.get_count() + 1);
Benoit Perrot's avatar
Benoit Perrot committed
81
	if (cpu_.get_halt() || cp0_.fatal_exception())
Benoit Perrot's avatar
Benoit Perrot committed
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
	  {
	    status_ = halt;
	    std::cerr << "Program exited." << std::endl;
	    break;
	  }
	if (has(breakpoints_, cpu_.get_pc()))
	  {
	    std::cout << "Breakpoint at pc = " << cpu_.get_pc() << std::endl;
	    status_ = pause;
	  }
	if (mode_ == step)
	  status_ = pause;
      }
  }

  void
Benoit Perrot's avatar
Benoit Perrot committed
98
  VirtualMachine::add_breakpoint(int offset)
Benoit Perrot's avatar
Benoit Perrot committed
99
  {
Benoit Perrot's avatar
Benoit Perrot committed
100
    assertion(0 < offset /* && (offset / 4) <= text_section.size() */);
Benoit Perrot's avatar
Benoit Perrot committed
101
102
103
104
105
    breakpoints_.push_back(offset + 4);
  }


} // namespace vm