Exemple #1
0
        private int GetAluResult(AluRegOperation aluOp, int a, int b)
        {
            switch (aluOp)
            {
            case AluRegOperation.Add:
            {
                ulong result = (ulong)a + (ulong)b;

                _carry = result > 0xffffffff;

                return((int)result);
            }

            case AluRegOperation.AddWithCarry:
            {
                ulong result = (ulong)a + (ulong)b + (_carry ? 1UL : 0UL);

                _carry = result > 0xffffffff;

                return((int)result);
            }

            case AluRegOperation.Subtract:
            {
                ulong result = (ulong)a - (ulong)b;

                _carry = result < 0x100000000;

                return((int)result);
            }

            case AluRegOperation.SubtractWithBorrow:
            {
                ulong result = (ulong)a - (ulong)b - (_carry ? 0UL : 1UL);

                _carry = result < 0x100000000;

                return((int)result);
            }

            case AluRegOperation.BitwiseExclusiveOr: return(a ^ b);

            case AluRegOperation.BitwiseOr:          return(a | b);

            case AluRegOperation.BitwiseAnd:         return(a & b);

            case AluRegOperation.BitwiseAndNot:      return(a & ~b);

            case AluRegOperation.BitwiseNotAnd:      return(~(a & b));
            }

            throw new ArgumentOutOfRangeException(nameof(aluOp));
        }
        private int GetAluResult(AluRegOperation AluOp, int A, int B)
        {
            switch (AluOp)
            {
            case AluRegOperation.Add:
            {
                ulong Result = (ulong)A + (ulong)B;

                Carry = Result > 0xffffffff;

                return((int)Result);
            }

            case AluRegOperation.AddWithCarry:
            {
                ulong Result = (ulong)A + (ulong)B + (Carry ? 1UL : 0UL);

                Carry = Result > 0xffffffff;

                return((int)Result);
            }

            case AluRegOperation.Subtract:
            {
                ulong Result = (ulong)A - (ulong)B;

                Carry = Result < 0x100000000;

                return((int)Result);
            }

            case AluRegOperation.SubtractWithBorrow:
            {
                ulong Result = (ulong)A - (ulong)B - (Carry ? 0UL : 1UL);

                Carry = Result < 0x100000000;

                return((int)Result);
            }

            case AluRegOperation.BitwiseExclusiveOr: return(A ^ B);

            case AluRegOperation.BitwiseOr:          return(A | B);

            case AluRegOperation.BitwiseAnd:         return(A & B);

            case AluRegOperation.BitwiseAndNot:      return(A & ~B);

            case AluRegOperation.BitwiseNotAnd:      return(~(A & B));
            }

            throw new ArgumentOutOfRangeException(nameof(AluOp));
        }
Exemple #3
0
        /// <summary>
        /// Gets the result of an Arithmetic and Logic operation using registers.
        /// </summary>
        /// <param name="aluOp">Arithmetic and Logic unit operation with registers</param>
        /// <param name="a">First operand value</param>
        /// <param name="b">Second operand value</param>
        /// <returns>Operation result</returns>
        private int GetAluResult(AluRegOperation aluOp, int a, int b)
        {
            ulong result;

            switch (aluOp)
            {
            case AluRegOperation.Add:
                result = (ulong)a + (ulong)b;

                _carry = result > 0xffffffff;

                return((int)result);

            case AluRegOperation.AddWithCarry:
                result = (ulong)a + (ulong)b + (_carry ? 1UL : 0UL);

                _carry = result > 0xffffffff;

                return((int)result);

            case AluRegOperation.Subtract:
                result = (ulong)a - (ulong)b;

                _carry = result < 0x100000000;

                return((int)result);

            case AluRegOperation.SubtractWithBorrow:
                result = (ulong)a - (ulong)b - (_carry ? 0UL : 1UL);

                _carry = result < 0x100000000;

                return((int)result);

            case AluRegOperation.BitwiseExclusiveOr: return(a ^ b);

            case AluRegOperation.BitwiseOr: return(a | b);

            case AluRegOperation.BitwiseAnd: return(a & b);

            case AluRegOperation.BitwiseAndNot: return(a & ~b);

            case AluRegOperation.BitwiseNotAnd: return(~(a & b));
            }

            throw new InvalidOperationException($"Invalid operation \"{aluOp}\" on instruction 0x{_opCode:X8}.");
        }
