I've introduced something that seems a bit nasty to me:
class Cpu
{
Cpu(Cp0 &cp0):
cp0_(cp0)
{}
Cp0 &cp0_;
}
class Cpu
{
Cp0(Cpu &cpu):
cpu_(cpu)
{}
Cpu &cpu_;
}
class VirtualMachine
{
VirtualMachine():
cpu_(cp0_),
cp0_(cpu_)
{}
Cpu cpu_;
Cp0 cp0_;
}
So Cpu's constructor is called with a not yet build coprocessor :/
This works well because this constructor requires only the address of
a Cp0. What do you think? Dangerous?
Index: ChangeLog
from Benoît Perrot <benoit(a)lrde.epita.fr>
Control coprocessor has the system library
* src/vm/cp0.hh, src/vm/cp0.hxx:
(set_system_library) New.
(raise_syscall) Invoke system library if any.
* src/vm/cpu.hh, src/vm/cpu.hxx:
(set_system_library) Remove.
* src/vm/cpu.cc:
(syscall) Raise a syscall exception through cp0.
* src/vm/virtual_machine.hh, src/vm/virtual_machine.hxx:
(get_cp0) New non-const accessor.
(set_system_library) Remove.
* src/vm-tasks.cc:
Access cp0 to set system library.
2006-01-08 Benoît Perrot <benoit(a)lrde.epita.fr>
Index: src/vm/cp0.hh
--- src/vm/cp0.hh (revision 211)
+++ src/vm/cp0.hh (working copy)
@@ -21,6 +21,8 @@
#ifndef VM_CP0_HH
# define VM_CP0_HH
+# include "vm/fwd.hh"
+
namespace inst { class Register; }
namespace vm
@@ -94,13 +96,14 @@
/** \name Constructor and destructor
\{ */
public:
- Cp0();
+ Cp0(Cpu &cpu);
/** \} */
public:
/// Reset the CPU (set registers to zero)
void reset();
+ void set_system_library(SystemLibrary *l);
/** \name Explicit register accessors
\{ */
@@ -132,16 +135,22 @@
/// Raise an address error on load exception
void raise_addr_store();
+ void raise_syscall();
+
void set_fatal_exception();
bool fatal_exception() const;
/** \} */
protected:
+ Cpu &cpu_;
+
bool fatal_exception_;
/// Dedicated registers (32 bits)
register_type registers[32];
+
+ SystemLibrary *system_library_;
};
} // namespace vm
Index: src/vm/virtual_machine.hxx
--- src/vm/virtual_machine.hxx (revision 211)
+++ src/vm/virtual_machine.hxx (working copy)
@@ -33,6 +33,7 @@
mode_(mode),
status_(stop),
mmu_(cp0_, memory_),
+ cp0_(cpu_),
cpu_(mmu_, cp0_)
{
}
@@ -46,13 +47,6 @@
}
//
- inline void
- VirtualMachine::set_system_library(SystemLibrary *l)
- {
- cpu_.set_system_library(l);
- }
-
- //
inline const std::vector<register_type> &
VirtualMachine::get_call_stack() const
{
@@ -86,6 +80,11 @@
{
return cp0_;
}
+ inline Cp0 &
+ VirtualMachine::get_cp0()
+ {
+ return cp0_;
+ }
inline const Cpu &
VirtualMachine::get_cpu() const
Index: src/vm/cpu.hh
--- src/vm/cpu.hh (revision 211)
+++ src/vm/cpu.hh (working copy)
@@ -128,8 +128,6 @@
Cp0 &get_cp0();
public:
- void set_system_library(SystemLibrary *l);
-
unsigned get_instruction_counter(inst::Inst::format_type format) const;
const std::vector<register_type> &get_call_stack() const;
@@ -224,8 +222,6 @@
/// Special Program Counter.
register_type pc_;
- SystemLibrary *system_library_;
-
/// Unlimited registers.
misc::Table<int, register_type> unlimited_;
Index: src/vm/cp0.hxx
--- src/vm/cp0.hxx (revision 211)
+++ src/vm/cp0.hxx (working copy)
@@ -20,6 +20,7 @@
# define VM_CP0_HXX
# include "vm/cp0.hh"
+# include "vm/system_library.hh"
# include "inst/register.hh"
@@ -30,7 +31,9 @@
//
inline
- Cp0::Cp0()
+ Cp0::Cp0(Cpu &cpu):
+ cpu_(cpu),
+ system_library_(0)
{
reset();
}
@@ -45,6 +48,12 @@
fatal_exception_ = false;
}
+ inline void
+ Cp0::set_system_library(SystemLibrary *l)
+ {
+ system_library_ = l;
+ }
+
//
inline void
Cp0::set_count(Cp0::register_type r)
@@ -99,6 +108,13 @@
fatal_exception_ = true;
}
+ inline void
+ Cp0::raise_syscall()
+ {
+ precondition(system_library_);
+ system_library_->invoke(cpu_);
+ }
+
//
inline void
Cp0::set_fatal_exception()
Index: src/vm/cpu.hxx
--- src/vm/cpu.hxx (revision 211)
+++ src/vm/cpu.hxx (working copy)
@@ -141,12 +141,6 @@
return cp0_;
}
- inline void
- Cpu::set_system_library(SystemLibrary *l)
- {
- system_library_ = l;
- }
-
//
inline void
Cpu::call()
Index: src/vm/virtual_machine.hh
--- src/vm/virtual_machine.hh (revision 211)
+++ src/vm/virtual_machine.hh (working copy)
@@ -69,8 +69,6 @@
/// Load a program into memory.
void load_program(const inst::Program &program);
- void set_system_library(SystemLibrary *l);
-
public:
/// Execute a program.
void execute();
@@ -98,6 +96,7 @@
status_type get_status() const;
const Cp0 &get_cp0() const;
+ Cp0 &get_cp0();
const Cpu &get_cpu() const;
Cpu &get_cpu();
Index: src/vm/cpu.cc
--- src/vm/cpu.cc (revision 211)
+++ src/vm/cpu.cc (working copy)
@@ -20,7 +20,6 @@
#include "vm/cpu.hh"
#include "vm/cp0.hh"
-#include "vm/system_library.hh"
#include "inst/all.hh"
#include "inst/int_exp.hh"
@@ -33,7 +32,6 @@
// --------------------------------------------------------------------------
Cpu::Cpu(Mmu &mmu, Cp0 &cp0):
mmu_(mmu), cp0_(cp0),
- system_library_(0),
check_callee_save_p_(false),
trace_p_(false),
bubble_(new inst::Sll(inst::Register(inst::Register::general, Cpu::zero),
@@ -684,8 +682,7 @@
void
Cpu::visit(const inst::Syscall&)
{
- precondition(system_library_);
- system_library_->invoke(*this);
+ cp0_.raise_syscall();
}
} // namespace vm
Index: src/vm-tasks.cc
--- src/vm-tasks.cc (revision 211)
+++ src/vm-tasks.cc (working copy)
@@ -72,7 +72,7 @@
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(system_library);
+ vm.get_cp0().set_system_library(system_library);
vm.load_program(* parse::tasks::program);
if (exit_status != exit_success)
exit(exit_status);