Generalize tail continues (#1298)
* Generalize tail continues * Fix DecodeBasicBlock `Next` and `Branch` would be null, which is not the state expected by the branch instructions. They end up branching or falling into a block which is never populated by the `Translator`. This causes an assert to be fired when building the CFG. * Clean up Decode overloads * Do not synchronize when branching into exit block If we're branching into an exit block, that exit block will tail continue into another translation which already has a synchronization. * Remove A32 predicate tail continue If `block` is not an exit block then the `block.Next` must exist (as per the last instruction of `block`). * Throw if decoded 0 blocks Address gdkchan's feedback * Rebuild block list instead of setting to null Address gdkchan's feedback
This commit is contained in:
parent
5e724cf24e
commit
2421186d97
9 changed files with 178 additions and 240 deletions
|
@ -15,14 +15,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
OpCodeBImmAl op = (OpCodeBImmAl)context.CurrOp;
|
||||
|
||||
if (context.CurrBlock.Branch != null)
|
||||
{
|
||||
context.Branch(context.GetLabel((ulong)op.Immediate));
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitTailContinue(context, Const(op.Immediate), context.CurrBlock.TailCall);
|
||||
}
|
||||
context.Branch(context.GetLabel((ulong)op.Immediate));
|
||||
}
|
||||
|
||||
public static void B_Cond(ArmEmitterContext context)
|
||||
|
@ -92,69 +85,22 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
OpCodeBImm op = (OpCodeBImm)context.CurrOp;
|
||||
|
||||
if (context.CurrBlock.Branch != null)
|
||||
{
|
||||
EmitCondBranch(context, context.GetLabel((ulong)op.Immediate), cond);
|
||||
|
||||
if (context.CurrBlock.Next == null)
|
||||
{
|
||||
EmitTailContinue(context, Const(op.Address + 4));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Operand lblTaken = Label();
|
||||
|
||||
EmitCondBranch(context, lblTaken, cond);
|
||||
|
||||
EmitTailContinue(context, Const(op.Address + 4));
|
||||
|
||||
context.MarkLabel(lblTaken);
|
||||
|
||||
EmitTailContinue(context, Const(op.Immediate));
|
||||
}
|
||||
EmitCondBranch(context, context.GetLabel((ulong)op.Immediate), cond);
|
||||
}
|
||||
|
||||
private static void EmitBranch(ArmEmitterContext context, Operand value, bool onNotZero)
|
||||
{
|
||||
OpCodeBImm op = (OpCodeBImm)context.CurrOp;
|
||||
|
||||
if (context.CurrBlock.Branch != null)
|
||||
Operand lblTarget = context.GetLabel((ulong)op.Immediate);
|
||||
|
||||
if (onNotZero)
|
||||
{
|
||||
Operand lblTarget = context.GetLabel((ulong)op.Immediate);
|
||||
|
||||
if (onNotZero)
|
||||
{
|
||||
context.BranchIfTrue(lblTarget, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.BranchIfFalse(lblTarget, value);
|
||||
}
|
||||
|
||||
if (context.CurrBlock.Next == null)
|
||||
{
|
||||
EmitTailContinue(context, Const(op.Address + 4));
|
||||
}
|
||||
context.BranchIfTrue(lblTarget, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Operand lblTaken = Label();
|
||||
|
||||
if (onNotZero)
|
||||
{
|
||||
context.BranchIfTrue(lblTaken, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.BranchIfFalse(lblTaken, value);
|
||||
}
|
||||
|
||||
EmitTailContinue(context, Const(op.Address + 4));
|
||||
|
||||
context.MarkLabel(lblTaken);
|
||||
|
||||
EmitTailContinue(context, Const(op.Immediate));
|
||||
context.BranchIfFalse(lblTarget, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue