예제 #1
0
        public OpCode32MemMult(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            Rn = (opCode >> 16) & 0xf;

            bool isLoad = (opCode & (1 << 20)) != 0;
            bool w      = (opCode & (1 << 21)) != 0;
            bool u      = (opCode & (1 << 23)) != 0;
            bool p      = (opCode & (1 << 24)) != 0;

            RegisterMask = opCode & 0xffff;

            int regsSize = BitOperations.PopCount((uint)RegisterMask) * 4;

            if (!u)
            {
                Offset -= regsSize;
            }

            if (u == p)
            {
                Offset += 4;
            }

            if (w)
            {
                PostOffset = u ? regsSize : -regsSize;
            }
            else
            {
                PostOffset = 0;
            }

            IsLoad = isLoad;
        }
예제 #2
0
        public OpCode32SimdMemSingle(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            Vd  = (opCode >> 12) & 0xf;
            Vd |= (opCode >> 18) & 0x10;

            IndexAlign = (opCode >> 4) & 0xf;

            Size      = (opCode >> 10) & 0x3;
            Replicate = Size == 3;
            if (Replicate)
            {
                Size      = (opCode >> 6) & 0x3;
                Increment = ((opCode >> 5) & 1) + 1;
                Index     = 0;
            }
            else
            {
                Increment = (((IndexAlign >> Size) & 1) == 0) ? 1 : 2;
                Index     = IndexAlign >> (1 + Size);
            }

            Rm = (opCode >> 0) & 0xf;
            Rn = (opCode >> 16) & 0xf;

            WBack         = Rm != RegisterAlias.Aarch32Pc;
            RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp;
        }
예제 #3
0
        public OpCodeT16MemStack(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            int extra    = (opCode >> 8) & 1;
            int regCount = BitOperations.PopCount((uint)opCode & 0x1ff);

            switch (inst.Name)
            {
            case InstName.Push:
                RegisterMask = (opCode & 0xff) | (extra << 14);
                IsLoad       = false;
                Offset       = -4 * regCount;
                PostOffset   = -4 * regCount;
                break;

            case InstName.Pop:
                RegisterMask = (opCode & 0xff) | (extra << 15);
                IsLoad       = true;
                Offset       = 0;
                PostOffset   = 4 * regCount;
                break;

            default:
                throw new InvalidOperationException();
            }
        }
예제 #4
0
파일: OpCodeAluImm.cs 프로젝트: derparb/h
        public OpCodeAluImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            if (DataOp == DataOp.Arithmetic)
            {
                Immediate = (opCode >> 10) & 0xfff;

                int shift = (opCode >> 22) & 3;

                Immediate <<= shift * 12;
            }
            else if (DataOp == DataOp.Logical)
            {
                var bm = DecoderHelper.DecodeBitMask(opCode, true);

                if (bm.IsUndefined)
                {
                    Instruction = InstDescriptor.Undefined;

                    return;
                }

                Immediate = bm.WMask;
            }
            else
            {
                throw new ArgumentException(nameof(opCode));
            }
        }
예제 #5
0
        public OpCodeT16MemSp(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            Rt = (opCode >> 8) & 7;

            IsLoad = ((opCode >> 11) & 1) != 0;

            Immediate = ((opCode >> 0) & 0xff) << 2;
        }
예제 #6
0
        public OpCode(InstDescriptor inst, ulong address, int opCode)
        {
            Instruction = inst;
            Address     = address;
            RawOpCode   = opCode;

            RegisterSize = RegisterSize.Int64;
        }
예제 #7
0
        public OpCode32AluImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            int value = (opCode >> 0) & 0xff;
            int shift = (opCode >> 8) & 0xf;

            Immediate = BitUtils.RotateRight(value, shift * 2, 32);

            IsRotated = shift != 0;
        }
예제 #8
0
        public OpCode32MsrReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            R      = ((opCode >> 22) & 1) != 0;
            Mask   = (opCode >> 16) & 0xf;
            Rd     = (opCode >> 12) & 0xf;
            Banked = ((opCode >> 9) & 1) != 0;
            Rn     = (opCode >> 0) & 0xf;

            if (Rn == RegisterAlias.Aarch32Pc || Mask == 0)
            {
                Instruction = InstDescriptor.Undefined;
            }
        }
예제 #9
0
        public OpCodeCcmp(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            int o3 = (opCode >> 4) & 1;

            if (o3 != 0)
            {
                Instruction = InstDescriptor.Undefined;

                return;
            }

            Nzcv  = (opCode >> 0) & 0xf;
            Cond  = (Condition)((opCode >> 12) & 0xf);
            RmImm = (opCode >> 16) & 0x1f;

            Rd = RegisterAlias.Zr;
        }
예제 #10
0
        public OpCodeT16MemMult(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            RegisterMask = opCode & 0xff;
            Rn           = (opCode >> 8) & 7;

            int regCount = BitOperations.PopCount((uint)RegisterMask);

            Offset     = 0;
            PostOffset = 4 * regCount;
            IsLoad     = inst.Name switch
            {
                InstName.Ldm => true,
                InstName.Stm => false,
                _ => throw new InvalidOperationException()
            };
        }
    }
예제 #11
0
        public OpCode32Mem(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            Rt = (opCode >> 12) & 0xf;
            Rn = (opCode >> 16) & 0xf;

            bool isLoad = (opCode & (1 << 20)) != 0;
            bool w      = (opCode & (1 << 21)) != 0;
            bool u      = (opCode & (1 << 23)) != 0;
            bool p      = (opCode & (1 << 24)) != 0;

            Index        = p;
            Add          = u;
            WBack        = !p || w;
            Unprivileged = !p && w;

            IsLoad = isLoad || inst.Name == InstName.Ldrd;
        }
예제 #12
0
        public OpCode32SimdCvtFFixed(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            Opc = (opCode >> 8) & 0x1;

            Size  = Opc == 1 ? 0 : 2;
            Fbits = 64 - ((opCode >> 16) & 0x3f);

            if (((opCode >> 21) & 0x1) == 0)
            {
                Instruction = InstDescriptor.Undefined;
            }

            if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm))
            {
                Instruction = InstDescriptor.Undefined;
            }
        }
예제 #13
0
        public OpCode32SimdMemPair(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            Vd  = (opCode >> 12) & 0xf;
            Vd |= (opCode >> 18) & 0x10;

            Size = (opCode >> 6) & 0x3;

            Align = (opCode >> 4) & 0x3;
            Rm    = (opCode >> 0) & 0xf;
            Rn    = (opCode >> 16) & 0xf;

            WBack         = Rm != RegisterAlias.Aarch32Pc;
            RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp;

            Regs = RegsMap[(opCode >> 8) & 0xf];

            Increment = Math.Min(Regs, ((opCode >> 8) & 0x1) + 1);
        }
예제 #14
0
        public OpCodeT32BImm20(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            uint pc = GetPc();

            int imm11 = (opCode >> 0) & 0x7ff;
            int j2    = (opCode >> 11) & 1;
            int j1    = (opCode >> 13) & 1;
            int imm6  = (opCode >> 16) & 0x3f;
            int s     = (opCode >> 26) & 1;

            int imm32 = imm11 | (imm6 << 11) | (j1 << 17) | (j2 << 18) | (s << 19);

            imm32 = (imm32 << 13) >> 12;

            Immediate = pc + imm32;

            Cond = (Condition)((opCode >> 22) & 0xf);
        }
예제 #15
0
        public OpCodeT16IfThen(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            List <Condition> conds = new();

            int cond = (opCode >> 4) & 0xf;
            int mask = opCode & 0xf;

            conds.Add((Condition)cond);

            while ((mask & 7) != 0)
            {
                int newLsb = (mask >> 3) & 1;
                cond   = (cond & 0xe) | newLsb;
                mask <<= 1;
                conds.Add((Condition)cond);
            }

            IfThenBlockConds = conds.ToArray();
        }
