Ejemplo n.º 1
0
        /// <summary>
        /// Gets the result of the current Arithmetic and Logic unit operation.
        /// </summary>
        /// <param name="state">Current GPU state</param>
        /// <returns>Operation result</returns>
        private int GetAluResult(GpuState state)
        {
            AluOperation op = (AluOperation)(_opCode & 7);

            switch (op)
            {
            case AluOperation.AluReg:
                return(GetAluResult((AluRegOperation)((_opCode >> 17) & 0x1f), GetGprA(), GetGprB()));

            case AluOperation.AddImmediate:
                return(GetGprA() + GetImm());

            case AluOperation.BitfieldReplace:
            case AluOperation.BitfieldExtractLslImm:
            case AluOperation.BitfieldExtractLslReg:
                int bfSrcBit = (_opCode >> 17) & 0x1f;
                int bfSize   = (_opCode >> 22) & 0x1f;
                int bfDstBit = (_opCode >> 27) & 0x1f;

                int bfMask = (1 << bfSize) - 1;

                int dst = GetGprA();
                int src = GetGprB();

                switch (op)
                {
                case AluOperation.BitfieldReplace:
                    src = (int)((uint)src >> bfSrcBit) & bfMask;

                    dst &= ~(bfMask << bfDstBit);

                    dst |= src << bfDstBit;

                    return(dst);

                case AluOperation.BitfieldExtractLslImm:
                    src = (int)((uint)src >> dst) & bfMask;

                    return(src << bfDstBit);

                case AluOperation.BitfieldExtractLslReg:
                    src = (int)((uint)src >> bfSrcBit) & bfMask;

                    return(src << dst);
                }

                break;

            case AluOperation.ReadImmediate:
                return(Read(state, GetGprA() + GetImm()));
            }

            throw new InvalidOperationException($"Invalid operation \"{op}\" on instruction 0x{_opCode:X8}.");
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Emits IL for a Arithmetic and Logic Unit instruction.
        /// </summary>
        /// <param name="opCode">Instruction to be translated</param>
        /// <exception cref="InvalidOperationException">Throw when the instruction encoding is invalid</exception>
        private void EmitAluOp(int opCode)
        {
            AluOperation op = (AluOperation)(opCode & 7);

            switch (op)
            {
            case AluOperation.AluReg:
                EmitAluOp((AluRegOperation)((opCode >> 17) & 0x1f), opCode);
                break;

            case AluOperation.AddImmediate:
                EmitLoadGprA(opCode);
                EmitLoadImm(opCode);
                _ilGen.Emit(OpCodes.Add);
                break;

            case AluOperation.BitfieldReplace:
            case AluOperation.BitfieldExtractLslImm:
            case AluOperation.BitfieldExtractLslReg:
                int bfSrcBit = (opCode >> 17) & 0x1f;
                int bfSize   = (opCode >> 22) & 0x1f;
                int bfDstBit = (opCode >> 27) & 0x1f;

                int bfMask = (1 << bfSize) - 1;

                switch (op)
                {
                case AluOperation.BitfieldReplace:
                    EmitLoadGprB(opCode);
                    _ilGen.Emit(OpCodes.Ldc_I4, bfSrcBit);
                    _ilGen.Emit(OpCodes.Shr_Un);
                    _ilGen.Emit(OpCodes.Ldc_I4, bfMask);
                    _ilGen.Emit(OpCodes.And);
                    _ilGen.Emit(OpCodes.Ldc_I4, bfDstBit);
                    _ilGen.Emit(OpCodes.Shl);
                    EmitLoadGprA(opCode);
                    _ilGen.Emit(OpCodes.Ldc_I4, ~(bfMask << bfDstBit));
                    _ilGen.Emit(OpCodes.And);
                    _ilGen.Emit(OpCodes.Or);
                    break;

                case AluOperation.BitfieldExtractLslImm:
                    EmitLoadGprB(opCode);
                    EmitLoadGprA(opCode);
                    _ilGen.Emit(OpCodes.Shr_Un);
                    _ilGen.Emit(OpCodes.Ldc_I4, bfMask);
                    _ilGen.Emit(OpCodes.And);
                    _ilGen.Emit(OpCodes.Ldc_I4, bfDstBit);
                    _ilGen.Emit(OpCodes.Shl);
                    break;

                case AluOperation.BitfieldExtractLslReg:
                    EmitLoadGprB(opCode);
                    _ilGen.Emit(OpCodes.Ldc_I4, bfSrcBit);
                    _ilGen.Emit(OpCodes.Shr_Un);
                    _ilGen.Emit(OpCodes.Ldc_I4, bfMask);
                    _ilGen.Emit(OpCodes.And);
                    EmitLoadGprA(opCode);
                    _ilGen.Emit(OpCodes.Shl);
                    break;
                }
                break;

            case AluOperation.ReadImmediate:
                _ilGen.Emit(OpCodes.Ldarg_1);
                EmitLoadGprA(opCode);
                EmitLoadImm(opCode);
                _ilGen.Emit(OpCodes.Add);
                _ilGen.Emit(OpCodes.Call, typeof(MacroJitContext).GetMethod(nameof(MacroJitContext.Read)));
                break;

            default:
                throw new InvalidOperationException($"Invalid operation \"{op}\" on instruction 0x{opCode:X8}.");
            }
        }
Ejemplo n.º 3
0
        private int GetAluResult()
        {
            AluOperation op = (AluOperation)(_opCode & 7);

            switch (op)
            {
            case AluOperation.AluReg:
            {
                AluRegOperation aluOp = (AluRegOperation)((_opCode >> 17) & 0x1f);

                return(GetAluResult(aluOp, GetGprA(), GetGprB()));
            }

            case AluOperation.AddImmediate:
            {
                return(GetGprA() + GetImm());
            }

            case AluOperation.BitfieldReplace:
            case AluOperation.BitfieldExtractLslImm:
            case AluOperation.BitfieldExtractLslReg:
            {
                int bfSrcBit = (_opCode >> 17) & 0x1f;
                int bfSize   = (_opCode >> 22) & 0x1f;
                int bfDstBit = (_opCode >> 27) & 0x1f;

                int bfMask = (1 << bfSize) - 1;

                int dst = GetGprA();
                int src = GetGprB();

                switch (op)
                {
                case AluOperation.BitfieldReplace:
                {
                    src = (int)((uint)src >> bfSrcBit) & bfMask;

                    dst &= ~(bfMask << bfDstBit);

                    dst |= src << bfDstBit;

                    return(dst);
                }

                case AluOperation.BitfieldExtractLslImm:
                {
                    src = (int)((uint)src >> dst) & bfMask;

                    return(src << bfDstBit);
                }

                case AluOperation.BitfieldExtractLslReg:
                {
                    src = (int)((uint)src >> bfSrcBit) & bfMask;

                    return(src << dst);
                }
                }

                break;
            }

            case AluOperation.ReadImmediate:
            {
                return(Read(GetGprA() + GetImm()));
            }
            }

            throw new ArgumentException(nameof(_opCode));
        }
Ejemplo n.º 4
0
        private int GetAluResult()
        {
            AluOperation Op = (AluOperation)(OpCode & 7);

            switch (Op)
            {
            case AluOperation.AluReg:
            {
                AluRegOperation AluOp = (AluRegOperation)((OpCode >> 17) & 0x1f);

                return(GetAluResult(AluOp, GetGprA(), GetGprB()));
            }

            case AluOperation.AddImmediate:
            {
                return(GetGprA() + GetImm());
            }

            case AluOperation.BitfieldReplace:
            case AluOperation.BitfieldExtractLslImm:
            case AluOperation.BitfieldExtractLslReg:
            {
                int BfSrcBit = (OpCode >> 17) & 0x1f;
                int BfSize   = (OpCode >> 22) & 0x1f;
                int BfDstBit = (OpCode >> 27) & 0x1f;

                int BfMask = (1 << BfSize) - 1;

                int Dst = GetGprA();
                int Src = GetGprB();

                switch (Op)
                {
                case AluOperation.BitfieldReplace:
                {
                    Src = (int)((uint)Src >> BfSrcBit) & BfMask;

                    Dst &= ~(BfMask << BfDstBit);

                    Dst |= Src << BfDstBit;

                    return(Dst);
                }

                case AluOperation.BitfieldExtractLslImm:
                {
                    Src = (int)((uint)Src >> Dst) & BfMask;

                    return(Src << BfDstBit);
                }

                case AluOperation.BitfieldExtractLslReg:
                {
                    Src = (int)((uint)Src >> BfSrcBit) & BfMask;

                    return(Src << Dst);
                }
                }

                break;
            }

            case AluOperation.ReadImmediate:
            {
                return(Read(GetGprA() + GetImm()));
            }
            }

            throw new ArgumentException(nameof(OpCode));
        }