private static void InsertTop( int XMask, int Value, AInst Inst, AExecutionMode Mode) { TreeNode Node = new TreeNode(XMask, Value, Inst); if (Mode == AExecutionMode.AArch64) { Node.Next = InstHeadA64; InstHeadA64 = Node; } else { Node.Next = InstHeadA32; InstHeadA32 = Node; } }
public AOpCodeSimdMemMs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { switch ((OpCode >> 12) & 0xf) { case 0b0000: Reps = 1; SElems = 4; break; case 0b0010: Reps = 4; SElems = 1; break; case 0b0100: Reps = 1; SElems = 3; break; case 0b0110: Reps = 3; SElems = 1; break; case 0b0111: Reps = 1; SElems = 1; break; case 0b1000: Reps = 1; SElems = 2; break; case 0b1010: Reps = 2; SElems = 1; break; default: Inst = AInst.Undefined; return; } Size = (OpCode >> 10) & 0x3; WBack = ((OpCode >> 23) & 0x1) != 0; bool Q = ((OpCode >> 30) & 1) != 0; if (!Q && Size == 3 && SElems != 1) { Inst = AInst.Undefined; return; } RegisterSize = Q ? ARegisterSize.SIMD128 : ARegisterSize.SIMD64; Elems = (GetBitsCount() >> 3) >> Size; }
public AOpCodeSimdRegElemF(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { switch ((OpCode >> 21) & 3) // sz:L { case 0: // H:0 Index = (OpCode >> 10) & 2; // 0, 2 break; case 1: // H:1 Index = (OpCode >> 10) & 2; Index++; // 1, 3 break; case 2: // H Index = (OpCode >> 11) & 1; // 0, 1 break; default: Emitter = AInstEmit.Und; return; } }
public AOpCodeMov(AInst Inst, long Position, int OpCode) : base(Inst, Position) { int P1 = (OpCode >> 22) & 1; int SF = (OpCode >> 31) & 1; if (SF == 0 && P1 != 0) { Emitter = AInstEmit.Und; return; } Rd = (OpCode >> 0) & 0x1f; Imm = (OpCode >> 5) & 0xffff; Pos = (OpCode >> 21) & 0x3; Pos <<= 4; Imm <<= Pos; RegisterSize = (OpCode >> 31) != 0 ? ARegisterSize.Int64 : ARegisterSize.Int32; }
public InstInfo(int Mask, int Value, AInst Inst) { this.Mask = Mask; this.Value = Value; this.Inst = Inst; }
public A32OpCode(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Cond = (ACond)((uint)OpCode >> 28); }
public AOpCodeBImmAl(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Imm = Position + ADecoderHelper.DecodeImm26_2(OpCode); }
public AOpCodeException(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Id = (OpCode >> 5) & 0xffff; }
public AOpCodeSimdExt(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Imm4 = (OpCode >> 11) & 0xf; }
public AOpCodeCcmpImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { }
public AOpCodeMem(AInst Inst, long Position, int OpCode) : base(Inst, Position) { Rt = (OpCode >> 0) & 0x1f; Rn = (OpCode >> 5) & 0x1f; Size = (OpCode >> 30) & 0x3; }
public AOpCodeSimdTbl(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Size = ((OpCode >> 13) & 3) + 1; }
public AOpCodeCsel(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Rm = (OpCode >> 16) & 0x1f; Cond = (ACond)((OpCode >> 12) & 0xf); }
public AOpCodeBImm(AInst Inst, long Position) : base(Inst, Position) { }
public AOpCodeAluRx(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Shift = (OpCode >> 10) & 0x7; IntType = (AIntType)((OpCode >> 13) & 0x7); Rm = (OpCode >> 16) & 0x1f; }
private static void Set(string Encoding, AInst Inst, AExecutionMode Mode) { int Bit = Encoding.Length - 1; int Value = 0; int XMask = 0; int XBits = 0; int[] XPos = new int[Encoding.Length]; int Blacklisted = 0; for (int Index = 0; Index < Encoding.Length; Index++, Bit--) { //Note: < and > are used on special encodings. //The < means that we should never have ALL bits with the '<' set. //So, when the encoding has <<, it means that 00, 01, and 10 are valid, //but not 11. <<< is 000, 001, ..., 110 but NOT 111, and so on... //For >, the invalid value is zero. So, for >> 01, 10 and 11 are valid, //but 00 isn't. char Chr = Encoding[Index]; if (Chr == '1') { Value |= 1 << Bit; } else if (Chr == 'x') { XMask |= 1 << Bit; } else if (Chr == '>') { XPos[XBits++] = Bit; } else if (Chr == '<') { XPos[XBits++] = Bit; Blacklisted |= 1 << Bit; } else if (Chr != '0') { throw new ArgumentException(nameof(Encoding)); } } XMask = ~XMask; if (XBits == 0) { InsertInst(XMask, Value, Inst, Mode); return; } for (int Index = 0; Index < (1 << XBits); Index++) { int Mask = 0; for (int X = 0; X < XBits; X++) { Mask |= ((Index >> X) & 1) << XPos[X]; } if (Mask != Blacklisted) { InsertInst(XMask, Value | Mask, Inst, Mode); } } }
public AOpCodeMul(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Ra = (OpCode >> 10) & 0x1f; Rm = (OpCode >> 16) & 0x1f; }
public AOpCodeBImmCmp(AInst Inst, long Position, int OpCode) : base(Inst, Position) { Rt = OpCode & 0x1f; Imm = Position + ADecoderHelper.DecodeImmS19_2(OpCode); }
public AOpCodeMemEx(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Rt2 = (OpCode >> 10) & 0x1f; Rs = (OpCode >> 16) & 0x1f; }
public A32OpCodeBImmAl(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Imm = (OpCode << 8) >> 6; H = (OpCode >> 23) & 2; }
public TreeNode(int Mask, int Value, AInst Inst) { this.Mask = Mask; this.Value = Value; this.Inst = Inst; }
public AOpCodeSimdReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Bit3 = ((OpCode >> 3) & 0x1) != 0; Ra = (OpCode >> 10) & 0x1f; Rm = (OpCode >> 16) & 0x1f; }
public AOpCodeSimdMemReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Size |= (OpCode >> 21) & 4; Extend64 = false; }
public AOpCodeSimdMemSs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { int Size = (OpCode >> 10) & 3; int S = (OpCode >> 12) & 1; int SElems = (OpCode >> 12) & 2; int Scale = (OpCode >> 14) & 3; int L = (OpCode >> 22) & 1; int Q = (OpCode >> 30) & 1; SElems |= (OpCode >> 21) & 1; SElems++; int Index = (Q << 3) | (S << 2) | Size; switch (Scale) { case 1: { if ((Size & 1) != 0) { Inst = AInst.Undefined; return; } Index >>= 1; break; } case 2: { if ((Size & 2) != 0 || ((Size & 1) != 0 && S != 0)) { Inst = AInst.Undefined; return; } if ((Size & 1) != 0) { Index >>= 3; Scale = 3; } else { Index >>= 2; } break; } case 3: { if (L == 0 || S != 0) { Inst = AInst.Undefined; return; } Scale = Size; Replicate = true; break; } } this.Index = Index; this.SElems = SElems; this.Size = Scale; Extend64 = false; WBack = ((OpCode >> 23) & 0x1) != 0; RegisterSize = Q != 0 ? ARegisterSize.SIMD128 : ARegisterSize.SIMD64; }
public AOpCodeSimdFcond(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { NZCV = (OpCode >> 0) & 0xf; Cond = (ACond)((OpCode >> 12) & 0xf); }
private static void Set(string Encoding, AInst Inst) { int Bit = Encoding.Length - 1; int Value = 0; int XMask = 0; int ZCount = 0; int OCount = 0; int[] ZPos = new int[Encoding.Length]; int[] OPos = new int[Encoding.Length]; for (int Index = 0; Index < Encoding.Length; Index++, Bit--) { //Note: < and > are used on special encodings. //The < means that we should never have ALL bits with the '<' set. //So, when the encoding has <<, it means that 00, 01, and 10 are valid, //but not 11. <<< is 000, 001, ..., 110 but NOT 111, and so on... //For >, the invalid value is zero. So, for << 01, 10 and 11 are valid, //but 00 isn't. switch (Encoding[Index]) { case '0': /* Do nothing. */ break; case '1': Value |= 1 << Bit; break; case 'x': XMask |= 1 << Bit; break; case '<': OPos[OCount++] = Bit; break; case '>': ZPos[ZCount++] = Bit; break; default: throw new ArgumentException(nameof(Encoding)); } } if (ZCount + OCount == 0) { InsertTop(XMask, Value, Inst); } else if (ZCount != 0 && OCount != 0) { //When both the > and the <, then a value is blacklisted, //with > indicating 0, and < indicating 1. So, for example, ><< //blacklists the pattern 011, but 000, 001, 010, 100, 101, //110 and 111 are valid. for (int OCtr = 0; (uint)OCtr < (1 << OCount); OCtr++) { int OVal = Value; for (int O = 0; O < OCount; O++) { OVal |= ((OCtr >> O) & 1) << OPos[O]; } int ZStart = OCtr == (1 << OCount) ? 1 : 0; InsertWithCtr(ZStart, 1 << ZCount, ZCount, ZPos, XMask, OVal, Inst); } } else if (ZCount != 0) { InsertWithCtr(1, 1 << ZCount, ZCount, ZPos, XMask, Value, Inst); } else if (OCount != 0) { InsertWithCtr(0, (1 << OCount) - 1, OCount, OPos, XMask, Value, Inst); } }
public AOpCodeSimdShImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { Imm = (OpCode >> 16) & 0x7f; Size = ABitUtils.HighestBitSetNibble(Imm >> 3); }