Example #1
0
        static private IList <byte> generateOffset(AssemblyOperand operand, EnumOffsetType offsetType, out bool calleeSuccess)
        {
            IList <byte> result = new List <byte>();

            uint rm;

            calleeSuccess = false;

            if (operand.type == AssemblyOperand.EnumType.MEMORYSIMPLE)
            {
                if (offsetType == EnumOffsetType.NOOFFSET)
                {
                    result = new List <byte>();
                }
                else if (offsetType == EnumOffsetType.SINGLEBYTE)
                {
                    result = new List <byte>()
                    {
                        (byte)operand.offset
                    };
                }
                else if (offsetType == EnumOffsetType.FOURBYTES)
                {
                    /* commented because not translated from D
                     *              ubyte *pointerToOffset;
                     *
                     *              pointerToOffset = cast(ubyte*)&operand.offset;
                     *
                     *              result = [pointerToOffset[0], pointerToOffset[1], pointerToOffset[2], pointerToOffset[3]];
                     *
                     *              assert(false, "TODO");
                     */
                    throw new NotImplementedException("TODO");
                }


                calleeSuccess = true;
                return(result);
            }
            else if (operand.type == AssemblyOperand.EnumType.XMM || operand.type == AssemblyOperand.EnumType.GENERALREGISTER)
            {
                // we dont need any offset for an xmm or a general register
                calleeSuccess = true;
                return(new List <byte>());
            }
            else
            {
                return(new List <byte>());
            }

            throw new Exception("Unreachable!");
        }
Example #2
0
        static private byte generateRmByteAndGetOffsetType(AssemblyOperand operandLeft, int defaultReg, AssemblyOperand operandRight, bool in64BitMode, out EnumOffsetType offsetType, out bool calleeSuccess)
        {
            uint registerMaxIndex;
            uint reg, mod, rm;

            offsetType    = EnumOffsetType.NOOFFSET;
            calleeSuccess = false;

            if (in64BitMode)
            {
                registerMaxIndex = 16;
            }
            else
            {
                registerMaxIndex = 8;
            }

            if (defaultReg == -1)
            {
                if (operandLeft.type == AssemblyOperand.EnumType.XMM && operandLeft.xmmRegister <= registerMaxIndex)
                {
                    reg = operandLeft.xmmRegister;
                }
                else if (operandLeft.type == AssemblyOperand.EnumType.GENERALREGISTER && operandLeft.generalPurposeRegister <= registerMaxIndex)
                {
                    reg = operandLeft.generalPurposeRegister;
                }
                else
                {
                    return(0);
                }
            }
            else
            {
                Debug.Assert(defaultReg >= 0);
                reg = (uint)defaultReg;
            }

            if (operandRight.type == AssemblyOperand.EnumType.XMM)
            {
                if (operandRight.xmmRegister >= registerMaxIndex)
                {
                    return(0);
                }

                mod = 3;
                rm  = operandRight.xmmRegister;
            }
            else if (operandRight.type == AssemblyOperand.EnumType.GENERALREGISTER)
            {
                if (operandRight.generalPurposeRegister >= registerMaxIndex)
                {
                    return(0);
                }

                mod = 3;
                rm  = operandRight.generalPurposeRegister;
            }
            else if (operandRight.type == AssemblyOperand.EnumType.MEMORYSIMPLE)
            {
                if (operandRight.offset == 0)
                {
                    offsetType = EnumOffsetType.NOOFFSET;
                }
                else if (operandRight.offset <= 127 && operandRight.offset >= -128)
                {
                    offsetType = EnumOffsetType.SINGLEBYTE;
                }
                else
                {
                    offsetType = EnumOffsetType.FOURBYTES;
                }

                // TODO< force offset with hints if possible >


                if (offsetType == EnumOffsetType.NOOFFSET)
                {
                    mod = 0;
                }
                else if (offsetType == EnumOffsetType.SINGLEBYTE)
                {
                    mod = 1;
                }
                else if (offsetType == EnumOffsetType.FOURBYTES)
                {
                    mod = 2;
                }
                else
                {
                    throw new Exception("Unreachable!");
                }


                if (operandRight.register == AssemblyOperand.EnumRegister.EAX)
                {
                    rm = 0;
                }
                else if (operandRight.register == AssemblyOperand.EnumRegister.EBX)
                {
                    rm = 3;
                }
                else if (operandRight.register == AssemblyOperand.EnumRegister.ECX)
                {
                    rm = 1;
                }
                else if (operandRight.register == AssemblyOperand.EnumRegister.EDX)
                {
                    rm = 2;
                }
                else
                {
                    // possible todo or unimplemented
                    throw new Exception("Internal error!");
                }
            }
            else
            {
                // unimplemented, todo, internal error
                throw new Exception("Internal error!");
            }

            calleeSuccess = true;
            return((byte)(((mod & 3) << 6) | ((reg & 7) << 3) | (rm & 7)));
        }