Commit 902282e4 authored by Benoit Perrot's avatar Benoit Perrot
Browse files

2005-09-24 Benoît Perrot <benoit@lrde.epita.fr>

	Introduce system libraries.

	* src/vm/cpu.hh, src/vm/cpu.cc:
	Export mmu and cp0. Move syscalls' implementation to...
	* src/vm/system_library.hh, src/vm/system_library.cc,
	* src/vm/spim_system_library.hh, src/vm/spim_system_library.hxx,
	* src/vm/spim_system_library.cc:
	These new files.
	* src/vm/cp0.hh: Export fatal_exception flag.
	* src/vm/Makefile.am: Update accordingly.
	* src/vm/virtual_machine.hh, src/vm/virtual_machine.cc:
	Propagate system library to cpu.
	* src/vm-tasks.cc: 
	Give a default system library to virtual machine.
parent b45ed049
2005-09-24 Benot Perrot <benoit@lrde.epita.fr>
Introduce system libraries.
* src/vm/cpu.hh, src/vm/cpu.cc:
Export mmu and cp0. Move syscalls' implementation to...
* src/vm/system_library.hh, src/vm/system_library.cc,
* src/vm/spim_system_library.hh, src/vm/spim_system_library.hxx,
* src/vm/spim_system_library.cc:
These new files.
* src/vm/cp0.hh: Export fatal_exception flag.
* src/vm/Makefile.am: Update accordingly.
* src/vm/virtual_machine.hh, src/vm/virtual_machine.cc:
Propagate system library to cpu.
* src/vm-tasks.cc:
Give a default system library to virtual machine.
2005-09-17 Benot Perrot <benoit@lrde.epita.fr>
--argument-registers
......
......@@ -18,6 +18,7 @@
//
#include "common.hh"
#include "vm/spim_system_library.hh"
#include "vm/virtual_machine.hh"
#include "parse-tasks.hh"
......@@ -33,9 +34,11 @@ namespace vm
void
execute ()
{
vm::SpimSystemLibrary l(std::cin, std::cout);
vm::VirtualMachine vm;
vm.get_cpu().set_check_callee_save(check_callee_save_p);
vm.get_cpu().set_trace(trace_exec_p);
vm.set_system_library(&l);
vm.load_program(* parse::tasks::program);
if (exit_status != exit_success)
exit(exit_status);
......
noinst_LIBRARIES = libvm.a
libvm_a_CPPFLAGS = -I $(top_srcdir)/lib -I $(top_srcdir)/src -I $(top_builddir)/src
libvm_a_SOURCES = \
mmu.hh \
cp0.hh \
cpu.hh cpu.cc \
segment.hh \
memory.hh \
libvm_a_SOURCES = \
mmu.hh \
cp0.hh \
cpu.hh cpu.cc \
segment.hh \
memory.hh \
system_library.hh system_library.cc \
spim_system_library.hh spim_system_library.hxx \
spim_system_library.cc \
virtual_machine.hh virtual_machine.cc
......@@ -165,7 +165,12 @@ namespace vm
exit_set(exit_runtime);
}
bool fatal_exception() const
void set_fatal_exception()
{
fatal_exception_ = true;
}
bool fatal_exception() const
{
return fatal_exception_;
}
......
......@@ -21,6 +21,7 @@
#include "common.hh"
#include "vm/cpu.hh"
#include "vm/system_library.hh"
#include "inst/all.hh"
#include "inst/int_exp.hh"
......@@ -31,12 +32,9 @@ namespace vm
// --------------------------------------------------------------------------
// Constructor and destructor
// --------------------------------------------------------------------------
Cpu::Cpu(Mmu& mmu,
Cp0 &cp0,
std::istream& istr,
std::ostream& ostr):
Cpu::Cpu(Mmu &mmu, Cp0 &cp0):
mmu_(mmu), cp0_(cp0),
istr_(istr), ostr_(ostr),
system_library_(0),
check_callee_save_p_(false),
trace_p_(false),
bubble_(new inst::Sll(inst::Register(inst::Register::general, Cpu::zero),
......@@ -57,8 +55,6 @@ namespace vm
void
Cpu::reset()
{
halt_ = false;
// Initialize general purpose registers to 0.
for (unsigned i = 0; i < 32; ++i)
GPR_[i] = 0;
......@@ -689,68 +685,8 @@ namespace vm
void
Cpu::visit(const inst::Syscall&)
{
switch (get_register(Cpu::v0))
{
// print_int (integer: $a0)
case 1:
ostr_ << get_register(Cpu::a0);
break;
// print_string (buffer: $a0)
case 4:
for (int i = get_register(Cpu::a0); true; ++i)
{
char b = mmu_.data_load_byte(i);
if (b == 0)
break;
ostr_ << b;
}
break;
// read_string (buffer: $a0, length: $a1)
case 8:
{
int i = 0;
int c = 0;
for (; (i < get_register(Cpu::a1) - 1) && (c != '\n') && (c != '\r');
++i)
{
c = istr_.get();
if (istr_.eof())
break;
mmu_.data_store_byte(get_register(Cpu::a0) + i, c);
}
mmu_.data_store_byte(get_register(Cpu::a0) + i, 0);
}
break;
// sbrk (size: $a0)
case 9:
set_register(Cpu::v0, mmu_.data_sbrk(get_register(Cpu::a0)));
break;
// exit (status : $a0)
case 10:
halt_ = true;
if (!exit_status)
exit_status = (exit_type) get_register(Cpu::a0);
break;
// print_err (buffer: $a0)
case 15:
for (int i = get_register(Cpu::a0); true; ++i)
{
char b = mmu_.data_load_byte(i);
if (b == 0)
break;
std::cerr << b;
}
break;
default:
assertion(!"syscall: Not implemented yet");
};
ostr_.flush();
precondition(system_library_);
system_library_->invoke(*this);
}
} // namespace vm
......@@ -34,13 +34,15 @@
# include "inst/program.hh"
# include "vm/mmu.hh"
# include "vm/cp0.hh"
namespace vm
{
typedef int32_t register_type;
typedef uint32_t uregister_type;
class Cp0;
class SystemLibrary;
/// Central Processor Unit abstraction
class Cpu:
......@@ -68,10 +70,7 @@ namespace vm
\{ */
public:
/// Construct a CPU.
Cpu(Mmu& mmu,
Cp0 &cp0,
std::istream& istr,
std::ostream& ostr);
Cpu(Mmu &mmu, Cp0 &cp0);
/// Destroy a CPU.
virtual ~Cpu();
/** \} */
......@@ -178,6 +177,11 @@ namespace vm
return counters_[format];
}
Mmu &get_mmu() { return mmu_; }
Cp0 &get_cp0() { return cp0_; }
void set_system_library(SystemLibrary *l) { system_library_ = l; }
protected:
virtual void visit(const inst::Add& add);
virtual void visit(const inst::Addi& addi);
......@@ -244,7 +248,7 @@ namespace vm
protected:
/// Memory management unit link.
Mmu& mmu_;
Mmu &mmu_;
/// Control coprocessor link.
Cp0 &cp0_;
......@@ -260,15 +264,7 @@ namespace vm
/// Unlimited registers.
misc::Table<int, register_type> unlimited_;
public:
bool get_halt() const { return halt_; }
protected:
bool halt_;
std::istream& istr_;
std::ostream& ostr_;
SystemLibrary *system_library_;
protected:
void call()
......
//
// This file is part of Nolimips, a MIPS simulator with unlimited registers
// Copyright (C) 2005 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 "common.hh"
#include "vm/spim_system_library.hh"
#include "vm/cpu.hh"
#include "vm/mmu.hh"
namespace vm
{
SpimSystemLibrary::~SpimSystemLibrary()
{}
void
SpimSystemLibrary::invoke(Cpu &cpu)
{
Mmu &mmu = cpu.get_mmu();
switch (cpu.get_register(Cpu::v0))
{
// print_int (integer: $a0)
case 1:
ostr_ << cpu.get_register(Cpu::a0);
break;
// print_string (buffer: $a0)
case 4:
for (int i = cpu.get_register(Cpu::a0); true; ++i)
{
char b = mmu.data_load_byte(i);
if (b == 0)
break;
ostr_ << b;
}
break;
// read_string (buffer: $a0, length: $a1)
case 8:
{
int i = 0;
int c = 0;
for (; (i < cpu.get_register(Cpu::a1) - 1)
&& (c != '\n') && (c != '\r');
++i)
{
c = istr_.get();
if (istr_.eof())
break;
mmu.data_store_byte(cpu.get_register(Cpu::a0) + i, c);
}
mmu.data_store_byte(cpu.get_register(Cpu::a0) + i, 0);
}
break;
// sbrk (size: $a0)
case 9:
cpu.set_register(Cpu::v0, mmu.data_sbrk(cpu.get_register(Cpu::a0)));
break;
// exit (status : $a0)
case 10:
{
cpu.get_cp0().set_fatal_exception();
if (!exit_status)
exit_status = (exit_type) cpu.get_register(Cpu::a0);
}
break;
// print_err (buffer: $a0)
case 15:
for (int i = cpu.get_register(Cpu::a0); true; ++i)
{
char b = mmu.data_load_byte(i);
if (b == 0)
break;
std::cerr << b;
}
break;
default:
assertion(!"syscall: Not implemented yet");
};
ostr_.flush();
}
} // namespace vm
//
// This file is part of Nolimips, a MIPS simulator with unlimited registers
// Copyright (C) 2005 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
//
#ifndef VM_SPIM_SYSTEM_LIBRARY_HH
# define VM_SPIM_SYSTEM_LIBRARY_HH
# include <iostream>
# include "vm/system_library.hh"
namespace vm
{
class SpimSystemLibrary: public SystemLibrary
{
public:
SpimSystemLibrary(std::istream &istr, std::ostream &ostr);
virtual ~SpimSystemLibrary();
public:
virtual void invoke(Cpu &cpu);
protected:
std::istream &istr_;
std::ostream &ostr_;
};
} // namespace vm
# include "vm/spim_system_library.hxx"
#endif // !VM_SPIM_SYSTEM_LIBRARY_HH
//
// This file is part of Nolimips, a MIPS simulator with unlimited registers
// Copyright (C) 2005 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
//
#ifndef VM_SPIM_SYSTEM_LIBRARY_HXX
# define VM_SPIM_SYSTEM_LIBRARY_HXX
# include "vm/spim_system_library.hh"
namespace vm
{
inline
SpimSystemLibrary::SpimSystemLibrary(std::istream &istr,
std::ostream &ostr):
istr_(istr), ostr_(ostr)
{}
} // namespace vm
#endif // !VM_SPIM_SYSTEM_LIBRARY_HH
//
// This file is part of Nolimips, a MIPS simulator with unlimited registers
// Copyright (C) 2005 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/system_library.hh"
namespace vm
{
SystemLibrary::~SystemLibrary()
{}
} // namespace vm
//
// This file is part of Nolimips, a MIPS simulator with unlimited registers
// Copyright (C) 2005 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
//
#ifndef VM_SYSTEM_LIBRARY_HH
# define VM_SYSTEM_LIBRARY_HH
namespace vm
{
class Cpu;
class SystemLibrary
{
public:
SystemLibrary()
{}
virtual ~SystemLibrary();
public:
virtual void invoke(Cpu &cpu) = 0;
};
} // namespace vm
#endif // !VM_SYSTEM_LIBRARY_HH
......@@ -56,7 +56,7 @@ namespace vm
// FIXME: precondition on loaded program
cpu_.set_pc(main_offset_);
while (! (cpu_.get_halt() || cp0_.fatal_exception()))
while (!cp0_.fatal_exception())
{
cpu_.step();
cp0_.set_count(cp0_.get_count() + 1);
......@@ -79,7 +79,7 @@ namespace vm
{
cpu_.step();
cp0_.set_count(cp0_.get_count() + 1);
if (cpu_.get_halt() || cp0_.fatal_exception())
if (cp0_.fatal_exception())
{
status_ = halt;
std::cerr << "Program exited." << std::endl;
......
......@@ -36,6 +36,7 @@
namespace vm
{
class SystemLibrary;
/// Virtual Machine abstraction
class VirtualMachine
......@@ -58,13 +59,11 @@ namespace vm
/** \name Constructor and destructor.
\{ */
public:
VirtualMachine(mode_type mode = normal,
std::istream& istr = std::cin,
std::ostream& ostr = std::cout):
VirtualMachine(mode_type mode = normal):
mode_(mode),
status_(stop),
mmu_(cp0_, memory_),
cpu_(mmu_, cp0_, istr, ostr)
cpu_(mmu_, cp0_)
{
}
/** \} */
......@@ -84,6 +83,9 @@ namespace vm
public:
/// Load a program into memory.
void load_program(const inst::Program& program);
void set_system_library(SystemLibrary *l) { cpu_.set_system_library(l); }
protected:
int main_offset_; // FIXME: Must disappear!
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment