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/Decoder/ADecoderHelper.cs | |
| parent | cb665bb715834526d73c9469d16114b287faaecd (diff) | |
Split main project into core,graphics and chocolarm4 subproject (#29)
Diffstat (limited to 'ChocolArm64/Decoder/ADecoderHelper.cs')
| -rw-r--r-- | ChocolArm64/Decoder/ADecoderHelper.cs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/ChocolArm64/Decoder/ADecoderHelper.cs b/ChocolArm64/Decoder/ADecoderHelper.cs new file mode 100644 index 00000000..a2179f49 --- /dev/null +++ b/ChocolArm64/Decoder/ADecoderHelper.cs @@ -0,0 +1,107 @@ +using System; + +namespace ChocolArm64.Decoder +{ + static class ADecoderHelper + { + public struct BitMask + { + public long WMask; + public long TMask; + public int Pos; + public int Shift; + public bool IsUndefined; + + public static BitMask Invalid => new BitMask { IsUndefined = true }; + } + + public static BitMask DecodeBitMask(int OpCode, bool Immediate) + { + int ImmS = (OpCode >> 10) & 0x3f; + int ImmR = (OpCode >> 16) & 0x3f; + + int N = (OpCode >> 22) & 1; + int SF = (OpCode >> 31) & 1; + + int Length = ABitUtils.HighestBitSet32((~ImmS & 0x3f) | (N << 6)); + + if (Length < 1 || (SF == 0 && N != 0)) + { + return BitMask.Invalid; + } + + int Size = 1 << Length; + + int Levels = Size - 1; + + int S = ImmS & Levels; + int R = ImmR & Levels; + + if (Immediate && S == Levels) + { + return BitMask.Invalid; + } + + long WMask = ABitUtils.FillWithOnes(S + 1); + long TMask = ABitUtils.FillWithOnes(((S - R) & Levels) + 1); + + if (R > 0) + { + WMask = ABitUtils.RotateRight(WMask, R, Size); + WMask &= ABitUtils.FillWithOnes(Size); + } + + return new BitMask() + { + WMask = ABitUtils.Replicate(WMask, Size), + TMask = ABitUtils.Replicate(TMask, Size), + + Pos = ImmS, + Shift = ImmR + }; + } + + public static long DecodeImm8Float(long Imm, int Size) + { + int E = 0, F = 0; + + switch (Size) + { + case 0: E = 8; F = 23; break; + case 1: E = 11; F = 52; break; + + default: throw new ArgumentOutOfRangeException(nameof(Size)); + } + + long Value = (Imm & 0x3f) << F - 4; + + long EBit = (Imm >> 6) & 1; + long SBit = (Imm >> 7) & 1; + + if (EBit != 0) + { + Value |= (1L << E - 3) - 1 << F + 2; + } + + Value |= (EBit ^ 1) << F + E - 1; + Value |= SBit << F + E; + + return Value; + } + + public static long DecodeImm26_2(int OpCode) + { + return ((long)OpCode << 38) >> 36; + } + + public static long DecodeImmS19_2(int OpCode) + { + return (((long)OpCode << 40) >> 43) & ~3; + } + + public static long DecodeImmS14_2(int OpCode) + { + return (((long)OpCode << 45) >> 48) & ~3; + } + } +}
\ No newline at end of file |
