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:
Randy Heit 2014-12-21 21:57:30 -06:00
parent 1ea03ffbec
commit b14f768b68
2 changed files with 20 additions and 11 deletions

View File

@ -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.
resultreg.Reuse(build); // This is really just for the assert in Reuse()
build->Emit(OP_MOVE, resultreg.RegNum, casereg.RegNum, 0);
resultreg.Free(build);
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);
}
// 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())
{

View File

@ -423,8 +423,9 @@ void VMFunctionBuilder::RegAvailability::Return(int reg, int count)
bool VMFunctionBuilder::RegAvailability::Reuse(int reg)
{
assert(reg >= 0 && reg <= 255);
assert(reg < MostUsed && "Attempt to reuse a register that was never used");
VM_UWORD mask = reg & 31;
VM_UWORD mask = 1 << (reg & 31);
int word = reg / 32;
if (Used[word] & mask)