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

Use HI and LO register to execute div, divu, rem, remu.

parent f73542e3
2003-07-07 Benot Perrot <benoit@lrde.epita.fr>
* dev/mipsy.xml,
* src/inst/program_builder.cc,
* src/inst/program_solver.hh,
* src/vm/cpu.hh,
* src/vm/virtual_machine.hh, src/vm/virtual_machine.cc:
Use HI and LO register to execute div, divu, rem, remu.
2003-07-06 Benot Perrot <benoit@lrde.epita.fr> 2003-07-06 Benot Perrot <benoit@lrde.epita.fr>
* src/vm/virtual_machine.cc: * src/vm/virtual_machine.cc:
......
...@@ -154,35 +154,53 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ...@@ -154,35 +154,53 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<instruction opcode="div" level="native"> <instruction opcode="div" level="native">
<format> <format>
<register name="dest" />
<register name="src1" /> <register name="src1" />
<register name="src2" /> <register name="src2" />
</format> </format>
<syntax> <syntax>
<register /> <register />
<register /> <register />
</syntax>
<syntax level="complex">
<register />
<register />
<register />
</syntax>
<syntax level="complex">
<register />
<register /> <register />
<immediate />
</syntax> </syntax>
</instruction> </instruction>
<instruction opcode="divu" level="native"> <instruction opcode="divu" level="native">
<format> <format>
<register name="dest" />
<register name="src1" /> <register name="src1" />
<register name="src2" /> <register name="src2" />
</format> </format>
<syntax> <syntax>
<register /> <register />
<register /> <register />
</syntax>
<syntax level="complex">
<register />
<register />
<register /> <register />
</syntax> </syntax>
<syntax level="complex">
<register />
<register />
<immediate />
</syntax>
</instruction> </instruction>
<instruction opcode="remu" level="native"> <instruction opcode="rem" level="complex">
<format> <syntax>
<register name="dest" /> <register />
<register name="src1" /> <register />
<register name="src2" /> <register />
</format> </syntax>
</instruction>
<instruction opcode="remu" level="complex">
<syntax> <syntax>
<register /> <register />
<register /> <register />
...@@ -943,6 +961,41 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ...@@ -943,6 +961,41 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</syntax> </syntax>
</instruction> </instruction>
<instruction opcode="mfhi" level="native">
<format>
<register name="dest" />
</format>
<syntax>
<register />
</syntax>
</instruction>
<instruction opcode="mflo" level="native">
<format>
<register name="dest" />
</format>
<syntax>
<register />
</syntax>
</instruction>
<instruction opcode="mthi" level="native">
<format>
<register name="src" />
</format>
<syntax>
<register />
</syntax>
</instruction>
<instruction opcode="mtlo" level="native">
<format>
<register name="src" />
</format>
<syntax>
<register />
</syntax>
</instruction>
<!-- Exception and trap instructions --> <!-- Exception and trap instructions -->
<instruction opcode="syscall" level="native"> <instruction opcode="syscall" level="native">
...@@ -952,4 +1005,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ...@@ -952,4 +1005,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</syntax> </syntax>
</instruction> </instruction>
<!-- Nop instructions -->
<instruction opcode="nop" level="native">
<format>
</format>
<syntax>
</syntax>
</instruction>
</instructions> </instructions>
...@@ -36,7 +36,57 @@ namespace inst ...@@ -36,7 +36,57 @@ namespace inst
add_inst(* new Sub(dest, * new Register(Register::zero), src)); add_inst(* new Sub(dest, * new Register(Register::zero), src));
} }
void
ProgramBuilder::add_div(Register& dest, Register& src1, Register& src2)
{
// FIXME: break on divide by zero, check overflow, see mips-as output
_program->text_section ().add_inst(* new Div(src1, src2));
_program->text_section ().add_inst(* new Mflo(dest));
}
void
ProgramBuilder::add_div(Register& dest, Register& src1, Exp& src2)
{
// FIXME: program_solver must warn and/or break when exp is zero
Register& at = * new Register(Register::at);
_program->text_section ().add_inst(* new Li(at, src2));
_program->text_section ().add_inst(* new Div(src1, at));
_program->text_section ().add_inst(* new Mflo(dest));
}
void
ProgramBuilder::add_divu(Register& dest, Register& src1, Register& src2)
{
// FIXME: break on divide by zero, check overflow, see mips-as output
_program->text_section ().add_inst(* new Divu(src1, src2));
_program->text_section ().add_inst(* new Mflo(dest));
}
void
ProgramBuilder::add_divu(Register& dest, Register& src1, Exp& src2)
{
// FIXME: program_solver must warn and/or break when exp is zero
Register& at = * new Register(Register::at);
_program->text_section ().add_inst(* new Li(at, src2));
_program->text_section ().add_inst(* new Divu(src1, at));
_program->text_section ().add_inst(* new Mflo(dest));
}
void
ProgramBuilder::add_rem(Register& dest, Register& src1, Register& src2)
{
// FIXME: break on divide by zero, check overflow, see mips-as output
_program->text_section ().add_inst(* new Div(src1, src2));
_program->text_section ().add_inst(* new Mfhi(dest));
}
void
ProgramBuilder::add_remu(Register& dest, Register& src1, Register& src2)
{
// FIXME: break on divide by zero, see mips-as output
_program->text_section ().add_inst(* new Divu(src1, src2));
_program->text_section ().add_inst(* new Mfhi(dest));
}
// Bitwise instructions ------------------------------------- // Bitwise instructions -------------------------------------
void void
ProgramBuilder::add_rol(Register& dest, Register& src1, Register& src2) ProgramBuilder::add_rol(Register& dest, Register& src1, Register& src2)
{ {
......
...@@ -141,7 +141,6 @@ namespace inst ...@@ -141,7 +141,6 @@ namespace inst
virtual void visit(Mul&) {} virtual void visit(Mul&) {}
virtual void visit(Div&) {} virtual void visit(Div&) {}
virtual void visit(Divu&) {} virtual void visit(Divu&) {}
virtual void visit(Remu&) {}
protected: protected:
virtual void visit(And&) {} virtual void visit(And&) {}
...@@ -246,9 +245,18 @@ namespace inst ...@@ -246,9 +245,18 @@ namespace inst
resolve_exp(sw.get_offset()); resolve_exp(sw.get_offset());
} }
protected:
virtual void visit(Mfhi&) {}
virtual void visit(Mflo&) {}
virtual void visit(Mthi&) {}
virtual void visit(Mtlo&) {}
protected: protected:
virtual void visit(Syscall&) {} virtual void visit(Syscall&) {}
protected:
virtual void visit(Nop&) {}
protected: protected:
Program* _program; Program* _program;
}; };
......
...@@ -57,6 +57,9 @@ namespace vm ...@@ -57,6 +57,9 @@ namespace vm
fp = Memory::stack_bottom; fp = Memory::stack_bottom;
ra = 0; ra = 0;
pc = 0; pc = 0;
lo = 0;
hi = 0;
} }
public: public:
...@@ -89,9 +92,6 @@ namespace vm ...@@ -89,9 +92,6 @@ namespace vm
register_t get_ra() const { return ra; } register_t get_ra() const { return ra; }
void set_ra(register_t r) { ra = r; } void set_ra(register_t r) { ra = r; }
register_t get_pc() const { return pc; }
void set_pc(register_t r) { pc = r; }
register_t get_unlimited(int i) const register_t get_unlimited(int i) const
{ {
// FIXME: precondition: check existence! // FIXME: precondition: check existence!
...@@ -122,7 +122,6 @@ namespace vm ...@@ -122,7 +122,6 @@ namespace vm
return zero; return zero;
} }
public:
void set_register(const inst::Register& reg, register_t r) void set_register(const inst::Register& reg, register_t r)
{ {
switch (reg.get_kind()) switch (reg.get_kind())
...@@ -142,6 +141,17 @@ namespace vm ...@@ -142,6 +141,17 @@ namespace vm
} }
} }
public:
register_t get_hi() const { return hi; }
void set_hi(register_t r) { hi = r; }
register_t get_lo() const { return lo; }
void set_lo(register_t r) { lo = r; }
register_t get_pc() const { return pc; }
void set_pc(register_t r) { pc = r; }
public: public:
void begin_scope() void begin_scope()
{ {
...@@ -161,8 +171,11 @@ namespace vm ...@@ -161,8 +171,11 @@ namespace vm
register_t s[9]; register_t s[9];
register_t sp, fp; register_t sp, fp;
register_t ra; register_t ra;
register_t pc;
Table<int, register_t> unlimited; Table<int, register_t> unlimited;
register_t hi, lo;
register_t pc;
}; };
} // namespace vm } // namespace vm
......
...@@ -174,7 +174,10 @@ namespace vm ...@@ -174,7 +174,10 @@ namespace vm
register_t b = cpu.get_register(div.get_src2 ()); register_t b = cpu.get_register(div.get_src2 ());
register_t c = a / b; register_t c = a / b;
cpu.set_register(div.get_dest (), c); cpu.set_lo(c);
c = a % b;
cpu.set_hi(c);
// FIXME: Check overflow ! // FIXME: Check overflow !
} }
...@@ -184,23 +187,8 @@ namespace vm ...@@ -184,23 +187,8 @@ namespace vm
uregister_t a = cpu.get_register(divu.get_src1 ()); uregister_t a = cpu.get_register(divu.get_src1 ());
uregister_t b = cpu.get_register(divu.get_src2 ()); uregister_t b = cpu.get_register(divu.get_src2 ());
uregister_t c = a / b; cpu.set_lo(a / b);
cpu.set_register(divu.get_dest (), c); cpu.set_hi(a % b);
// FIXME: Check overflow !
}
void
VirtualMachine::visit(const inst::Remu& remu)
{
uregister_t a = cpu.get_register(remu.get_src1 ());
uregister_t b = cpu.get_register(remu.get_src2 ());
uregister_t c = a % b;
cpu.set_register(remu.get_dest (), c);
// FIXME: Check overflow !
} }
...@@ -472,7 +460,33 @@ namespace vm ...@@ -472,7 +460,33 @@ namespace vm
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Syscall and builtins // Data movement instructions
// --------------------------------------------------------------------------
void
VirtualMachine::visit(const inst::Mfhi& mfhi)
{
cpu.set_register(mfhi.get_dest(), cpu.get_hi());
}
void
VirtualMachine::visit(const inst::Mflo& mflo)
{
cpu.set_register(mflo.get_dest(), cpu.get_lo());
}
void
VirtualMachine::visit(const inst::Mthi& mthi)
{
cpu.set_hi(cpu.get_register(mthi.get_src()));
}
void
VirtualMachine::visit(const inst::Mtlo& mtlo)
{
cpu.set_lo(cpu.get_register(mtlo.get_src()));
}
// --------------------------------------------------------------------------
// Exception and trap instructions
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
void void
......
...@@ -90,7 +90,6 @@ namespace vm ...@@ -90,7 +90,6 @@ namespace vm
virtual void visit(const inst::Mul& mul); virtual void visit(const inst::Mul& mul);
virtual void visit(const inst::Div& div); virtual void visit(const inst::Div& div);
virtual void visit(const inst::Divu& divu); virtual void visit(const inst::Divu& divu);
virtual void visit(const inst::Remu& remu);
virtual void visit(const inst::Lb& lb); virtual void visit(const inst::Lb& lb);
virtual void visit(const inst::Lbu& Lbu); virtual void visit(const inst::Lbu& Lbu);
...@@ -128,8 +127,15 @@ namespace vm ...@@ -128,8 +127,15 @@ namespace vm
virtual void visit(const inst::Bltz& bltz); virtual void visit(const inst::Bltz& bltz);
virtual void visit(const inst::Bltzal& bltzal); virtual void visit(const inst::Bltzal& bltzal);
virtual void visit(const inst::Mfhi& mfhi);
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::Syscall& sycall); virtual void visit(const inst::Syscall& sycall);
virtual void visit(const inst::Nop&) {}
protected: protected:
void begin_scope() void begin_scope()
{ {
......
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