
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@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@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);