Commit e7fe750e authored by Benoit Perrot's avatar Benoit Perrot
Browse files

Make the Cpu responsible of the execution of instructions.

parent 7ad718f1
2003-08-21 Benot Perrot <benoit@lrde.epita.fr>
Make the Cpu responsible of the execution of instructions ;
the VirtualMachine must be seen as a motherboard that could
support more than one Cpu.
* src/vm/virtual_machine.cc: Move to...
* src/vm/cpu.cc: here.
* src/vm/Makefile.am: Propagate it.
* src/vm/virtual_machine.hh: Move execution interface to...
* src/vm/cpu.hh: here.
2003-08-20 Benot Perrot <benoit@lrde.epita.fr>
* dev/mipsy.xml: Add mul with immediate pseudo-instruction.
......
......@@ -2,16 +2,16 @@
(Created-By-Prcs-Version 1 3 2)
(Project-Description "")
(Project-Version mipsy 0 52)
(Parent-Version mipsy 0 51)
(Project-Version mipsy 0 53)
(Parent-Version mipsy 0 52)
(Version-Log
"Add mul with immediate pseudo-instruction.
"Make the Cpu responsible of the execution of instructions.
")
(New-Version-Log
"")
(Checkin-Time "Wed, 20 Aug 2003 16:32:31 +0200")
(Checkin-Time "Thu, 21 Aug 2003 17:41:31 +0200")
(Checkin-Login benoit)
(Files
......@@ -19,7 +19,7 @@
;; ./
(AUTHORS (mipsy/0_AUTHORS 1.1 644))
(COPYING (mipsy/1_COPYING 1.1 644))
(ChangeLog (mipsy/2_ChangeLog 1.46 644))
(ChangeLog (mipsy/2_ChangeLog 1.47 644))
(Makefile.am (mipsy/3_Makefile.a 1.5 644))
(NEWS (mipsy/b/25_NEWS 1.5 644))
(README (mipsy/4_README 1.2 644))
......@@ -95,13 +95,13 @@
(src/task/task_register.hh (mipsy/51_task_regis 1.3 604))
;; ./src/vm/
(src/vm/Makefile.am (mipsy/b/0_Makefile.a 1.2 644))
(src/vm/cpu.hh (mipsy/b/1_cpu.hh 1.6 644))
(src/vm/Makefile.am (mipsy/b/0_Makefile.a 1.3 644))
(src/vm/cpu.hh (mipsy/b/1_cpu.hh 1.7 644))
(src/vm/cpu.cc (mipsy/b/5_virtual_ma 1.16 604))
(src/vm/memory.hh (mipsy/b/2_memory.hh 1.6 644))
(src/vm/segment.hh (mipsy/b/3_segment.hh 1.2 644))
(src/vm/table.hh (mipsy/b/4_table.hh 1.2 644))
(src/vm/virtual_machine.cc (mipsy/b/5_virtual_ma 1.15 604))
(src/vm/virtual_machine.hh (mipsy/b/6_virtual_ma 1.10 604))
(src/vm/virtual_machine.hh (mipsy/b/6_virtual_ma 1.11 604))
(src/vm/vm-tasks.cc (mipsy/b/7_vm-tasks.c 1.4 604))
(src/vm/vm-tasks.hh (mipsy/b/8_vm-tasks.h 1.3 604))
......
......@@ -4,8 +4,8 @@ noinst_LIBRARIES = libvm.a
libvm_a_SOURCES = \
table.hh \
cpu.hh \
cpu.hh cpu.cc \
segment.hh \
memory.hh \
virtual_machine.hh virtual_machine.cc \
virtual_machine.hh \
vm-tasks.hh vm-tasks.cc
......@@ -18,7 +18,7 @@
//
#include "common.hh"
#include "vm/virtual_machine.hh"
#include "vm/cpu.hh"
#include "inst/all.hh"
......@@ -30,13 +30,13 @@ namespace vm
// --------------------------------------------------------------------------
void
VirtualMachine::visit(const inst::Add& add)
Cpu::visit(const inst::Add& add)
{
register_t a = cpu.get_register(add.get_src1 ());
register_t b = cpu.get_register(add.get_src2 ());
register_t a = get_register(add.get_src1 ());
register_t b = get_register(add.get_src2 ());
register_t c = a + b;
cpu.set_register(add.get_dest (), c);
set_register(add.get_dest (), c);
// FIXME: might be accelerated by testing only the sign bit.
if ((a < 0 && b < 0 && c > 0) ||
......@@ -47,13 +47,13 @@ namespace vm
}
}
void
VirtualMachine::visit(const inst::Addi& addi)
Cpu::visit(const inst::Addi& addi)
{
register_t a = cpu.get_register(addi.get_src ());
register_t a = get_register(addi.get_src ());
int b = addi.get_imm ();
register_t c = a + b;
cpu.set_register(addi.get_dest (), c);
set_register(addi.get_dest (), c);
// FIXME: might be accelerated by testing only the sign bit.
if ((a < 0 && b < 0 && c > 0) ||
......@@ -64,27 +64,27 @@ namespace vm
}
}
void
VirtualMachine::visit(const inst::Addu& addu)
Cpu::visit(const inst::Addu& addu)
{
cpu.set_register(addu.get_dest (),
cpu.get_register(addu.get_src1 ()) +
cpu.get_register(addu.get_src2 ()));
set_register(addu.get_dest (),
get_register(addu.get_src1 ()) +
get_register(addu.get_src2 ()));
}
void
VirtualMachine::visit(const inst::Addiu& addiu)
Cpu::visit(const inst::Addiu& addiu)
{
cpu.set_register(addiu.get_dest (),
cpu.get_register(addiu.get_src ()) + addiu.get_imm ());
set_register(addiu.get_dest (),
get_register(addiu.get_src ()) + addiu.get_imm ());
}
void
VirtualMachine::visit(const inst::Sub& sub)
Cpu::visit(const inst::Sub& sub)
{
register_t a = cpu.get_register(sub.get_src1 ());
register_t b = cpu.get_register(sub.get_src2 ());
register_t a = get_register(sub.get_src1 ());
register_t b = get_register(sub.get_src2 ());
register_t c = a - b;
cpu.set_register(sub.get_dest (), c);
set_register(sub.get_dest (), c);
if ((a < b && c > 0) || (a > b && c < 0))
{
......@@ -93,113 +93,113 @@ namespace vm
}
}
void
VirtualMachine::visit(const inst::Subu& subu)
Cpu::visit(const inst::Subu& subu)
{
cpu.set_register(subu.get_dest (),
cpu.get_register(subu.get_src1 ()) -
cpu.get_register(subu.get_src2 ()));
set_register(subu.get_dest (),
get_register(subu.get_src1 ()) -
get_register(subu.get_src2 ()));
}
void
VirtualMachine::visit(const inst::Sll& sll)
Cpu::visit(const inst::Sll& sll)
{
uregister_t a = cpu.get_register(sll.get_src ());
uregister_t a = get_register(sll.get_src ());
unsigned i = sll.get_imm ();
register_t c = a << i;
cpu.set_register(sll.get_dest (), c);
set_register(sll.get_dest (), c);
// FIXME: Check overflow !
}
void
VirtualMachine::visit(const inst::Sllv& slv)
Cpu::visit(const inst::Sllv& slv)
{
uregister_t a = cpu.get_register(slv.get_src1 ());
uregister_t b = cpu.get_register(slv.get_src2 ());
uregister_t a = get_register(slv.get_src1 ());
uregister_t b = get_register(slv.get_src2 ());
register_t c = a << b;
cpu.set_register(slv.get_dest (), c);
set_register(slv.get_dest (), c);
// FIXME: Check overflow !
}
void
VirtualMachine::visit(const inst::Sra& sra)
Cpu::visit(const inst::Sra& sra)
{
register_t a = cpu.get_register(sra.get_src ());
register_t a = get_register(sra.get_src ());
unsigned b = sra.get_imm ();
register_t c = a >> b;
cpu.set_register(sra.get_dest (), c);
set_register(sra.get_dest (), c);
// FIXME: Check overflow !
}
void
VirtualMachine::visit(const inst::Srav& srav)
Cpu::visit(const inst::Srav& srav)
{
register_t a = cpu.get_register(srav.get_src1 ());
register_t b = cpu.get_register(srav.get_src2 ());
register_t a = get_register(srav.get_src1 ());
register_t b = get_register(srav.get_src2 ());
register_t c = a >> b;
cpu.set_register(srav.get_dest (), c);
set_register(srav.get_dest (), c);
// FIXME: Check overflow !
}
void
VirtualMachine::visit(const inst::Srl& srl)
Cpu::visit(const inst::Srl& srl)
{
uregister_t a = cpu.get_register(srl.get_src ());
uregister_t a = get_register(srl.get_src ());
unsigned i = srl.get_imm ();
uregister_t c = a >> i;
cpu.set_register(srl.get_dest (), c);
set_register(srl.get_dest (), c);
// FIXME: Check overflow !
}
void
VirtualMachine::visit(const inst::Srlv& srlv)
Cpu::visit(const inst::Srlv& srlv)
{
uregister_t a = cpu.get_register(srlv.get_src1 ());
uregister_t b = cpu.get_register(srlv.get_src2 ());
uregister_t a = get_register(srlv.get_src1 ());
uregister_t b = get_register(srlv.get_src2 ());
uregister_t c = a >> b;
cpu.set_register(srlv.get_dest (), c);
set_register(srlv.get_dest (), c);
// FIXME: Check overflow !
}
void
VirtualMachine::visit(const inst::Mul& mul)
Cpu::visit(const inst::Mul& mul)
{
register_t a = cpu.get_register(mul.get_src1 ());
register_t b = cpu.get_register(mul.get_src2 ());
register_t a = get_register(mul.get_src1 ());
register_t b = get_register(mul.get_src2 ());
register_t c = a * b;
cpu.set_register(mul.get_dest (), c);
set_register(mul.get_dest (), c);
// FIXME: Check overflow !
}
void
VirtualMachine::visit(const inst::Div& div)
Cpu::visit(const inst::Div& div)
{
register_t a = cpu.get_register(div.get_src1 ());
register_t b = cpu.get_register(div.get_src2 ());
register_t a = get_register(div.get_src1 ());
register_t b = get_register(div.get_src2 ());
register_t c = a / b;
cpu.set_lo(c);
set_lo(c);
c = a % b;
cpu.set_hi(c);
set_hi(c);
// FIXME: Check overflow !
}
void
VirtualMachine::visit(const inst::Divu& divu)
Cpu::visit(const inst::Divu& divu)
{
uregister_t a = cpu.get_register(divu.get_src1 ());
uregister_t b = cpu.get_register(divu.get_src2 ());
uregister_t a = get_register(divu.get_src1 ());
uregister_t b = get_register(divu.get_src2 ());
cpu.set_lo(a / b);
cpu.set_hi(a % b);
set_lo(a / b);
set_hi(a % b);
}
......@@ -208,70 +208,70 @@ namespace vm
// --------------------------------------------------------------------------
void
VirtualMachine::visit(const inst::And& _and)
Cpu::visit(const inst::And& _and)
{
register_t a = cpu.get_register(_and.get_src1 ());
register_t b = cpu.get_register(_and.get_src2 ());
register_t a = get_register(_and.get_src1 ());
register_t b = get_register(_and.get_src2 ());
register_t c = a & b;
cpu.set_register(_and.get_dest (), c);
set_register(_and.get_dest (), c);
}
void
VirtualMachine::visit(const inst::Andi& andi)
Cpu::visit(const inst::Andi& andi)
{
register_t a = cpu.get_register(andi.get_src ());
register_t a = get_register(andi.get_src ());
int b = andi.get_imm ();
register_t c = a & b;
cpu.set_register(andi.get_dest (), c);
set_register(andi.get_dest (), c);
}
void
VirtualMachine::visit(const inst::Or& _or)
Cpu::visit(const inst::Or& _or)
{
register_t a = cpu.get_register(_or.get_src1 ());
register_t b = cpu.get_register(_or.get_src2 ());
register_t a = get_register(_or.get_src1 ());
register_t b = get_register(_or.get_src2 ());
register_t c = a | b;
cpu.set_register(_or.get_dest (), c);
set_register(_or.get_dest (), c);
}
void
VirtualMachine::visit(const inst::Ori& ori)
Cpu::visit(const inst::Ori& ori)
{
register_t a = cpu.get_register(ori.get_src ());
register_t a = get_register(ori.get_src ());
int b = ori.get_imm ();
register_t c = a | b;
cpu.set_register(ori.get_dest (), c);
set_register(ori.get_dest (), c);
}
void
VirtualMachine::visit(const inst::Nor& nor)
Cpu::visit(const inst::Nor& nor)
{
register_t a = cpu.get_register(nor.get_src1 ());
register_t b = cpu.get_register(nor.get_src2 ());
register_t a = get_register(nor.get_src1 ());
register_t b = get_register(nor.get_src2 ());
register_t c = a | b;
cpu.set_register(nor.get_dest (), ~c);
set_register(nor.get_dest (), ~c);
}
void
VirtualMachine::visit(const inst::Xor& _xor)
Cpu::visit(const inst::Xor& _xor)
{
register_t a = cpu.get_register(_xor.get_src1 ());
register_t b = cpu.get_register(_xor.get_src2 ());
register_t a = get_register(_xor.get_src1 ());
register_t b = get_register(_xor.get_src2 ());
register_t c = a ^ b;
cpu.set_register(_xor.get_dest (), c);
set_register(_xor.get_dest (), c);
}
void
VirtualMachine::visit(const inst::Xori& xori)
Cpu::visit(const inst::Xori& xori)
{
register_t a = cpu.get_register(xori.get_src ());
register_t a = get_register(xori.get_src ());
int b = xori.get_imm ();
register_t c = a ^ b;
cpu.set_register(xori.get_dest (), c);
set_register(xori.get_dest (), c);
}
......@@ -280,47 +280,47 @@ namespace vm
// --------------------------------------------------------------------------
void
VirtualMachine::visit(const inst::Li& li)
Cpu::visit(const inst::Li& li)
{
cpu.set_register(li.get_dest (), li.get_imm ());
set_register(li.get_dest (), li.get_imm ());
}
// Store
void
VirtualMachine::visit(const inst::Sb& sb)
Cpu::visit(const inst::Sb& sb)
{
register_t addr = cpu.get_register(sb.get_base ()) + sb.get_offset ();
memory.store_byte(addr, cpu.get_register(sb.get_src ()));
register_t addr = get_register(sb.get_base ()) + sb.get_offset ();
memory.store_byte(addr, get_register(sb.get_src ()));
}
void
VirtualMachine::visit(const inst::Sw& sw)
Cpu::visit(const inst::Sw& sw)
{
register_t addr = cpu.get_register(sw.get_base ()) + sw.get_offset ();
memory.store_word(addr, cpu.get_register(sw.get_src ()));
register_t addr = get_register(sw.get_base ()) + sw.get_offset ();
memory.store_word(addr, get_register(sw.get_src ()));
}
// Load
void
VirtualMachine::visit(const inst::Lb& lb)
Cpu::visit(const inst::Lb& lb)
{
register_t addr = cpu.get_register(lb.get_base ()) + lb.get_offset ();
cpu.set_register(lb.get_dest (), memory.load_byte(addr));
register_t addr = get_register(lb.get_base ()) + lb.get_offset ();
set_register(lb.get_dest (), memory.load_byte(addr));
}
void
VirtualMachine::visit(const inst::Lbu& lbu)
Cpu::visit(const inst::Lbu& lbu)
{
register_t addr = cpu.get_register(lbu.get_base ()) + lbu.get_offset ();
register_t addr = get_register(lbu.get_base ()) + lbu.get_offset ();
unsigned b = memory.load_byte(addr);
cpu.set_register(lbu.get_dest (), b % 256);
set_register(lbu.get_dest (), b % 256);
}
void
VirtualMachine::visit(const inst::Lw& lw)
Cpu::visit(const inst::Lw& lw)
{
register_t addr = cpu.get_register(lw.get_base ()) + lw.get_offset ();
cpu.set_register(lw.get_dest (), memory.load_word(addr));
register_t addr = get_register(lw.get_base ()) + lw.get_offset ();
set_register(lw.get_dest (), memory.load_word(addr));
}
// --------------------------------------------------------------------------
......@@ -328,38 +328,38 @@ namespace vm
// --------------------------------------------------------------------------
void
VirtualMachine::visit(const inst::Slt& slt)
Cpu::visit(const inst::Slt& slt)
{
if (cpu.get_register(slt.get_src1 ()) < cpu.get_register(slt.get_src2 ()))
cpu.set_register(slt.get_dest(), 1);
if (get_register(slt.get_src1 ()) < get_register(slt.get_src2 ()))
set_register(slt.get_dest(), 1);
else
cpu.set_register(slt.get_dest(), 0);
set_register(slt.get_dest(), 0);
}
void
VirtualMachine::visit(const inst::Slti& slti)
Cpu::visit(const inst::Slti& slti)
{
if (cpu.get_register(slti.get_src ()) < slti.get_imm ())
cpu.set_register(slti.get_dest(), 1);
if (get_register(slti.get_src ()) < slti.get_imm ())
set_register(slti.get_dest(), 1);
else
cpu.set_register(slti.get_dest(), 0);
set_register(slti.get_dest(), 0);
}
void
VirtualMachine::visit(const inst::Sltu& sltu)
Cpu::visit(const inst::Sltu& sltu)
{
if ((uregister_t) cpu.get_register(sltu.get_src1 ()) <
(uregister_t) cpu.get_register(sltu.get_src2 ()))
cpu.set_register(sltu.get_dest(), 1);
if ((uregister_t) get_register(sltu.get_src1 ()) <
(uregister_t) get_register(sltu.get_src2 ()))
set_register(sltu.get_dest(), 1);
else
cpu.set_register(sltu.get_dest(), 0);
set_register(sltu.get_dest(), 0);
}
void
VirtualMachine::visit(const inst::Sltiu& sltiu)
Cpu::visit(const inst::Sltiu& sltiu)
{
if ((uregister_t) cpu.get_register(sltiu.get_src ()) <
if ((uregister_t) get_register(sltiu.get_src ()) <
(uregister_t) sltiu.get_imm ())
cpu.set_register(sltiu.get_dest(), 1);
set_register(sltiu.get_dest(), 1);
else
cpu.set_register(sltiu.get_dest(), 0);
set_register(sltiu.get_dest(), 0);
}
......@@ -369,33 +369,33 @@ namespace vm
// Unconditional
void
VirtualMachine::visit(const inst::Jmp& jmp)
Cpu::visit(const inst::Jmp& jmp)
{
cpu.set_pc(cpu.get_pc() + jmp.get_label());
set_pc(get_pc() + jmp.get_label());
}
void
VirtualMachine::visit(const inst::Jr& jr)
Cpu::visit(const inst::Jr& jr)
{
// Assume it is a ret
ret();
cpu.set_pc(cpu.get_register(jr.get_dest()));
set_pc(get_register(jr.get_dest()));
}
void
VirtualMachine::visit(const inst::Jal& jal)
Cpu::visit(const inst::Jal& jal)
{
cpu.set_ra(cpu.get_pc());
cpu.set_pc(cpu.get_ra() + jal.get_label());
set_ra(get_pc());
set_pc(get_ra() + jal.get_label());
// Assume it is a call
call();
}
void
VirtualMachine::visit(const inst::Jalr& jalr)
Cpu::visit(const inst::Jalr& jalr)
{
cpu.set_ra(cpu.get_pc());
cpu.set_pc(cpu.get_register(jalr.get_dest()));
set_ra(get_pc());
set_pc(get_register(jalr.get_dest()));
// Assume it is a call
call();
......@@ -405,67 +405,67 @@ namespace vm
// Equality
void
VirtualMachine::visit(const inst::Beq& beq)
Cpu::visit(const inst::Beq& beq)
{
if (cpu.get_register(beq.get_src1 ()) == cpu.get_register(beq.get_src2 ()))
cpu.set_pc(cpu.get_pc() + beq.get_label());
if (get_register(beq.get_src1 ()) == get_register(beq.get_src2 ()))
set_pc(get_pc() + beq.get_label());
}
void
VirtualMachine::visit(const inst::Bne& bne)
Cpu::visit(const inst::Bne& bne)
{
if (cpu.get_register(bne.get_src1 ()) != cpu.get_register(bne.get_src2 ()))
cpu.set_pc(cpu.get_pc() + bne.get_label());
if (get_register(bne.get_src1 ()) != get_register(bne.get_src2 ()))
set_pc(get_pc() + bne.get_label());
}
// Greater
void
VirtualMachine::visit(const inst::Bgez& bgez)
Cpu::visit(const inst::Bgez& bgez)
{
if (cpu.get_register(bgez.get_src ()) >= 0)
cpu.set_pc(cpu.get_pc() + bgez.get_label());
if (get_register(bgez.get_src ()) >= 0)
set_pc(get_pc() + bgez.get_label());
}
void
VirtualMachine::visit(const inst::Bgezal& bgezal)
Cpu::visit(const inst::Bgezal& bgezal)
{
if (cpu.get_register(bgezal.get_src ()) >= 0)
if (get_register(bgezal.get_src ()) >= 0)
{
// Assume it is a call
call();
cpu.set_ra(cpu.get_pc());
cpu.set_pc(cpu.get_pc() + bgezal.get_label());