2018-02-05 00:08:20 +01:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
namespace ChocolArm64.Translation
|
|
|
|
{
|
|
|
|
class AILBlock : IAILEmit
|
|
|
|
{
|
2018-02-26 02:14:58 +01:00
|
|
|
public long IntInputs { get; private set; }
|
|
|
|
public long IntOutputs { get; private set; }
|
|
|
|
public long IntAwOutputs { get; private set; }
|
2018-02-05 00:08:20 +01:00
|
|
|
|
2018-02-26 02:14:58 +01:00
|
|
|
public long VecInputs { get; private set; }
|
|
|
|
public long VecOutputs { get; private set; }
|
|
|
|
public long VecAwOutputs { get; private set; }
|
2018-02-05 00:08:20 +01:00
|
|
|
|
|
|
|
public bool HasStateStore { get; private set; }
|
|
|
|
|
|
|
|
public List<IAILEmit> ILEmitters { get; private set; }
|
|
|
|
|
|
|
|
public AILBlock Next { get; set; }
|
|
|
|
public AILBlock Branch { get; set; }
|
|
|
|
|
|
|
|
public AILBlock()
|
|
|
|
{
|
|
|
|
ILEmitters = new List<IAILEmit>();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Add(IAILEmit ILEmitter)
|
|
|
|
{
|
2018-02-26 02:14:58 +01:00
|
|
|
if (ILEmitter is AILBarrier)
|
|
|
|
{
|
|
|
|
//Those barriers are used to separate the groups of CIL
|
|
|
|
//opcodes emitted by each ARM instruction.
|
|
|
|
//We can only consider the new outputs for doing input elimination
|
|
|
|
//after all the CIL opcodes used by the instruction being emitted.
|
|
|
|
IntAwOutputs = IntOutputs;
|
|
|
|
VecAwOutputs = VecOutputs;
|
|
|
|
}
|
|
|
|
else if (ILEmitter is AILOpCodeLoad Ld && AILEmitter.IsRegIndex(Ld.Index))
|
2018-02-05 00:08:20 +01:00
|
|
|
{
|
2018-02-18 05:57:33 +01:00
|
|
|
switch (Ld.IoType)
|
2018-02-05 00:08:20 +01:00
|
|
|
{
|
2018-02-26 02:14:58 +01:00
|
|
|
case AIoType.Flag: IntInputs |= ((1L << Ld.Index) << 32) & ~IntAwOutputs; break;
|
|
|
|
case AIoType.Int: IntInputs |= (1L << Ld.Index) & ~IntAwOutputs; break;
|
|
|
|
case AIoType.Vector: VecInputs |= (1L << Ld.Index) & ~VecAwOutputs; break;
|
2018-02-05 00:08:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ILEmitter is AILOpCodeStore St)
|
|
|
|
{
|
|
|
|
if (AILEmitter.IsRegIndex(St.Index))
|
|
|
|
{
|
2018-02-18 05:57:33 +01:00
|
|
|
switch (St.IoType)
|
2018-02-05 00:08:20 +01:00
|
|
|
{
|
|
|
|
case AIoType.Flag: IntOutputs |= (1L << St.Index) << 32; break;
|
|
|
|
case AIoType.Int: IntOutputs |= 1L << St.Index; break;
|
|
|
|
case AIoType.Vector: VecOutputs |= 1L << St.Index; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (St.IoType == AIoType.Fields)
|
|
|
|
{
|
|
|
|
HasStateStore = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ILEmitters.Add(ILEmitter);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Emit(AILEmitter Context)
|
|
|
|
{
|
|
|
|
foreach (IAILEmit ILEmitter in ILEmitters)
|
|
|
|
{
|
|
|
|
ILEmitter.Emit(Context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|