Commit 3b12f953 authored by Benoit Perrot's avatar Benoit Perrot
Browse files

Index: ChangeLog

from  Benoît Perrot  <benoit@lrde.epita.fr>
        * src/vm/cp0.hh:
        Add control coprocessor.
        * src/vm/Makefile.am:
        Distribute it.
        * src/vm/cpu.hh, src/vm/cpu.cc,
        * src/vm/virtual_machine.hh:
        Use control coprocessor.
        * dev/mipsy.py,
        * dev/mipsy.xml:
        Add instructions to move registers to/from control coprocessor.
        * dev/inst-solver-gen.py,
        Check register identifiers for control coprocessor instructions.
parent a89344a0
2004-04-05 Benot Perrot <benoit@lrde.epita.fr>
* src/vm/cp0.hh:
Add control coprocessor.
* src/vm/Makefile.am:
Distribute it.
* src/vm/cpu.hh, src/vm/cpu.cc,
* src/vm/virtual_machine.hh:
Use control coprocessor.
* dev/mipsy.py,
* dev/mipsy.xml:
Add instructions to move registers to/from control coprocessor.
* dev/inst-solver-gen.py,
Check register identifiers for control coprocessor instructions.
2004-04-05 Benot Perrot <benoit@lrde.epita.fr>
* dev/inst-solver-gen.py,
......
-*- text -*-
New in 0.6:
* The virtual machine now includes a control coprocessor.
For the moment, only mfc0 and mtc0 instructions are supported, and the
count register ($9) is functional.
* The scanner now supports explicit and generic register identifiers.
The statement:
addi $t0, $t1, 2097
is equivalent to:
addi $8, $9, 2097
New in 0.5:
New in 0.5, 2004-01-12:
* The virtual machine now supports delay slot.
The statement:
jal exit
......
......@@ -210,8 +210,11 @@ for inst in instructions:
content = content + " solve_exp(" + \
var_id + ".get_" + attribute.name + "());\n"
elif attribute.type == "Register":
content = content + " solve_cpu_register(" + \
var_id + ".get_" + attribute.name + "());"
if attribute.restriction == "generic":
content = content + " solve_cop_register("
else:
content = content + " solve_cpu_register("
content = content + var_id + ".get_" + attribute.name + "());\n"
print " void"
if content != "":
......
......@@ -75,7 +75,7 @@ def class_id(s):
res = ""
non_ascii = True
for i in range(0, len(s)):
if s[i] in string.ascii_letters:
if s[i] in string.ascii_letters or s[i] in string.digits:
if non_ascii:
res = res + string.upper(s[i])
non_ascii = False
......@@ -98,22 +98,26 @@ def var_id(s):
## -------------------------------------
class Attribute:
def __init__(self, type, name, value):
def __init__(self, type, restriction, name, value):
self.type = type
self.restriction = restriction
self.name = name
self.value = value # FIXME: useless
def __str__(self):
return "<attribute type=\"" + self.type + "\" name=\"" + self.name +"\" />"
return "<attribute type=\"" + self.type + \
"\" restriction=\"" + self.restriction + \
"\" name=\"" + self.name +"\" />"
class AttributeBuilder:
def reset(self):
self.type = ""
self.restriction = ""
self.name = ""
self.value = ""# FIXME: useless
def __init__(self):
self.reset()
def get(self):
assert(self.type != "" and self.name != "")
return Attribute(self.type, self.name, self.value)
return Attribute(self.type, self.restriction, self.name, self.value)
class Format:
def __init__(self, attributes):
......@@ -244,6 +248,8 @@ class InstructionSetHandler(ContentHandler):
elif name == "attribute":
self.attr_b.reset()
self.attr_b.type = attrs["type"]
if attrs.has_key("restriction"):
self.attr_b.restriction = attrs["restriction"]
self.attr_b.name = attrs["name"]
# if attrs.has_key("default"):
# self.attr_b.default = attrs["default"]
......
......@@ -1133,6 +1133,31 @@ dest as a signed value.</description>
</syntax>
</instruction>
<instruction opcode="mfc0" level="native" kind="movement">
<description>Move the contents of control coprocessor src register
to CPU dest register.</description>
<format>
<attribute type="Register" name="dest" />
<attribute type="Register" restriction="generic" name="src" />
</format>
<syntax>
<token kind="register" />
<token kind="register" />
</syntax>
</instruction>
<instruction opcode="mtc0" level="native" kind="movement">
<description>Move the contents of CPU src register to control coprocessor
dest register.</description>
<format>
<attribute type="Register" restriction="generic" name="dest" />
<attribute type="Register" name="src" />
</format>
<syntax>
<token kind="register" />
<token kind="register" />
</syntax>
</instruction>
<!-- Exception and trap instructions -->
<instruction opcode="syscall" level="native" kind="syscall">
......
......@@ -2,31 +2,30 @@
(Created-By-Prcs-Version 1 3 2)
(Project-Description "")
(Project-Version mipsy 0 82)
(Parent-Version mipsy 0 81)
(Project-Version mipsy 0 83)
(Parent-Version mipsy 0 82)
(Version-Log
"Index: ChangeLog
from Benot Perrot <benoit@lrde.epita.fr>
* src/vm/cp0.hh:
Add control coprocessor.
* src/vm/Makefile.am:
Distribute it.
* src/vm/cpu.hh, src/vm/cpu.cc,
* src/vm/virtual_machine.hh:
Use control coprocessor.
* dev/mipsy.py,
* dev/mipsy.xml:
Add instructions to move registers to/from control coprocessor.
* dev/inst-solver-gen.py,
* dev/parse-asm-scan-gen.py,
* src/inst/register.hh:
Support generic register identifiers.
* NEWS:
Document it.
* tests/lexical/unlimited-regs.s:
Move to...
* tests/solve/unlimited-regs.s:
This file.
* tests/lexical/Makefile.am,
* tests/solve/Makefile.am:
Update.
Check register identifiers for control coprocessor instructions.
")
(New-Version-Log
"")
(Checkin-Time "Sun, 04 Apr 2004 17:11:04 +0200")
(Checkin-Time "Sun, 04 Apr 2004 22:19:20 +0200")
(Checkin-Login benoit)
(Files
......@@ -34,10 +33,10 @@ from Beno
;; ./
(AUTHORS (mipsy/0_AUTHORS 1.1 644))
(COPYING (mipsy/1_COPYING 1.1 644))
(ChangeLog (mipsy/2_ChangeLog 1.76 604))
(ChangeLog (mipsy/2_ChangeLog 1.77 604))
(INSTALL (mipsy/b/12_INSTALL 1.1 604))
(Makefile.am (mipsy/3_Makefile.a 1.8 604))
(NEWS (mipsy/b/25_NEWS 1.7 604))
(NEWS (mipsy/b/25_NEWS 1.8 604))
(README (mipsy/4_README 1.3 604))
(TODO (mipsy/5_TODO 1.3 604))
(bootstrap (mipsy/b/14_bootstrap 1.3 705))
......@@ -52,9 +51,9 @@ from Beno
(dev/inst-builder-gen.py (mipsy/15_mipsy-buil 1.12 705))
(dev/inst-makefile-gen.py (mipsy/b/15_mipsy-mk-i 1.9 705))
(dev/inst-nodes-gen.py (mipsy/12_mipsy-inst 1.10 705))
(dev/inst-solver-gen.py (mipsy/b/13_inst-solve 1.2 755))
(dev/mipsy.py (mipsy/16_mipsy.py 1.9 705))
(dev/mipsy.xml (mipsy/17_mipsy.xml 1.16 604))
(dev/inst-solver-gen.py (mipsy/b/13_inst-solve 1.3 755))
(dev/mipsy.py (mipsy/16_mipsy.py 1.10 705))
(dev/mipsy.xml (mipsy/17_mipsy.xml 1.17 604))
(dev/parse-asm-parse-gen.py (mipsy/13_mipsy-pars 1.10 705))
(dev/parse-asm-scan-gen.py (mipsy/14_mipsy-scan 1.12 705))
......@@ -116,14 +115,15 @@ from Beno
(src/task/task_register.hh (mipsy/51_task_regis 1.5 604))
;; ./src/vm/
(src/vm/Makefile.am (mipsy/b/0_Makefile.a 1.4 604))
(src/vm/cpu.hh (mipsy/b/1_cpu.hh 1.17 604))
(src/vm/cpu.cc (mipsy/b/5_virtual_ma 1.24 604))
(src/vm/Makefile.am (mipsy/b/0_Makefile.a 1.5 604))
(src/vm/cp0.hh (mipsy/b/16_cp0.hh 1.1 644))
(src/vm/cpu.hh (mipsy/b/1_cpu.hh 1.18 604))
(src/vm/cpu.cc (mipsy/b/5_virtual_ma 1.25 604))
(src/vm/memory.hh (mipsy/b/2_memory.hh 1.10 604))
(src/vm/mmu.hh (mipsy/c/15_mmu.hh 1.3 604))
(src/vm/segment.hh (mipsy/b/3_segment.hh 1.5 644))
(src/vm/table.hh (mipsy/b/4_table.hh 1.5 604))
(src/vm/virtual_machine.hh (mipsy/b/6_virtual_ma 1.16 604))
(src/vm/virtual_machine.hh (mipsy/b/6_virtual_ma 1.17 604))
(src/vm/vm-tasks.cc (mipsy/b/7_vm-tasks.c 1.7 604))
(src/vm/vm-tasks.hh (mipsy/b/8_vm-tasks.h 1.4 604))
......
......@@ -5,6 +5,7 @@ noinst_LIBRARIES = libvm.a
libvm_a_SOURCES = \
table.hh \
mmu.hh \
cp0.hh \
cpu.hh cpu.cc \
segment.hh \
memory.hh \
......
//
// This file is part of Mipsy, a tiny MIPS simulator
// Copyright (C) 2003, 2004 Benoit Perrot <benoit@lrde.epita.fr>
//
// Mipsy 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.
//
// Mipsy 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
//
/** \file vm/cp0.hh
\brief Declare Coprocessor 0 class. */
#ifndef VM_CP0_HH
# define VM_CP0_HH
# include "inst/register.hh"
namespace vm
{
/// Coprocessor 0 (control coprocessor) abstraction
class Cp0
{
typedef uint32_t register_type;
public:
/// Coprocessor 0 registers indices
enum kind_type
{
index = 0, ///< Index register
random = 1, ///< Random register
entry_lo0 = 2, ///< Entry for even pages
entry_lo1 = 3, ///< Entry for odd pages
context = 4, ///< Context register
page_mask = 5, ///< Page mask register
wired = 6, ///< Wired register
error = 7, ///< Status/control register
bad_vaddr = 8, ///< Bad virtual address register
count = 9, ///< Count register
entry_hi = 10, ///< Entry high
compare = 11, ///< Compare register
status = 12, ///< Status (kernel/user mode, etc.) register
cause = 13, ///< Cause of exception register
epc = 14, ///< Exception program counter
pr_id = 15, ///< Processor identification
config = 16, ///< Configuration register (64 bits)
lladdr = 17, ///< Loaded linked address
watch_lo = 18, ///< Watch point debug facility, low part
watch_hi = 19, ///< Watch point debug facility, high part
x_context = 20, ///< X context register
reserved0 = 21, ///< (Reserved register)
reserved1 = 22, ///< (Reserved register)
debug = 23, ///< Debug register
depc = 24, ///< Debug exception program counter
perf_cnt = 25, ///< Performance counter register
err_ctl = 26, ///< Error control register
cache_err = 27, ///< Cache error register
cache_tag_lo = 28, ///< Cache tag/data low
cache_tag_hi = 29, ///< Cache tag/data high
error_epc = 30, ///< Error exception program counter
desave = 31 ///< Debug exception SAVE
};
/** \name Constructor and destructor
\{ */
public:
Cp0()
{
reset();
}
/** \} */
public:
/// Reset the CPU (set registers to zero)
void reset()
{
// Initialize registers to 0.
for (unsigned i = 0; i < 32; ++i)
registers[i] = 0;
}
/** \name Explicit register accessors
\{ */
public:
register_type get_count() const { return registers[count]; }
void set_count(register_type r) { registers[count] = r; }
/** \} */
/** \name Register unified accessors.
\{ */
public:
/// Return the register identified by \a reg.
register_type get_register(const inst::Register &reg) const
{
precondition(reg.get_kind() == inst::Register::generic);
return registers[reg.get_index()];
}
/// Set the register identified by \a reg to \a r.
void set_register(const inst::Register &reg, register_type r)
{
precondition(reg.get_kind() == inst::Register::generic);
registers[reg.get_index()] = r;
}
/** \} */
protected:
/// Dedicated registers (32 bits)
register_type registers[32];
};
} // namespace vm
#endif // !VM_CP0_HH
......@@ -29,11 +29,12 @@ namespace vm
// Constructor and destructor
// --------------------------------------------------------------------------
Cpu::Cpu(Mmu& mmu,
Cp0 &cp0,
std::istream& istr,
std::ostream& ostr,
bool check_callee_save_p,
bool trace_p):
mmu_(mmu),
mmu_(mmu), cp0_(cp0),
istr_(istr), ostr_(ostr),
check_callee_save_p_(check_callee_save_p),
trace_p_(trace_p),
......@@ -629,6 +630,16 @@ namespace vm
{
set_lo(get_register(mtlo.get_src()));
}
void
Cpu::visit(const inst::Mfc0& mfc0)
{
set_register(mfc0.get_dest(), cp0_.get_register(mfc0.get_src()));
}
void
Cpu::visit(const inst::Mtc0& mtc0)
{
cp0_.set_register(mtc0.get_dest(), get_register(mtc0.get_src()));
}
// --------------------------------------------------------------------------
......
......@@ -31,6 +31,7 @@
# include "inst/program.hh"
# include "vm/mmu.hh"
# include "vm/cp0.hh"
# include "vm/table.hh"
namespace vm
......@@ -66,6 +67,7 @@ namespace vm
public:
/// Construct a CPU.
Cpu(Mmu& mmu,
Cp0 &cp0,
std::istream& istr,
std::ostream& ostr,
bool check_callee_save_p_,
......@@ -222,12 +224,16 @@ namespace vm
virtual void visit(const inst::Mflo& mflo);
virtual void visit(const inst::Mthi& mthi);
virtual void visit(const inst::Mtlo& mtlo);
virtual void visit(const inst::Mfc0& mfc0);
virtual void visit(const inst::Mtc0& mtc0);
virtual void visit(const inst::Syscall& sycall);
protected:
/// Memory management unit link.
Mmu& mmu_;
/// Control coprocessor link.
Cp0 &cp0_;
/// General purpose registers.
register_type GPR_[32];
......@@ -311,12 +317,12 @@ namespace vm
enum pipeline_stage_type
{
i_stage = 0,
d_stage,
r_stage,
e_stage,
m_stage,
w_stage
i_stage = 0, ///< Instruction fetch stage
d_stage, ///< Instruction dispatch stage
r_stage, ///< Regoster file read stage
e_stage, ///< Execution stage
m_stage, ///< Memory access stage
w_stage ///< Writeback stage
};
inst::Inst* bubble_;
const inst::Inst* pipeline_[6];
......
......@@ -30,6 +30,7 @@
# include "vm/memory.hh"
# include "vm/mmu.hh"
# include "vm/cp0.hh"
# include "vm/cpu.hh"
namespace vm
......@@ -46,7 +47,7 @@ namespace vm
std::istream& istr = std::cin,
std::ostream& ostr = std::cout):
mmu_(memory_),
cpu_(mmu_, istr, ostr, check_callee_save_p, trace_exec_p)
cpu_(mmu_, cp0_, istr, ostr, check_callee_save_p, trace_exec_p)
{
}
/** \} */
......@@ -73,14 +74,20 @@ namespace vm
// FIXME: precondition on loaded program
while (!cpu_.get_halt())
{
cpu_.step();
cp0_.set_count(cp0_.get_count() + 1);
}
}
protected:
/// Memory block.
Memory memory_;
/// Memory management unit.
Mmu mmu_;
/// Control coprocessor.
Cp0 cp0_;
/// Central processor unit.
Cpu cpu_;
};
......
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