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>
* src/vm/virtual_machine.cc:
......
......@@ -154,35 +154,53 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<instruction opcode="div" level="native">
<format>
<register name="dest" />
<register name="src1" />
<register name="src2" />
</format>
<syntax>
<register />
<register />
</syntax>
<syntax level="complex">
<register />
<register />
<register />
</syntax>
<syntax level="complex">
<register />
<register />
<immediate />
</syntax>
</instruction>
<instruction opcode="divu" level="native">
<format>
<register name="dest" />
<register name="src1" />
<register name="src2" />
</format>
<syntax>
<register />
<register />
</syntax>
<syntax level="complex">
<register />
<register />
<register />
</syntax>
<syntax level="complex">
<register />
<register />
<immediate />
</syntax>
</instruction>
<instruction opcode="remu" level="native">
<format>
<register name="dest" />
<register name="src1" />
<register name="src2" />
</format>
<instruction opcode="rem" level="complex">
<syntax>
<register />
<register />
<register />
</syntax>
</instruction>
<instruction opcode="remu" level="complex">
<syntax>
<register />
<register />
......@@ -943,6 +961,41 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</syntax>
</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 -->
<instruction opcode="syscall" level="native">
......@@ -952,4 +1005,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</syntax>
</instruction>
<!-- Nop instructions -->
<instruction opcode="nop" level="native">
<format>
</format>
<syntax>
</syntax>
</instruction>
</instructions>
......@@ -36,7 +36,57 @@ namespace inst
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 -------------------------------------
void
ProgramBuilder::add_rol(Register& dest, Register& src1, Register& src2)
{
......
......@@ -141,7 +141,6 @@ namespace inst
virtual void visit(Mul&) {}
virtual void visit(Div&) {}
virtual void visit(Divu&) {}
virtual void visit(Remu&) {}
protected:
virtual void visit(And&) {}
......@@ -246,9 +245,18 @@ namespace inst
resolve_exp(sw.get_offset());
}
protected:
virtual void visit(Mfhi&) {}
virtual void visit(Mflo&) {}
virtual void visit(Mthi&) {}
virtual void visit(Mtlo&) {}
protected:
virtual void visit(Syscall&) {}
protected:
virtual void visit(Nop&) {}
protected:
Program* _program;
};
......
......@@ -57,6 +57,9 @@ namespace vm
fp = Memory::stack_bottom;
ra = 0;
pc = 0;
lo = 0;
hi = 0;
}
public:
......@@ -89,9 +92,6 @@ namespace vm
register_t get_ra() const { return ra; }
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
{
// FIXME: precondition: check existence!
......@@ -122,7 +122,6 @@ namespace vm
return zero;
}
public:
void set_register(const inst::Register& reg, register_t r)
{
switch (reg.get_kind())
......@@ -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:
void begin_scope()
{
......@@ -161,8 +171,11 @@ namespace vm
register_t s[9];
register_t sp, fp;
register_t ra;
register_t pc;
Table<int, register_t> unlimited;
register_t hi, lo;
register_t pc;
};
} // namespace vm
......
......@@ -174,7 +174,10 @@ namespace vm
register_t b = cpu.get_register(div.get_src2 ());
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 !
}
......@@ -184,23 +187,8 @@ namespace vm
uregister_t a = cpu.get_register(divu.get_src1 ());
uregister_t b = cpu.get_register(divu.get_src2 ());
uregister_t c = a / b;
cpu.set_register(divu.get_dest (), c);
// 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 !
cpu.set_lo(a / b);
cpu.set_hi(a % b);
}
......@@ -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
......
......@@ -90,7 +90,6 @@ namespace vm
virtual void visit(const inst::Mul& mul);
virtual void visit(const inst::Div& div);
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::Lbu& Lbu);
......@@ -128,8 +127,15 @@ namespace vm
virtual void visit(const inst::Bltz& bltz);
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::Nop&) {}
protected:
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