diff options
| author | emmauss <emmausssss@gmail.com> | 2018-02-20 22:09:23 +0200 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-02-20 17:09:23 -0300 |
| commit | 62b827f474f0aa2152dd339fcc7cf31084e16a0b (patch) | |
| tree | 0e5c55b341aee4db0ccb841a084f253ec5e05657 /ChocolArm64/Instruction/AInstEmitSystem.cs | |
| parent | cb665bb715834526d73c9469d16114b287faaecd (diff) | |
Split main project into core,graphics and chocolarm4 subproject (#29)
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSystem.cs')
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSystem.cs | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSystem.cs b/ChocolArm64/Instruction/AInstEmitSystem.cs new file mode 100644 index 00000000..6754be7a --- /dev/null +++ b/ChocolArm64/Instruction/AInstEmitSystem.cs @@ -0,0 +1,122 @@ +using ChocolArm64.Decoder; +using ChocolArm64.State; +using ChocolArm64.Translation; +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace ChocolArm64.Instruction +{ + static partial class AInstEmit + { + public static void Mrs(AILEmitterCtx Context) + { + AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp; + + Context.EmitLdarg(ATranslatedSub.StateArgIdx); + + string PropName; + + switch (GetPackedId(Op)) + { + case 0b11_011_0000_0000_001: PropName = nameof(AThreadState.CtrEl0); break; + case 0b11_011_0000_0000_111: PropName = nameof(AThreadState.DczidEl0); break; + case 0b11_011_0100_0100_000: PropName = nameof(AThreadState.Fpcr); break; + case 0b11_011_0100_0100_001: PropName = nameof(AThreadState.Fpsr); break; + case 0b11_011_1101_0000_010: PropName = nameof(AThreadState.TpidrEl0); break; + case 0b11_011_1101_0000_011: PropName = nameof(AThreadState.Tpidr); break; + case 0b11_011_1110_0000_001: PropName = nameof(AThreadState.CntpctEl0); break; + + default: throw new NotImplementedException($"Unknown MRS at {Op.Position:x16}"); + } + + Context.EmitCallPropGet(typeof(AThreadState), PropName); + + PropertyInfo PropInfo = typeof(AThreadState).GetProperty(PropName); + + if (PropInfo.PropertyType != typeof(long) && + PropInfo.PropertyType != typeof(ulong)) + { + Context.Emit(OpCodes.Conv_U8); + } + + Context.EmitStintzr(Op.Rt); + } + + public static void Msr(AILEmitterCtx Context) + { + AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp; + + Context.EmitLdarg(ATranslatedSub.StateArgIdx); + Context.EmitLdintzr(Op.Rt); + + string PropName; + + switch (GetPackedId(Op)) + { + case 0b11_011_0100_0100_000: PropName = nameof(AThreadState.Fpcr); break; + case 0b11_011_0100_0100_001: PropName = nameof(AThreadState.Fpsr); break; + case 0b11_011_1101_0000_010: PropName = nameof(AThreadState.TpidrEl0); break; + + default: throw new NotImplementedException($"Unknown MSR at {Op.Position:x16}"); + } + + PropertyInfo PropInfo = typeof(AThreadState).GetProperty(PropName); + + if (PropInfo.PropertyType != typeof(long) && + PropInfo.PropertyType != typeof(ulong)) + { + Context.Emit(OpCodes.Conv_U4); + } + + Context.EmitCallPropSet(typeof(AThreadState), PropName); + } + + public static void Nop(AILEmitterCtx Context) + { + //Do nothing. + } + + public static void Sys(AILEmitterCtx Context) + { + //This instruction is used to do some operations on the CPU like cache invalidation, + //address translation and the like. + //We treat it as no-op here since we don't have any cache being emulated anyway. + AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp; + + switch (GetPackedId(Op)) + { + case 0b11_011_0111_0100_001: + { + //DC ZVA + for (int Offs = 0; Offs < (4 << AThreadState.DczSizeLog2); Offs += 8) + { + Context.EmitLdarg(ATranslatedSub.MemoryArgIdx); + Context.EmitLdint(Op.Rt); + Context.EmitLdc_I(Offs); + + Context.Emit(OpCodes.Add); + + Context.EmitLdc_I8(0); + + AInstEmitMemoryHelper.EmitWriteCall(Context, 3); + } + break; + } + } + } + + private static int GetPackedId(AOpCodeSystem Op) + { + int Id; + + Id = Op.Op2 << 0; + Id |= Op.CRm << 3; + Id |= Op.CRn << 7; + Id |= Op.Op1 << 11; + Id |= Op.Op0 << 14; + + return Id; + } + } +}
\ No newline at end of file |