Exemple #4
0
        /// <summary>
        /// Emits IL for a binary Arithmetic and Logic Unit instruction.
        /// </summary>
        /// <param name="aluOp">Arithmetic and Logic Unit instruction</param>
        /// <param name="opCode">Raw instruction</param>
        /// <exception cref="InvalidOperationException">Throw when the instruction encoding is invalid</exception>
        private void EmitAluOp(AluRegOperation aluOp, int opCode)
        {
            switch (aluOp)
            {
            case AluRegOperation.Add:
                EmitLoadGprA(opCode);
                _ilGen.Emit(OpCodes.Conv_U8);
                EmitLoadGprB(opCode);
                _ilGen.Emit(OpCodes.Conv_U8);
                _ilGen.Emit(OpCodes.Add);
                _ilGen.Emit(OpCodes.Dup);
                _ilGen.Emit(OpCodes.Ldc_I8, 0xffffffffL);
                _ilGen.Emit(OpCodes.Cgt_Un);
                _ilGen.Emit(OpCodes.Stloc, _carry);
                _ilGen.Emit(OpCodes.Conv_U4);
                break;

            case AluRegOperation.AddWithCarry:
                EmitLoadGprA(opCode);
                _ilGen.Emit(OpCodes.Conv_U8);
                EmitLoadGprB(opCode);
                _ilGen.Emit(OpCodes.Conv_U8);
                _ilGen.Emit(OpCodes.Ldloc_S, _carry);
                _ilGen.Emit(OpCodes.Conv_U8);
                _ilGen.Emit(OpCodes.Add);
                _ilGen.Emit(OpCodes.Add);
                _ilGen.Emit(OpCodes.Dup);
                _ilGen.Emit(OpCodes.Ldc_I8, 0xffffffffL);
                _ilGen.Emit(OpCodes.Cgt_Un);
                _ilGen.Emit(OpCodes.Stloc, _carry);
                _ilGen.Emit(OpCodes.Conv_U4);
                break;

            case AluRegOperation.Subtract:
                EmitLoadGprA(opCode);
                _ilGen.Emit(OpCodes.Conv_U8);
                EmitLoadGprB(opCode);
                _ilGen.Emit(OpCodes.Conv_U8);
                _ilGen.Emit(OpCodes.Sub);
                _ilGen.Emit(OpCodes.Dup);
                _ilGen.Emit(OpCodes.Ldc_I8, 0x100000000L);
                _ilGen.Emit(OpCodes.Clt_Un);
                _ilGen.Emit(OpCodes.Stloc, _carry);
                _ilGen.Emit(OpCodes.Conv_U4);
                break;

            case AluRegOperation.SubtractWithBorrow:
                EmitLoadGprA(opCode);
                _ilGen.Emit(OpCodes.Conv_U8);
                EmitLoadGprB(opCode);
                _ilGen.Emit(OpCodes.Conv_U8);
                _ilGen.Emit(OpCodes.Ldc_I4_1);
                _ilGen.Emit(OpCodes.Ldloc_S, _carry);
                _ilGen.Emit(OpCodes.Sub);
                _ilGen.Emit(OpCodes.Conv_U8);
                _ilGen.Emit(OpCodes.Sub);
                _ilGen.Emit(OpCodes.Sub);
                _ilGen.Emit(OpCodes.Dup);
                _ilGen.Emit(OpCodes.Ldc_I8, 0x100000000L);
                _ilGen.Emit(OpCodes.Clt_Un);
                _ilGen.Emit(OpCodes.Stloc, _carry);
                _ilGen.Emit(OpCodes.Conv_U4);
                break;

            case AluRegOperation.BitwiseExclusiveOr:
                EmitLoadGprA(opCode);
                EmitLoadGprB(opCode);
                _ilGen.Emit(OpCodes.Xor);
                break;

            case AluRegOperation.BitwiseOr:
                EmitLoadGprA(opCode);
                EmitLoadGprB(opCode);
                _ilGen.Emit(OpCodes.Or);
                break;

            case AluRegOperation.BitwiseAnd:
                EmitLoadGprA(opCode);
                EmitLoadGprB(opCode);
                _ilGen.Emit(OpCodes.And);
                break;

            case AluRegOperation.BitwiseAndNot:
                EmitLoadGprA(opCode);
                EmitLoadGprB(opCode);
                _ilGen.Emit(OpCodes.Not);
                _ilGen.Emit(OpCodes.And);
                break;

            case AluRegOperation.BitwiseNotAnd:
                EmitLoadGprA(opCode);
                EmitLoadGprB(opCode);
                _ilGen.Emit(OpCodes.And);
                _ilGen.Emit(OpCodes.Not);
                break;

            default:
                throw new InvalidOperationException($"Invalid operation \"{aluOp}\" on instruction 0x{opCode:X8}.");
            }
        }
Exemple #5
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));
        }
        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));
        }