Fix FxPick code emission
- Fixed: Integer constants passed to pick() need to manually generate load instructions, since FxConstant::Emit() will just return a constant register with its value. - Fixed: VMFunctionBuilder::RegAvailability::Reuse() didn't actually calculate a proper mask. Also added another assert to this function.
This commit is contained in:
parent
1ea03ffbec
commit
b14f768b68
2 changed files with 19 additions and 10 deletions
|
|
@ -2203,17 +2203,25 @@ ExpEmit FxPick::Emit(VMFunctionBuilder *build)
|
|||
for (unsigned i = 0; i < choices.Size(); ++i)
|
||||
{
|
||||
build->BackpatchToHere(jumptable + i);
|
||||
ExpEmit casereg = choices[i]->Emit(build);
|
||||
if (casereg.RegNum != resultreg.RegNum)
|
||||
{ // The result of the case is in a different register from what
|
||||
// was expected. Copy it to the one we wanted.
|
||||
if (choices[i]->isConstant())
|
||||
{
|
||||
int val = static_cast<FxConstant *>(choices[i])->GetValue().GetInt();
|
||||
build->EmitLoadInt(resultreg.RegNum, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExpEmit casereg = choices[i]->Emit(build);
|
||||
if (casereg.RegNum != resultreg.RegNum)
|
||||
{ // The result of the case is in a different register from what
|
||||
// was expected. Copy it to the one we wanted.
|
||||
|
||||
resultreg.Reuse(build); // This is really just for the assert in Reuse()
|
||||
build->Emit(OP_MOVE, resultreg.RegNum, casereg.RegNum, 0);
|
||||
resultreg.Free(build);
|
||||
resultreg.Reuse(build); // This is really just for the assert in Reuse()
|
||||
build->Emit(OP_MOVE, resultreg.RegNum, casereg.RegNum, 0);
|
||||
resultreg.Free(build);
|
||||
}
|
||||
// Free this register so the remaining cases can use it.
|
||||
casereg.Free(build);
|
||||
}
|
||||
// Free this register so the remaining cases can use it.
|
||||
casereg.Free(build);
|
||||
// All but the final case needs a jump to the end of the expression's code.
|
||||
if (i + 1 < choices.Size())
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue