aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Decoder/ADecoderHelper.cs
diff options
context:
space:
mode:
authoremmauss <emmausssss@gmail.com>2018-02-20 22:09:23 +0200
committergdkchan <gab.dark.100@gmail.com>2018-02-20 17:09:23 -0300
commit62b827f474f0aa2152dd339fcc7cf31084e16a0b (patch)
tree0e5c55b341aee4db0ccb841a084f253ec5e05657 /ChocolArm64/Decoder/ADecoderHelper.cs
parentcb665bb715834526d73c9469d16114b287faaecd (diff)
Split main project into core,graphics and chocolarm4 subproject (#29)
Diffstat (limited to 'ChocolArm64/Decoder/ADecoderHelper.cs')
-rw-r--r--ChocolArm64/Decoder/ADecoderHelper.cs107
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