diff options
author | Ficture Seven <FICTURE7@gmail.com> | 2020-06-18 07:37:21 +0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-18 13:37:21 +1000 |
commit | 2421186d974446ef4183420c50bc37e58d9fe213 (patch) | |
tree | e182d974bc8dde8c6dcb206936cd2c4146f2f736 /ARMeilleure/Instructions/InstEmitFlow.cs | |
parent | 5e724cf24e3d696b95be859c055a617e5d37bf80 (diff) |
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
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitFlow.cs')
-rw-r--r-- | ARMeilleure/Instructions/InstEmitFlow.cs | 68 |
1 files changed, 7 insertions, 61 deletions
diff --git a/ARMeilleure/Instructions/InstEmitFlow.cs b/ARMeilleure/Instructions/InstEmitFlow.cs index 6f2a346e..2fcf50db 100644 --- a/ARMeilleure/Instructions/InstEmitFlow.cs +++ b/ARMeilleure/Instructions/InstEmitFlow.cs @@ -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); } } } |