예제 #16
0
        public OpCodeT16MemImm5(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            Rt = (opCode >> 0) & 7;
            Rn = (opCode >> 3) & 7;

            switch (inst.Name)
            {
            case InstName.Ldr:
            case InstName.Ldrb:
            case InstName.Ldrh:
                IsLoad = true;
                break;

            case InstName.Str:
            case InstName.Strb:
            case InstName.Strh:
                IsLoad = false;
                break;
            }

            switch (inst.Name)
            {
            case InstName.Str:
            case InstName.Ldr:
                Immediate = ((opCode >> 6) & 0x1f) << 2;
                break;

            case InstName.Strb:
            case InstName.Ldrb:
                Immediate = ((opCode >> 6) & 0x1f);
                break;

            case InstName.Strh:
            case InstName.Ldrh:
                Immediate = ((opCode >> 6) & 0x1f) << 1;
                break;

            default:
                throw new InvalidOperationException();
            }
        }
예제 #17
0
        public OpCodeT32AluImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            int imm8 = (opCode >> 0) & 0xff;
            int imm3 = (opCode >> 12) & 7;
            int imm1 = (opCode >> 26) & 1;

            int imm12 = imm8 | (imm3 << 8) | (imm1 << 11);

            if ((imm12 >> 10) == 0)
            {
                Immediate = imm8 * _factor.GetElement((imm12 >> 8) & 3);
                IsRotated = false;
            }
            else
            {
                int shift = imm12 >> 7;

                Immediate = BitUtils.RotateRight(0x80 | (imm12 & 0x7f), shift, 32);
                IsRotated = shift != 0;
            }
        }
예제 #18
0
        public OpCodeT32BImm24(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            uint pc = GetPc();

            if (inst.Name == InstName.Blx)
            {
                pc &= ~3u;
            }

            int imm11 = (opCode >> 0) & 0x7ff;
            int j2    = (opCode >> 11) & 1;
            int j1    = (opCode >> 13) & 1;
            int imm10 = (opCode >> 16) & 0x3ff;
            int s     = (opCode >> 26) & 1;

            int i1 = j1 ^ s ^ 1;
            int i2 = j2 ^ s ^ 1;

            int imm32 = imm11 | (imm10 << 11) | (i2 << 21) | (i1 << 22) | (s << 23);

            imm32 = (imm32 << 9) >> 8;

            Immediate = pc + imm32;
        }
예제 #19
0
 public OpCode32SimdBase(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
 {
 }
예제 #20
0
파일: Decoder.cs 프로젝트: dnmodder/Ryujinx
        private static OpCode MakeOpCode(InstDescriptor inst, Type type, ulong address, int opCode)
        {
            MakeOp createInstance = _opActivators.GetOrAdd(type, CacheOpActivator);

            return((OpCode)createInstance(inst, address, opCode));
        }
예제 #21
0
        public OpCodeT16MemLit(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            Rt = (opCode >> 8) & 7;

            Immediate = (opCode & 0xff) << 2;
        }
예제 #22
0
파일: OpCodeAluImm.cs 프로젝트: derparb/h
 public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeAluImm(inst, address, opCode);
예제 #23
0
 public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMemSingle(inst, address, opCode);
예제 #24
0
 public OpCode32AluUx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
 {
     Rotate = (opCode >> 10) & 0x3;
 }
예제 #25
0
 public OpCodeT16AddSubSp(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
 {
     Immediate = ((opCode >> 0) & 0x7f) << 2;
 }
예제 #26
0
 public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16SpRel(inst, address, opCode);
예제 #27
0
 public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemMult(inst, address, opCode);
예제 #28
0
 public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16MemStack(inst, address, opCode);
예제 #29
0
        public OpCodeSimdShImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
        {
            Imm = (opCode >> 16) & 0x7f;

            Size = BitUtils.HighestBitSetNibble(Imm >> 3);
        }
예제 #30
0
 public OpCodeT16SpRel(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
 {
     Rd        = (opCode >> 8) & 0x7;
     Immediate = ((opCode >> 0) & 0xff) << 2;
 }