Allow loops inside basic blocks
This commit is contained in:
parent
51605fafc0
commit
08047ad5c9
3 changed files with 58 additions and 12 deletions
|
@ -117,13 +117,11 @@ namespace ChocolArm64
|
||||||
|
|
||||||
private ATranslatedSub TranslateTier0(AThreadState State, AMemory Memory, long Position)
|
private ATranslatedSub TranslateTier0(AThreadState State, AMemory Memory, long Position)
|
||||||
{
|
{
|
||||||
ABlock Block = ADecoder.DecodeBasicBlock(State, this, Memory, Position);
|
(ABlock[] Graph, ABlock Root) = ADecoder.DecodeBasicBlock(State, this, Memory, Position);
|
||||||
|
|
||||||
ABlock[] Graph = new ABlock[] { Block };
|
|
||||||
|
|
||||||
string SubName = GetSubName(Position);
|
string SubName = GetSubName(Position);
|
||||||
|
|
||||||
AILEmitterCtx Context = new AILEmitterCtx(this, Graph, Block, SubName);
|
AILEmitterCtx Context = new AILEmitterCtx(this, Graph, Root, SubName);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -137,8 +135,6 @@ namespace ChocolArm64
|
||||||
|
|
||||||
CachedSubs.AddOrUpdate(Position, Subroutine, (Key, OldVal) => Subroutine);
|
CachedSubs.AddOrUpdate(Position, Subroutine, (Key, OldVal) => Subroutine);
|
||||||
|
|
||||||
AOpCode LastOp = Block.GetLastOp();
|
|
||||||
|
|
||||||
return Subroutine;
|
return Subroutine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace ChocolArm64.Decoder
|
||||||
OpActivators = new ConcurrentDictionary<Type, OpActivator>();
|
OpActivators = new ConcurrentDictionary<Type, OpActivator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ABlock DecodeBasicBlock(
|
public static (ABlock[] Graph, ABlock Root) DecodeBasicBlock(
|
||||||
AThreadState State,
|
AThreadState State,
|
||||||
ATranslator Translator,
|
ATranslator Translator,
|
||||||
AMemory Memory,
|
AMemory Memory,
|
||||||
|
@ -29,7 +29,41 @@ namespace ChocolArm64.Decoder
|
||||||
|
|
||||||
FillBlock(State, Memory, Block);
|
FillBlock(State, Memory, Block);
|
||||||
|
|
||||||
return Block;
|
AOpCode LastOp = Block.GetLastOp();
|
||||||
|
|
||||||
|
if (LastOp is AOpCodeBImm Op && Op.Emitter != AInstEmit.Bl)
|
||||||
|
{
|
||||||
|
if (Op.Imm == Start)
|
||||||
|
{
|
||||||
|
Block.Branch = Block;
|
||||||
|
}
|
||||||
|
else if ((ulong)Op.Imm > (ulong)Start &&
|
||||||
|
(ulong)Op.Imm < (ulong)Block.EndPosition)
|
||||||
|
{
|
||||||
|
int NewBlockIndex = (int)((Op.Imm - Start) / 4);
|
||||||
|
|
||||||
|
ABlock NewBlock = new ABlock(Op.Imm);
|
||||||
|
|
||||||
|
for (int Index = NewBlockIndex; Index < Block.OpCodes.Count; Index++)
|
||||||
|
{
|
||||||
|
NewBlock.OpCodes.Add(Block.OpCodes[Index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Block.OpCodes.RemoveRange(NewBlockIndex, Block.OpCodes.Count - NewBlockIndex);
|
||||||
|
|
||||||
|
NewBlock.EndPosition = Block.EndPosition;
|
||||||
|
|
||||||
|
NewBlock.Branch = NewBlock;
|
||||||
|
|
||||||
|
Block.EndPosition = Op.Imm;
|
||||||
|
|
||||||
|
Block.Next = NewBlock;
|
||||||
|
|
||||||
|
return (new ABlock[] { Block, NewBlock }, Block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (new ABlock[] { Block }, Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (ABlock[] Graph, ABlock Root) DecodeSubroutine(
|
public static (ABlock[] Graph, ABlock Root) DecodeSubroutine(
|
||||||
|
|
|
@ -163,10 +163,18 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
AOpCodeBImm Op = (AOpCodeBImm)Context.CurrOp;
|
AOpCodeBImm Op = (AOpCodeBImm)Context.CurrOp;
|
||||||
|
|
||||||
if (Context.CurrBlock.Next != null &&
|
if (Context.CurrBlock.Branch != null)
|
||||||
Context.CurrBlock.Branch != null)
|
|
||||||
{
|
{
|
||||||
Context.EmitCondBranch(Context.GetLabel(Op.Imm), Cond);
|
Context.EmitCondBranch(Context.GetLabel(Op.Imm), Cond);
|
||||||
|
|
||||||
|
if (Context.CurrBlock.Next == null)
|
||||||
|
{
|
||||||
|
Context.EmitStoreState();
|
||||||
|
|
||||||
|
Context.EmitLdc_I8(Op.Position + 4);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -192,10 +200,18 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
AOpCodeBImm Op = (AOpCodeBImm)Context.CurrOp;
|
AOpCodeBImm Op = (AOpCodeBImm)Context.CurrOp;
|
||||||
|
|
||||||
if (Context.CurrBlock.Next != null &&
|
if (Context.CurrBlock.Branch != null)
|
||||||
Context.CurrBlock.Branch != null)
|
|
||||||
{
|
{
|
||||||
Context.Emit(ILOp, Context.GetLabel(Op.Imm));
|
Context.Emit(ILOp, Context.GetLabel(Op.Imm));
|
||||||
|
|
||||||
|
if (Context.CurrBlock.Next == null)
|
||||||
|
{
|
||||||
|
Context.EmitStoreState();
|
||||||
|
|
||||||
|
Context.EmitLdc_I8(Op.Position + 4);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue