Example #1
0
        private static void GetBranchTarget(Instruction instruction, CodeContext context, GpRegister target)
        {
            var operand = instruction.Operands.First();

            switch (operand.Type)
            {
            case ud_type.UD_OP_REG:
                var maybeRegister = SdToAsm.SdToAsmJit(context, operand.Base);
                if (!maybeRegister.Present)
                {
                    throw new Exception("could not map register");
                }
                switch (maybeRegister.Type)
                {
                case RegisterType.GpRegister:
                    context.Mov(target, (GpRegister)maybeRegister.Register);
                    break;

                case RegisterType.SegRegister:
                    context.Mov(target, (SegRegister)maybeRegister.Register);
                    break;

                default:
                    throw new Exception("unsupported register");
                }
                break;

            case ud_type.UD_OP_MEM:
                CreateLea(context, target, instruction);
                break;

            case ud_type.UD_OP_JIMM:
                ulong immediate;
                ulong truncMask = 0xffffffffffffffff >> (64 - instruction.opr_mode);
                // Console.WriteLine($"opr_mode: {instruction.opr_mode}");
                switch (operand.Size)
                {
                case 8:
                    immediate = (instruction.PC + (ulong)operand.LvalSByte) & truncMask;
                    break;

                case 16:
                    immediate = (instruction.PC + (ulong)operand.LvalSWord) & truncMask;
                    break;

                case 32:
                    immediate = (instruction.PC + (ulong)operand.LvalSDWord) & truncMask;
                    break;

                default:
                    throw new Exception("invalid relative offset size.");
                }
                // in our emulator we are going to keep RIP in target (RAX)
                context.Lea(target, Memory.QWord(target, (int)immediate));
                break;

            default:
                throw new Exception("unsupported operand type");
            }
        }
Example #2
0
 protected override void Compile(CodeContext c)
 {
     c.Push(c.Ebp);
     c.Mov(c.Ebp, c.Esp);
     c.Sub(c.Esp, 192);
     c.Push(c.Ebx);
     c.Push(c.Esi);
     c.Push(c.Edi);
     c.Lea(c.Edi, Memory.DWord(c.Ebp, -192));
     c.Mov(c.Ecx, 48);
     c.Mov(c.Eax, -858993460);
     c.RepStosd();
     c.Mov(c.Eax, Memory.DWord(c.Ebp, 8));
     c.Add(c.Eax, Memory.DWord(c.Ebp, 12));
     c.Pop(c.Edi);
     c.Pop(c.Esi);
     c.Pop(c.Ebx);
     c.Mov(c.Esp, c.Ebp);
     c.Pop(c.Ebp);
     c.Ret(8);
 }
Example #3
0
        protected override void Compile(CodeContext c)
        {
            var dst = c.IntPtr("dst");
            var src = c.IntPtr("src");

            var i = c.IntPtr("i");
            var j = c.IntPtr("j");
            var t = c.IntPtr("t");

            var cZero    = c.Xmm("cZero");
            var cMul255A = c.Xmm("cMul255A");
            var cMul255M = c.Xmm("cMul255M");

            var x0 = c.Xmm("x0");
            var x1 = c.Xmm("x1");
            var y0 = c.Xmm("y0");
            var a0 = c.Xmm("a0");
            var a1 = c.Xmm("a1");

            var smallLoop = c.Label();
            var smallEnd  = c.Label();

            var largeLoop = c.Label();
            var largeEnd  = c.Label();

            var data = c.Label();

            c.SetArgument(0, dst);
            c.SetArgument(1, src);
            c.SetArgument(2, i);

            c.Allocate(dst);
            c.Allocate(src);
            c.Allocate(i);

            // How many pixels have to be processed to make the loop aligned.
            c.Lea(t, Memory.Ptr(data));
            c.Xor(j, j);
            c.Xorps(cZero, cZero);

            c.Sub(j, dst);
            c.Movaps(cMul255A, Memory.Ptr(t, 0));

            c.And(j, 15);
            c.Movaps(cMul255M, Memory.Ptr(t, 16));

            c.Shr(j, 2);
            c.Jz(smallEnd);

            // j = min(i, j).
            c.Cmp(j, i);
            c.Cmovg(j, i);

            // i -= j.
            c.Sub(i, j);

            // Small loop.
            c.Bind(smallLoop);

            c.Pcmpeqb(a0, a0);
            c.Movd(y0, Memory.Ptr(src));

            c.Pxor(a0, y0);
            c.Movd(x0, Memory.Ptr(dst));

            c.Psrlw(a0, 8);
            c.Punpcklbw(x0, cZero);

            c.Pshuflw(a0, a0, AsmJit.Common.Utils.Shuffle(1, 1, 1, 1));
            c.Punpcklbw(y0, cZero);

            c.Pmullw(x0, a0);
            c.Paddsw(x0, cMul255A);
            c.Pmulhuw(x0, cMul255M);

            c.Paddw(x0, y0);
            c.Packuswb(x0, x0);

            c.Movd(Memory.Ptr(dst), x0);

            c.Add(dst, 4);
            c.Add(src, 4);

            c.Dec(j);
            c.Jnz(smallLoop);

            // Second section, prepare for an aligned loop.
            c.Bind(smallEnd);

            c.Test(i, i);
            c.Mov(j, i);
            c.Jz(c.Exit);

            c.And(j, 3);
            c.Shr(i, 2);
            c.Jz(largeEnd);

            // Aligned loop.
            c.Bind(largeLoop);

            c.Movups(y0, Memory.Ptr(src));
            c.Pcmpeqb(a0, a0);
            c.Movaps(x0, Memory.Ptr(dst));

            c.Xorps(a0, y0);
            c.Movaps(x1, x0);

            c.Psrlw(a0, 8);
            c.Punpcklbw(x0, cZero);

            c.Movaps(a1, a0);
            c.Punpcklwd(a0, a0);

            c.Punpckhbw(x1, cZero);
            c.Punpckhwd(a1, a1);

            c.Pshufd(a0, a0, AsmJit.Common.Utils.Shuffle(3, 3, 1, 1));
            c.Pshufd(a1, a1, AsmJit.Common.Utils.Shuffle(3, 3, 1, 1));

            c.Pmullw(x0, a0);
            c.Pmullw(x1, a1);

            c.Paddsw(x0, cMul255A);
            c.Paddsw(x1, cMul255A);

            c.Pmulhuw(x0, cMul255M);
            c.Pmulhuw(x1, cMul255M);

            c.Add(src, 16);
            c.Packuswb(x0, x1);

            c.Paddw(x0, y0);
            c.Movaps(Memory.Ptr(dst), x0);

            c.Add(dst, 16);

            c.Dec(i);
            c.Jnz(largeLoop);

            c.Bind(largeEnd);
            c.Test(j, j);
            c.Jnz(smallLoop);

            // Data
            c.Data(data, 16,
                   Data.Of(0x0080008000800080, 0x0080008000800080),
                   Data.Of(0x0101010101010101, 0x0080008000800080));
        }
Example #4
0
        public static void CreateLea(CodeContext context, GpRegister target, Instruction instruction)
        {
            var           operand            = instruction.Operands.First();
            Memory        memoryReference    = null;
            GpRegister    baseRegister       = null;
            bool          baseRipRegister    = false;
            MaybeRegister maybeIndexRegister = null;

            if (operand.Base != ud_type.UD_NONE)
            {
                var maybeBaseRegister = SdToAsm.SdToAsmJit(context, operand.Base);
                if (!maybeBaseRegister.Present)
                {
                    throw new Exception($"could not map base register for: {instruction}");
                }
                if (maybeBaseRegister.Type != RegisterType.GpRegister)
                {
                    if (maybeBaseRegister.Type == RegisterType.RipRegister)
                    {
                        baseRipRegister = true;
                    }
                    else
                    {
                        throw new Exception("could not map base register to GpRegister");
                    }
                }
                else
                {
                    baseRegister = (GpRegister)maybeBaseRegister.Register;
                }
            }

            if (operand.Index != ud_type.UD_NONE)
            {
                maybeIndexRegister = SdToAsm.SdToAsmJit(context, operand.Index);
                if (!maybeIndexRegister.Present)
                {
                    throw new Exception("could not map base register");
                }
            }

            var displacement       = SdToAsm.GetDisplacement(instruction, operand);
            var displacementIntPtr = (IntPtr)displacement.Value;
            var scale = 0;

            switch (operand.Scale)
            {
            case 0:
            case 1:
                scale = 0;
                break;

            case 2:
                scale = 1;
                break;

            case 4:
                scale = 2;
                break;

            case 8:
                scale = 3;
                break;
            }

            if (baseRipRegister)
            {
                // in our emulator we are going to keep our RIP in target (RAX)
                baseRegister = target;
                if (maybeIndexRegister == null)
                {
                    switch (operand.Size)
                    {
                    case 8:
                        memoryReference = Memory.Byte(baseRegister, (int)displacement.Value);
                        break;

                    case 16:
                        memoryReference = Memory.Word(baseRegister, (int)displacement.Value);
                        break;

                    case 32:
                        memoryReference = Memory.DWord(baseRegister, (int)displacement.Value);
                        break;

                    case 64:
                        memoryReference = Memory.QWord(baseRegister, (int)displacement.Value);
                        break;

                    case 80:
                        memoryReference = Memory.TWord(baseRegister, (int)displacement.Value);
                        break;

                    default:
                        throw new Exception("unsupported operand size");
                    }
                }
                else
                {
                    throw new Exception("index register not supported when base register is RIP");
                }
            }
            else
            {
                if (baseRegister == null && maybeIndexRegister == null)
                {
                    switch (operand.Size)
                    {
                    case 8:
                        memoryReference = Memory.ByteAbs(displacementIntPtr);
                        break;

                    case 16:
                        memoryReference = Memory.WordAbs(displacementIntPtr);
                        break;

                    case 32:
                        memoryReference = Memory.DWordAbs(displacementIntPtr);
                        break;

                    case 64:
                        memoryReference = Memory.QWordAbs(displacementIntPtr);
                        break;

                    default:
                        throw new Exception("unsupported operand size");
                    }
                }
                else if (baseRegister != null && maybeIndexRegister == null)
                {
                    switch (operand.Size)
                    {
                    case 8:
                        memoryReference = Memory.Byte(baseRegister, (int)displacement.Value);
                        break;

                    case 16:
                        memoryReference = Memory.Word(baseRegister, (int)displacement.Value);
                        break;

                    case 32:
                        memoryReference = Memory.DWord(baseRegister, (int)displacement.Value);
                        break;

                    case 64:
                        memoryReference = Memory.QWord(baseRegister, (int)displacement.Value);
                        break;

                    case 80:
                        memoryReference = Memory.TWord(baseRegister, (int)displacement.Value);
                        break;

                    default:
                        throw new Exception("unsupported operand size");
                    }
                }
                else if (baseRegister == null)
                {
                    switch (operand.Size)
                    {
                    case 8:
                        switch (maybeIndexRegister.Type)
                        {
                        case RegisterType.MmRegister:
                            throw new Exception("mmregister not supported as index by asmjit");

                        case RegisterType.SegRegister:
                            throw new Exception("segregister not supported as index by asmjit");

                        case RegisterType.GpRegister:
                            memoryReference = Memory.ByteAbs(displacementIntPtr,
                                                             (GpRegister)maybeIndexRegister.Register, scale);
                            break;

                        case RegisterType.XmmRegister:
                            memoryReference = Memory.ByteAbs(displacementIntPtr,
                                                             (XmmRegister)maybeIndexRegister.Register, scale);
                            break;

                        case RegisterType.YmmRegister:
                            memoryReference = Memory.ByteAbs(displacementIntPtr,
                                                             (YmmRegister)maybeIndexRegister.Register, scale);
                            break;
                        }
                        break;

                    case 16:
                        switch (maybeIndexRegister.Type)
                        {
                        case RegisterType.MmRegister:
                            throw new Exception("mmregister not supported as index by asmjit");

                        case RegisterType.SegRegister:
                            throw new Exception("segregister not supported as index by asmjit");

                        case RegisterType.GpRegister:
                            memoryReference = Memory.WordAbs(displacementIntPtr,
                                                             (GpRegister)maybeIndexRegister.Register, scale);
                            break;

                        case RegisterType.XmmRegister:
                            memoryReference = Memory.WordAbs(displacementIntPtr,
                                                             (XmmRegister)maybeIndexRegister.Register, scale);
                            break;

                        case RegisterType.YmmRegister:
                            memoryReference = Memory.WordAbs(displacementIntPtr,
                                                             (YmmRegister)maybeIndexRegister.Register, scale);
                            break;
                        }
                        break;

                    case 32:
                        switch (maybeIndexRegister.Type)
                        {
                        case RegisterType.MmRegister:
                            throw new Exception("mmregister not supported as index by asmjit");

                        case RegisterType.SegRegister:
                            throw new Exception("segregister not supported as index by asmjit");

                        case RegisterType.GpRegister:
                            memoryReference = Memory.DWordAbs(displacementIntPtr,
                                                              (GpRegister)maybeIndexRegister.Register, scale);
                            break;

                        case RegisterType.XmmRegister:
                            memoryReference = Memory.DWordAbs(displacementIntPtr,
                                                              (XmmRegister)maybeIndexRegister.Register, scale);
                            break;

                        case RegisterType.YmmRegister:
                            memoryReference = Memory.DWordAbs(displacementIntPtr,
                                                              (YmmRegister)maybeIndexRegister.Register, scale);
                            break;
                        }
                        break;

                    case 64:
                        switch (maybeIndexRegister.Type)
                        {
                        case RegisterType.MmRegister:
                            throw new Exception("mmregister not supported as index by asmjit");

                        case RegisterType.SegRegister:
                            throw new Exception("segregister not supported as index by asmjit");

                        case RegisterType.GpRegister:
                            memoryReference = Memory.QWordAbs(displacementIntPtr,
                                                              (GpRegister)maybeIndexRegister.Register, scale);
                            break;

                        case RegisterType.XmmRegister:
                            memoryReference = Memory.QWordAbs(displacementIntPtr,
                                                              (XmmRegister)maybeIndexRegister.Register, scale);
                            break;

                        case RegisterType.YmmRegister:
                            memoryReference = Memory.QWordAbs(displacementIntPtr,
                                                              (YmmRegister)maybeIndexRegister.Register, scale);
                            break;
                        }
                        break;

                    case 80:
                        throw new Exception("unsupported operand size 80");

                    default:
                        throw new Exception("unsupported operand size");
                    }
                }
                else
                {
                    switch (operand.Size)
                    {
                    case 8:
                        switch (maybeIndexRegister.Type)
                        {
                        case RegisterType.MmRegister:
                            throw new Exception("mmregister not supported as index by asmjit");

                        case RegisterType.SegRegister:
                            throw new Exception("segregister not supported as index by asmjit");

                        case RegisterType.GpRegister:
                            memoryReference = Memory.Byte(baseRegister,
                                                          (GpRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;

                        case RegisterType.XmmRegister:
                            memoryReference = Memory.Byte(baseRegister,
                                                          (XmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;

                        case RegisterType.YmmRegister:
                            memoryReference = Memory.Byte(baseRegister,
                                                          (YmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;
                        }
                        break;

                    case 16:
                        switch (maybeIndexRegister.Type)
                        {
                        case RegisterType.MmRegister:
                            throw new Exception("mmregister not supported as index by asmjit");

                        case RegisterType.SegRegister:
                            throw new Exception("segregister not supported as index by asmjit");

                        case RegisterType.GpRegister:
                            memoryReference = Memory.Word(baseRegister,
                                                          (GpRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;

                        case RegisterType.XmmRegister:
                            memoryReference = Memory.Word(baseRegister,
                                                          (XmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;

                        case RegisterType.YmmRegister:
                            memoryReference = Memory.Word(baseRegister,
                                                          (YmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;
                        }
                        break;

                    case 32:
                        switch (maybeIndexRegister.Type)
                        {
                        case RegisterType.MmRegister:
                            throw new Exception("mmregister not supported as index by asmjit");

                        case RegisterType.SegRegister:
                            throw new Exception("segregister not supported as index by asmjit");

                        case RegisterType.GpRegister:
                            memoryReference = Memory.DWord(baseRegister,
                                                           (GpRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;

                        case RegisterType.XmmRegister:
                            memoryReference = Memory.DWord(baseRegister,
                                                           (XmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;

                        case RegisterType.YmmRegister:
                            memoryReference = Memory.DWord(baseRegister,
                                                           (YmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;
                        }
                        break;

                    case 64:
                        switch (maybeIndexRegister.Type)
                        {
                        case RegisterType.MmRegister:
                            throw new Exception("mmregister not supported as index by asmjit");

                        case RegisterType.SegRegister:
                            throw new Exception("segregister not supported as index by asmjit");

                        case RegisterType.GpRegister:
                            memoryReference = Memory.QWord(baseRegister,
                                                           (GpRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;

                        case RegisterType.XmmRegister:
                            memoryReference = Memory.QWord(baseRegister,
                                                           (XmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;

                        case RegisterType.YmmRegister:
                            memoryReference = Memory.QWord(baseRegister,
                                                           (YmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value);
                            break;
                        }
                        break;

                    case 80:
                        throw new Exception("unsupported operand size 80");

                    default:
                        throw new Exception("unsupported operand size");
                    }
                }
            }
            context.Lea(target, memoryReference);
        }