This patch reveals the lack of nolimips in immediate checking:
li $t0, 0x10001
is invalid since 0x10001 does not fit in 16bits. In these cases,
the assembler should output:
lui $t0, 0x1
ori $t0, $t0, 0x10000
... The worst is that this remark is valid for every immediate
instructions (addi, ori, andi, etc.)
Index: ChangeLog
from BenoƮt Perrot <benoit(a)lrde.epita.fr>
Li is not a native instruction
* dev/nolimips.xml, src/int/program_builder.cc:
Make `li' a pseudo instruction for `addiu'.
* src/vm/cpu.hh, src/vm/cpu.cc:
Remove emulation of `li'.
Index: src/vm/cpu.hh
--- src/vm/cpu.hh (revision 124)
+++ src/vm/cpu.hh (revision 125)
@@ -195,7 +195,6 @@
virtual void visit(const inst::Lb& lb);
virtual void visit(const inst::Lbu& Lbu);
virtual void visit(const inst::Lw& lw);
- virtual void visit(const inst::Li& li);
virtual void visit(const inst::Sb& sb);
virtual void visit(const inst::Sw& sw);
Index: src/vm/cpu.cc
--- src/vm/cpu.cc (revision 124)
+++ src/vm/cpu.cc (revision 125)
@@ -365,12 +365,6 @@
// Move instructions
// --------------------------------------------------------------------------
- void
- Cpu::visit(const inst::Li& li)
- {
- set_register(li.get_dest (), li.get_imm ());
- }
-
// Store
void
Cpu::visit(const inst::Sb& sb)
Index: src/inst/program_builder.cc
--- src/inst/program_builder.cc (revision 124)
+++ src/inst/program_builder.cc (revision 125)
@@ -50,7 +50,8 @@
{
// Warning: is not implemented in as for mips, check why.
program_->text_section ().
- add_inst(new Li(Register(Register::general, Cpu::at), src2));
+ add_inst(new Addiu(Register(Register::general, Cpu::at),
+ Register(Register::general, Cpu::zero), src2));
program_->text_section ().
add_inst(new Mul(*dest, *src1, Register(Register::general, Cpu::at)));
}
@@ -67,7 +68,8 @@
{
// FIXME: program_solver must warn and/or break when exp is zero
program_->text_section ().
- add_inst(new Li(Register(Register::general, Cpu::at), src2));
+ add_inst(new Addiu(Register(Register::general, Cpu::at),
+ Register(Register::general, Cpu::zero), src2));
program_->text_section ().
add_inst(new Div(*src1, Register(Register::general, Cpu::at)));
program_->text_section ().add_inst(new Mflo(*dest));
@@ -84,7 +86,8 @@
{
// FIXME: program_solver must warn and/or break when exp is zero
program_->text_section ().
- add_inst(new Li(Register(Register::general, Cpu::at), src2));
+ add_inst(new Addiu(Register(Register::general, Cpu::at),
+ Register(Register::general, Cpu::zero), src2));
program_->text_section ().
add_inst(new Divu(*src1, Register(Register::general, Cpu::at)));
program_->text_section ().add_inst(new Mflo(*dest));
@@ -234,7 +237,8 @@
ProgramBuilder::add_sgt(Register *dest, Register *src1, Exp *src2)
{
program_->text_section ().
- add_inst(new Li(Register(Register::general, Cpu::at), src2));
+ add_inst(new Addiu(Register(Register::general, Cpu::at),
+ Register(Register::general, Cpu::zero), src2));
program_->text_section ().
add_inst(new Slt(*dest, Register(Register::general, Cpu::at), *src1));
}
@@ -242,7 +246,8 @@
ProgramBuilder::add_sgtu(Register *dest, Register *src1, Exp *src2)
{
program_->text_section ().
- add_inst(new Li(Register(Register::general, Cpu::at), src2));
+ add_inst(new Addiu(Register(Register::general, Cpu::at),
+ Register(Register::general, Cpu::zero), src2));
program_->text_section ().
add_inst(new Sltu(*dest, Register(Register::general, Cpu::at), *src1));
}
@@ -258,7 +263,8 @@
ProgramBuilder::add_sle(Register *dest, Register *src1, Exp *src2)
{
program_->text_section ().
- add_inst(new Li(Register(Register::general, Cpu::at), src2));
+ add_inst(new Addiu(Register(Register::general, Cpu::at),
+ Register(Register::general, Cpu::zero), src2));
program_->text_section ().
add_inst(new Slt(*dest, Register(Register::general, Cpu::at), *src1));
program_->text_section ().add_inst(new Xori(*dest, *dest, new IntExp(1)));
@@ -273,7 +279,8 @@
ProgramBuilder::add_sleu(Register *dest, Register *src1, Exp *src2)
{
program_->text_section ().
- add_inst(new Li(Register(Register::general, Cpu::at), src2));
+ add_inst(new Addiu(Register(Register::general, Cpu::at),
+ Register(Register::general, Cpu::zero), src2));
program_->text_section ().
add_inst(new Sltu(*dest, Register(Register::general, Cpu::at), *src1));
program_->text_section ().
@@ -288,7 +295,8 @@
ProgramBuilder::add_bne(Register *src1, Exp *src2, Exp *dest)
{
program_->text_section ().
- add_inst(new Li(Register(Register::general, Cpu::at), src2));
+ add_inst(new Addiu(Register(Register::general, Cpu::at),
+ Register(Register::general, Cpu::zero), src2));
program_->text_section ().
add_inst(new Bne(*src1, Register(Register::general, Cpu::at), dest));
// This nop is in the delay slot
@@ -301,7 +309,8 @@
ProgramBuilder::add_beq(Register *src1, Exp *src2, Exp *dest)
{
program_->text_section ().
- add_inst(new Li(Register(Register::general, Cpu::at), src2));
+ add_inst(new Addiu(Register(Register::general, Cpu::at),
+ Register(Register::general, Cpu::zero), src2));
program_->text_section ().
add_inst(new Beq(*src1, Register(Register::general, Cpu::at), dest));
// This nop is in the delay slot
@@ -545,7 +554,10 @@
new IntExp(0)));
}
- // Load address ------------------------------------------
+ // Load --------------------------------------------------
+
+ // Load address
+ // FIXME: alias?
void
ProgramBuilder::add_la (Register *dest, Exp *exp, Register *base)
{
@@ -554,8 +566,8 @@
void
ProgramBuilder::add_la (Register *reg, Exp *exp)
{
- // FIXME: alias
- program_->text_section ().add_inst(new Li(*reg, exp));
+ program_->text_section ().
+ add_inst(new Addiu(*reg, Register(Register::general, Cpu::zero), exp));
}
} // namespace inst
Index: dev/nolimips.xml
--- dev/nolimips.xml (revision 124)
+++ dev/nolimips.xml (revision 125)
@@ -1026,15 +1026,11 @@
</syntax>
</instruction>
- <!-- FIXME, should be a complex form -->
- <instruction opcode="li" level="native"
kind="load">
+ <instruction opcode="li" level="pseudo"
kind="load">
<description>Move the constant imm into dest.</description>
- <format>
- <attribute type="Register" name="dest"/>
- <attribute type="Exp" name="imm"/>
- </format>
- <syntax>
+ <syntax alias="ori">
<token kind="register" />
+ <token kind="hidden" value="new Register(Register::general,
Cpu::zero)"/>
<token kind="immediate" />
</syntax>
</instruction>