Exemple #1
0
 private void MaybeUpdateFlags(Expression opDst)
 {
     if (instr.ArchitectureDetail.UpdateFlags)
     {
         m.Assign(frame.EnsureFlagGroup(A32Registers.cpsr, 0x1111, "NZCV", PrimitiveType.Byte), m.Cond(opDst));
     }
 }
Exemple #2
0
        /// <summary>
        /// Breaks up very common case of x86:
        /// <code>
        ///		op [memaddr], reg
        /// </code>
        /// into the equivalent:
        /// <code>
        ///		tmp := [memaddr] op reg;
        ///		store([memaddr], tmp);
        /// </code>
        /// </summary>
        /// <param name="opDst"></param>
        /// <param name="src"></param>
        /// <param name="forceBreak">if true, forcibly splits the assignments in two if the destination is a memory store.</param>
        /// <returns>Returns the destination of the copy.</returns>
        public void EmitCopy(MachineOperand opDst, Expression src, CopyFlags flags)
        {
            Expression dst   = SrcOp(opDst);
            Identifier idDst = dst as Identifier;

            if (idDst != null || (flags & CopyFlags.ForceBreak) == 0)
            {
                emitter.Assign(dst, src);
            }
            else
            {
                Identifier tmp = frame.CreateTemporary(opDst.Width);
                emitter.Assign(tmp, src);
                var ea = orw.CreateMemoryAccess(instrCur, (MemoryOperand)opDst, state);
                emitter.Assign(ea, tmp);
                dst = tmp;
            }
            if ((flags & CopyFlags.EmitCc) != 0)
            {
                EmitCcInstr(dst, X86Instruction.DefCc(instrCur.code));
            }
            if ((flags & CopyFlags.SetCfIf0) != 0)
            {
                emitter.Assign(orw.FlagGroup(FlagM.CF), emitter.Eq0(dst));
            }
        }
Exemple #3
0
        private void RewriteLoad(MipsInstruction instr)
        {
            var opSrc = RewriteOperand(instr.op2);
            var opDst = RewriteOperand(instr.op1);

            emitter.Assign(opDst, emitter.Cast(arch.WordWidth, opSrc));
        }
Exemple #4
0
        private void Push(Expression exp)
        {
            var sp = binder.EnsureRegister(arch.StackRegister);

            m.Assign(sp, m.ISub(sp, m.Int32(8)));
            m.Assign(m.Mem(exp.DataType, sp), exp);
        }
Exemple #5
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (instrs.MoveNext())
            {
                var instr      = instrs.Current;
                var rtlCluster = new RtlInstructionCluster(instr.Address, instr.Length);
                emitter = new RtlEmitter(rtlCluster.Instructions);
                switch (instr.Opcode)
                {
                default: throw new AddressCorrelatedException(
                              instr.Address,
                              "Rewriting of PDP-11 instruction {0} not supported yet.", instr.Opcode);

                case Opcodes.xor:
                    var src = RewriteSrc(instr.op1);
                    var dst = RewriteDst(instr.op2);
                    emitter.Assign(dst, emitter.Xor(dst, src));
                    emitter.Assign(
                        frame.EnsureFlagGroup((uint)(FlagM.NF | FlagM.ZF), "NZ", PrimitiveType.Byte),
                        emitter.Cond(dst));
                    emitter.Assign(frame.EnsureFlagGroup((uint)FlagM.CF, "C", PrimitiveType.Bool), Constant.False());
                    emitter.Assign(frame.EnsureFlagGroup((uint)FlagM.VF, "V", PrimitiveType.Bool), Constant.False());
                    break;
                }
                yield return(rtlCluster);
            }
        }
Exemple #6
0
        /// <summary>
        /// Generates assignments, with special-case logic to break up
        /// instructions where the destination is a memory address.
        /// </summary>
        /// <remarks>
        /// The special case breaks instructions that write to memory
        /// like this:
        /// <code>
        ///		op [memaddr], reg
        /// </code>
        /// into into the equivalent:
        /// <code>
        ///		tmp := [memaddr] op reg;
        ///		store([memaddr], tmp);
        /// </code>
        /// This makes analysis easier for the subsequent phases of the
        /// decompiler.
        /// </remarks>
        public void EmitCopy(MachineOperand opDst, Expression src, CopyFlags flags)
        {
            Expression dst = SrcOp(opDst);

            if (dst is Identifier idDst)
            {
                AssignToRegister(idDst, src);
            }
            else
            {
                var tmp = binder.CreateTemporary(opDst.Width);
                m.Assign(tmp, src);
                var ea = orw.CreateMemoryAccess(instrCur, (MemoryOperand)opDst, state);
                m.Assign(ea, tmp);
                dst = tmp;
            }
            if ((flags & CopyFlags.EmitCc) != 0)
            {
                EmitCcInstr(dst, X86Instruction.DefCc(instrCur.Mnemonic));
            }
            if ((flags & CopyFlags.SetCfIf0) != 0)
            {
                m.Assign(orw.FlagGroup(FlagM.CF), m.Eq0(dst));
            }
        }
Exemple #7
0
        private Expression DstOperand(int iOperand, Expression src)
        {
            switch (instr.Operands[iOperand])
            {
            case RegisterOperand rop:
                var dst = binder.EnsureRegister(rop.Register);
                m.Assign(dst, src);
                return(dst);

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                var ea = EffectiveAddress(mem);
                m.Assign(m.Mem(mem.Width, ea), src);
                return(src);

            case RegisterRange range:
                var extReg = ExtendedRegister(range);
                m.Assign(extReg, src);
                return(extReg);

            default:
                throw new NotImplementedException($"Operand type {instr.Operands[iOperand].GetType().Name}.");
            }
        }
Exemple #8
0
        private void RewriteAndNot()
        {
            var src1 = Operand(instr.Operands[1]);
            var dst  = Operand(instr.Operands[0]);

            m.Assign(dst, m.And(dst, m.Comp(src1)));
        }
Exemple #9
0
        private void Rewrite3(Func <Expression, Expression, Expression> fn)
        {
            var dst  = Rewrite(instrCur.Operands[0]);
            var src1 = Rewrite(instrCur.Operands[1]);
            var src2 = Rewrite(instrCur.Operands[2]);

            m.Assign(dst, fn(src1, src2));
        }
Exemple #10
0
 private void EmitCc(Expression dst)
 {
     m.Assign(
         binder.EnsureFlagGroup(
             arch.Registers.psr,
             0xF, "NZVC",
             PrimitiveType.Byte),
         m.Cond(dst));
 }
Exemple #11
0
        private Expression RewriteSrc(MachineOperand op)
        {
            var reg = op as RegisterOperand;

            if (reg != null)
            {
                return(binder.EnsureRegister(reg.Register));
            }
            var addr = op as AddressOperand;

            if (addr != null)
            {
                return(addr.Address);
            }
            var imm = op as ImmediateOperand;

            if (imm != null)
            {
                return(imm.Value);
            }
            var mem = op as MemoryOperand;

            if (mem != null)
            {
                Expression ea  = RewriteSrcEa(mem);
                var        tmp = binder.CreateTemporary(mem.Width);
                m.Assign(tmp, m.Mem(mem.Width, ea));
                return(tmp);
            }

            throw new NotImplementedException(op.GetType().Name);
        }
Exemple #12
0
        private Expression RewriteOp(int iOp)
        {
            switch (instr.Operands[iOp])
            {
            case RegisterOperand r:
                if (r.Register == arch.Registers.GpRegs[0])
                {
                    return(Constant.Zero(r.Register.DataType));
                }
                else
                {
                    return(binder.EnsureRegister(r.Register));
                }

            case ImmediateOperand i:
                return(i.Value);

            case LeftImmediateOperand l:
                return(l.Value);

            case AddressOperand a:
                return(a.Address);

            case MemoryOperand mem:
                Identifier rb = binder.EnsureRegister(mem.Base);
                Expression ea = rb;
                if (mem.Index != null)
                {
                    if (mem.Index != arch.Registers.GpRegs[0])
                    {
                        var idx = binder.EnsureRegister(mem.Index);
                        ea = m.IAdd(ea, idx);
                    }
                }
                else if (mem.Offset != 0)
                {
                    ea = m.IAddS(ea, mem.Offset);
                }
                if (instr.BaseReg == AddrRegMod.mb)
                {
                    m.Assign(rb, ea);
                    ea = rb;
                }
                else if (instr.BaseReg == AddrRegMod.ma)
                {
                    var tmp = binder.CreateTemporary(rb.DataType);
                    m.Assign(tmp, ea);
                    m.Assign(rb, tmp);
                    ea = tmp;
                }
                return(m.Mem(mem.Width, ea));
            }
            throw new NotImplementedException($"Unimplemented PA-RISC operand type {instr.Operands[iOp].GetType()}.");
        }
Exemple #13
0
        private void RewriteIntrinsic(string intrinsicName, bool isIntrinsic)
        {
            var dst  = Op(0);
            var args = Enumerable.Range(1, instrCur.Operands.Length - 1)
                       .Select(i => Op(i))
                       .ToArray();

            m.Assign(dst, host.Intrinsic(intrinsicName, isIntrinsic, dst.DataType, args));
        }
Exemple #14
0
 private void MaybeSignExtend(Expression dst, Expression src, DataType dt)
 {
     if (dt != null && dt.BitSize < dst.DataType.BitSize)
     {
         src = m.Cast(arch.NaturalSignedInteger, m.Cast(dt, src));
     }
     m.Assign(dst, src);
 }
Exemple #15
0
        void CheckForLoopExit()
        {
            if (lend == null)
            {
                return;
            }
            if (instr.Address.ToLinear() + (uint)instr.Length == lend.ToLinear())
            {
                var addrNext = instr.Address + instr.Length;
                var lcount   = binder.EnsureRegister(Registers.LCOUNT);
                m.BranchInMiddleOfInstruction(m.Eq0(lcount), addrNext, InstrClass.ConditionalTransfer);
                m.Assign(lcount, m.ISub(lcount, 1));
                m.Goto(this.lbegin);

                lbegin = null;
                lend   = null;
            }
        }
Exemple #16
0
        private void RewriteLet()
        {
            Expression lhs = ExpectLValue();

            Expect((byte)Token.eq);
            Expression rhs = ParseExpr();

            emitter.Assign(lhs, rhs);
        }
Exemple #17
0
 private void EmitCc(Expression dst)
 {
     emitter.Assign(
         frame.EnsureFlagGroup(
             Registers.psr,
             0xF, "NZVC",
             PrimitiveType.Byte),
         emitter.Cond(dst));
 }
Exemple #18
0
        private void RewriteBinary(MipsInstruction instr, Func <Expression, Expression, Expression> fn)
        {
            Expression dst, left, right;

            if (instr.Operands.Length == 2)
            {
                dst   = Rewrite(instr.Operands[0]);
                left  = dst;
                right = Rewrite(instr.Operands[1]);
            }
            else
            {
                dst   = Rewrite(instr.Operands[0]);
                left  = Rewrite(instr.Operands[1]);
                right = Rewrite(instr.Operands[2]);
            }
            m.Assign(dst, fn(left, right));
        }
Exemple #19
0
        public override List <RtlInstruction> InlineCall(
            IServiceProvider services,
            Address addrCallee,
            Address addrContinuation,
            EndianImageReader rdr,
            IStorageBinder binder)
        {
            var dasm   = CreateDisassembler(services, rdr, new X86Options());
            var instrs = dasm.Take(2).ToArray();

            if (instrs.Length < 2)
            {
                return(null);
            }
            // Detect the pattern
            //   mov <reg>,[esp+0]
            //   ret
            // which is used by i386 ELF binaries to capture
            // the value in the EIP register.

            if (instrs[0].Mnemonic == Mnemonic.mov &&
                instrs[1].Mnemonic == Mnemonic.ret)
            {
                if (!(instrs[0].Operands[1] is MemoryOperand mop))
                {
                    return(null);
                }
                if (mop.Base != StackRegister)
                {
                    return(null);
                }
                if (mop.Offset != null && mop.Offset.IsValid && !mop.Offset.IsIntegerZero)
                {
                    return(null);
                }
                if (mop.Index != null && mop.Index != RegisterStorage.None)
                {
                    return(null);
                }

                if (instrs[1].Operands.Length > 0)
                {
                    return(null);
                }
                var reg  = binder.EnsureRegister(((RegisterOperand)instrs[0].Operands[0]).Register);
                var rtls = new List <RtlInstruction>();
                var m    = new RtlEmitter(rtls);
                m.Assign(reg, addrContinuation);
                return(rtls);
            }
            return(null);
        }
Exemple #20
0
        private Expression Operand(ArmInstructionOperand op)
        {
            switch (op.Type)
            {
            case ArmInstructionOperandType.Register:
                var reg = frame.EnsureRegister(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value]);
                return(MaybeShiftOperand(reg, op));

            case ArmInstructionOperandType.Immediate:
                return(Constant.Word32(op.ImmediateValue.Value));

            case ArmInstructionOperandType.Memory:
                Expression baseReg = Reg(op.MemoryValue.BaseRegister);
                Expression ea      = baseReg;
                if (op.MemoryValue.BaseRegister == ArmRegister.PC)  // PC-relative address
                {
                    if (op.MemoryValue.Displacement != 0)
                    {
                        var dst = (uint)((int)instrs.Current.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u;
                        return(emitter.Load(SizeFromLoadStore(instr), Address.Ptr32(dst)));
                    }
                }
                if (op.MemoryValue.Displacement != 0 && instrs.Current.IsLastOperand(op))
                {
                    var offset = Constant.Int32(op.MemoryValue.Displacement);
                    ea = op.MemoryValue.IndexRegisterScale < 0
                        ? emitter.ISub(ea, offset)
                        : emitter.IAdd(ea, offset);
                }
                if (instrs.Current.IsLastOperand(op) && instr.ArchitectureDetail.WriteBack)
                {
                    emitter.Assign(baseReg, ea);
                    ea = baseReg;
                }
                return(emitter.Load(SizeFromLoadStore(instr), ea));
            }
            throw new NotImplementedException(op.Type.ToString());
        }
Exemple #21
0
        private Expression RewriteSrc(MachineOperand op)
        {
            var memOp = op as MemoryOperand;

            if (memOp != null)
            {
                var r   = frame.EnsureRegister(memOp.Register);
                var tmp = frame.CreateTemporary(op.Width);
                if (memOp.Mode == AddressMode.AutoIncr)
                {
                    emitter.Assign(tmp, emitter.Load(op.Width, r));
                    emitter.Assign(r, emitter.IAdd(r, memOp.Width.Size));
                    return(tmp);
                }
                return(tmp);
            }
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                return(frame.EnsureRegister(regOp.Register));
            }
            throw new NotImplementedException();
        }
Exemple #22
0
        public void EmitCc(Expression exp, string szhvnc)
        {
            // SZIH XVNC
            var  mask = 1u << 7;
            uint grf  = 0;

            foreach (var c in szhvnc)
            {
                switch (c)
                {
                case '*':
                case 'S':
                case 'Z':
                case 'I':
                case 'H':
                case 'X':
                case 'V':
                case 'N':
                case 'C':
                    grf |= mask;
                    break;

                case '0':
                    m.Assign(
                        binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, mask)),
                        Constant.False());
                    break;

                case '1':
                    m.Assign(
                        binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, mask)),
                        Constant.True());
                    break;
                }
                mask >>= 1;
            }
            if (grf != 0)
            {
                m.Assign(
                    binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, grf)),
                    m.Cond(exp));
            }
        }
Exemple #23
0
 private void SetFlags(Expression?e, FlagGroupStorage changed)
 {
     if (e == null)
     {
         Invalid();
         return;
     }
     if (changed != null)
     {
         var grfChanged = binder.EnsureFlagGroup(changed);
         m.Assign(grfChanged, m.Cond(e));
     }
 }
Exemple #24
0
        private Expression Assign(Expression dst, Expression src)
        {
            var excessBits = dst.DataType.BitSize - src.DataType.BitSize;

            if (excessBits > 0)
            {
                if (!(src is Identifier || src is Constant))
                {
                    var tmp = binder.CreateTemporary(src.DataType);
                    m.Assign(tmp, src);
                    src = tmp;
                }
                var seq = m.Dpb(dst, src, 0);
                m.Assign(dst, seq);
                return(seq.Expressions[1]);
            }
            else
            {
                m.Assign(dst, src);
                return(dst);
            }
        }
Exemple #25
0
        private Expression OpSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand reg:
                return(binder.EnsureRegister(reg.Register));

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Base != null)
                {
                    var regBase = binder.EnsureRegister(mem.Base);
                    if (mem.PostIncrement)
                    {
                        ea = binder.CreateTemporary(regBase.DataType);
                        m.Assign(ea, regBase);
                    }
                    else if (mem.PreDecrement)
                    {
                        m.Assign(regBase, m.ISubS(regBase, mem.Width.Size));
                        ea = regBase;
                    }
                    else
                    {
                        ea = m.AddSubSignedInt(regBase, mem.Offset);
                    }
                }
                else
                {
                    ea = Address.Ptr16((ushort)mem.Offset);
                }
                return(m.Mem(mem.Width ?? (DataType)VoidType.Instance, ea));
            }
            throw new NotImplementedException();
        }
Exemple #26
0
        private void NZCV(Expression test)
        {
            var nzcv = NZCV();

            m.Assign(nzcv, test);
        }
Exemple #27
0
        /// <summary>
        /// Iterator that yields one RtlIntructionCluster for each x86 instruction.
        /// </summary>
        /// <returns></returns>
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                instrCur = dasm.Current;
                var addr = instrCur.Address;
                this.rtlInstructions = new List <RtlInstruction>();
                this.iclass          = instrCur.InstructionClass;
                m   = new RtlEmitter(rtlInstructions);
                orw = arch.ProcessorMode.CreateOperandRewriter(arch, m, binder, host);
                switch (instrCur.Mnemonic)
                {
                default:
                    EmitUnitTest();
                    host.Warn(
                        dasm.Current.Address,
                        "x86 instruction '{0}' is not supported yet.",
                        instrCur.Mnemonic);
                    goto case Mnemonic.illegal;

                case Mnemonic.illegal: iclass = InstrClass.Invalid; m.Invalid(); break;

                case Mnemonic.aaa: RewriteAaa(); break;

                case Mnemonic.aad: RewriteAad(); break;

                case Mnemonic.aam: RewriteAam(); break;

                case Mnemonic.aas: RewriteAas(); break;

                case Mnemonic.adc: RewriteAdcSbb(m.IAdd); break;

                case Mnemonic.add: RewriteAddSub(Operator.IAdd); break;

                case Mnemonic.addss: RewriteScalarBinop(m.FAdd, PrimitiveType.Real32, false); break;

                case Mnemonic.vaddss: RewriteScalarBinop(m.FAdd, PrimitiveType.Real32, true); break;

                case Mnemonic.addsd: RewriteScalarBinop(m.FAdd, PrimitiveType.Real64, false); break;

                case Mnemonic.vaddsd: RewriteScalarBinop(m.FAdd, PrimitiveType.Real64, true); break;

                case Mnemonic.addps: RewritePackedBinop("__addps", PrimitiveType.Real32); break;

                case Mnemonic.addpd: RewritePackedBinop("__addpd", PrimitiveType.Real64); break;

                case Mnemonic.aesimc: RewriteAesimc(); break;

                case Mnemonic.and: RewriteLogical(Operator.And); break;

                case Mnemonic.andnps: RewriteAndnps(); break;

                case Mnemonic.andpd: RewritePackedBinop("__andpd", PrimitiveType.Real64); break;

                case Mnemonic.andps: RewritePackedBinop("__andps", PrimitiveType.Real32); break;

                case Mnemonic.arpl: RewriteArpl(); break;

                case Mnemonic.bound: RewriteBound(); break;

                case Mnemonic.bsf: RewriteBsf(); break;

                case Mnemonic.bsr: RewriteBsr(); break;

                case Mnemonic.bswap: RewriteBswap(); break;

                case Mnemonic.bt: RewriteBt(); break;

                case Mnemonic.btc: RewriteBtc(); break;

                case Mnemonic.btr: RewriteBtr(); break;

                case Mnemonic.bts: RewriteBts(); break;

                case Mnemonic.call: RewriteCall(instrCur.Operands[0], instrCur.Operands[0].Width); break;

                case Mnemonic.cbw: RewriteCbw(); break;

                case Mnemonic.cdq: RewriteCdq(); break;

                case Mnemonic.cdqe: RewriteCdqe(); break;

                case Mnemonic.cqo: RewriteCqo(); break;

                case Mnemonic.clc: RewriteSetFlag(FlagM.CF, Constant.False()); break;

                case Mnemonic.cld: RewriteSetFlag(FlagM.DF, Constant.False()); break;

                case Mnemonic.cli: RewriteCli(); break;

                case Mnemonic.clts: RewriteClts(); break;

                case Mnemonic.cmc: m.Assign(orw.FlagGroup(FlagM.CF), m.Not(orw.FlagGroup(FlagM.CF))); break;

                case Mnemonic.cmova: RewriteConditionalMove(ConditionCode.UGT, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovbe: RewriteConditionalMove(ConditionCode.ULE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovc: RewriteConditionalMove(ConditionCode.ULT, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovge: RewriteConditionalMove(ConditionCode.GE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovg: RewriteConditionalMove(ConditionCode.GT, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovl: RewriteConditionalMove(ConditionCode.LT, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovle: RewriteConditionalMove(ConditionCode.LE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovnc: RewriteConditionalMove(ConditionCode.UGE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovno: RewriteConditionalMove(ConditionCode.NO, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovns: RewriteConditionalMove(ConditionCode.NS, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovnz: RewriteConditionalMove(ConditionCode.NE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovo: RewriteConditionalMove(ConditionCode.OV, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovpe: RewriteConditionalMove(ConditionCode.PE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovpo: RewriteConditionalMove(ConditionCode.PO, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovs: RewriteConditionalMove(ConditionCode.SG, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovz: RewriteConditionalMove(ConditionCode.EQ, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmpxchg: RewriteCmpxchg(); break;

                case Mnemonic.cmpxchg8b: RewriteCmpxchgNb("__cmpxchg8b", Registers.edx, Registers.eax, Registers.ecx, Registers.ebx); break;

                case Mnemonic.cmpxchg16b: RewriteCmpxchgNb("__cmpxchg16b", Registers.rdx, Registers.rax, Registers.rcx, Registers.rbx); break;

                case Mnemonic.cmp: RewriteCmp(); break;

                case Mnemonic.cmps: RewriteStringInstruction(); break;

                case Mnemonic.cmppd: RewriteCmpp("__cmppd", PrimitiveType.Real64); break;

                case Mnemonic.cmpps: RewriteCmpp("__cmpps", PrimitiveType.Real32); break;

                case Mnemonic.cmpsb: RewriteStringInstruction(); break;

                case Mnemonic.comisd: RewriteComis(PrimitiveType.Real64); break;

                case Mnemonic.comiss: RewriteComis(PrimitiveType.Real32); break;

                case Mnemonic.cpuid: RewriteCpuid(); break;

                case Mnemonic.cvtpi2ps: RewriteCvtPackedToReal(PrimitiveType.Real32); break;

                case Mnemonic.cvtps2pi: RewriteCvtps2pi("__cvtps2pi", PrimitiveType.Real32, PrimitiveType.Int32); break;

                case Mnemonic.cvtps2pd: RewriteCvtps2pi("__cvtps2pd", PrimitiveType.Real32, PrimitiveType.Real64); break;

                case Mnemonic.cvtdq2ps: RewriteCvtps2pi("__cvtdq2ps", PrimitiveType.Int64, PrimitiveType.Real32); break;

                case Mnemonic.cvtsd2si: RewriteCvts2si(PrimitiveType.Real64); break;

                case Mnemonic.cvtsd2ss: RewriteCvtToReal(PrimitiveType.Real32); break;

                case Mnemonic.cvtsi2ss:
                case Mnemonic.vcvtsi2ss: RewriteCvtToReal(PrimitiveType.Real32); break;

                case Mnemonic.cvtsi2sd:
                case Mnemonic.vcvtsi2sd: RewriteCvtToReal(PrimitiveType.Real64); break;

                case Mnemonic.cvtss2sd: RewriteCvtToReal(PrimitiveType.Real64); break;

                case Mnemonic.cvtss2si: RewriteCvts2si(PrimitiveType.Real32); break;

                case Mnemonic.cvttsd2si: RewriteCvtts2si(PrimitiveType.Real64); break;

                case Mnemonic.cvttss2si: RewriteCvtts2si(PrimitiveType.Real32); break;

                case Mnemonic.cvttps2pi: RewriteCvttps2pi(); break;

                case Mnemonic.cwd: RewriteCwd(); break;

                case Mnemonic.cwde: RewriteCwde(); break;

                case Mnemonic.daa: EmitDaaDas("__daa"); break;

                case Mnemonic.das: EmitDaaDas("__das"); break;

                case Mnemonic.dec: RewriteIncDec(-1); break;

                case Mnemonic.div: RewriteDivide(m.UDiv, Domain.UnsignedInt); break;

                case Mnemonic.divps: RewritePackedBinop("__divps", PrimitiveType.Real32); break;

                case Mnemonic.divsd: RewriteScalarBinop(m.FDiv, PrimitiveType.Real64, false); break;

                case Mnemonic.vdivsd: RewriteScalarBinop(m.FDiv, PrimitiveType.Real64, true); break;

                case Mnemonic.divss: RewriteScalarBinop(m.FDiv, PrimitiveType.Real32, false); break;

                case Mnemonic.vdivss: RewriteScalarBinop(m.FDiv, PrimitiveType.Real32, true); break;

                case Mnemonic.f2xm1: RewriteF2xm1(); break;

                case Mnemonic.emms: RewriteEmms(); break;

                case Mnemonic.enter: RewriteEnter(); break;

                case Mnemonic.fabs: RewriteFabs(); break;

                case Mnemonic.fadd: EmitCommonFpuInstruction(m.FAdd, false, false); break;

                case Mnemonic.faddp: EmitCommonFpuInstruction(m.FAdd, false, true); break;

                case Mnemonic.fbld: RewriteFbld(); break;

                case Mnemonic.fbstp: RewriteFbstp(); break;

                case Mnemonic.fchs: EmitFchs(); break;

                case Mnemonic.fclex: RewriteFclex(); break;

                case Mnemonic.fcmovb: RewriteFcmov(FlagM.CF, ConditionCode.GE); break;

                case Mnemonic.fcmovbe: RewriteFcmov(FlagM.CF | FlagM.ZF, ConditionCode.GT); break;

                case Mnemonic.fcmove: RewriteFcmov(FlagM.ZF, ConditionCode.NE); break;

                case Mnemonic.fcmovnb: RewriteFcmov(FlagM.CF | FlagM.ZF, ConditionCode.GE); break;

                case Mnemonic.fcmovnbe: RewriteFcmov(FlagM.CF | FlagM.ZF, ConditionCode.LE); break;

                case Mnemonic.fcmovne: RewriteFcmov(FlagM.ZF, ConditionCode.EQ); break;

                case Mnemonic.fcmovnu: RewriteFcmov(FlagM.PF, ConditionCode.IS_NAN); break;

                case Mnemonic.fcmovu: RewriteFcmov(FlagM.PF, ConditionCode.NOT_NAN); break;

                case Mnemonic.fcom: RewriteFcom(0); break;

                case Mnemonic.fcomi: RewriteFcomi(false); break;

                case Mnemonic.fcomip: RewriteFcomi(true); break;

                case Mnemonic.fcomp: RewriteFcom(1); break;

                case Mnemonic.fcompp: RewriteFcom(2); break;

                case Mnemonic.fcos: RewriteFUnary("cos"); break;

                case Mnemonic.fdecstp: RewriteFdecstp(); break;

                case Mnemonic.fdiv: EmitCommonFpuInstruction(m.FDiv, false, false); break;

                case Mnemonic.fdivp: EmitCommonFpuInstruction(m.FDiv, false, true); break;

                case Mnemonic.femms: RewriteFemms(); break;

                case Mnemonic.ffree: RewriteFfree(false); break;

                case Mnemonic.ffreep: RewriteFfree(true); break;

                case Mnemonic.fiadd: EmitCommonFpuInstruction(m.FAdd, false, false, PrimitiveType.Real64); break;

                case Mnemonic.ficom: RewriteFicom(false); break;

                case Mnemonic.ficomp: RewriteFicom(true); break;

                case Mnemonic.fimul: EmitCommonFpuInstruction(m.FMul, false, false, PrimitiveType.Real64); break;

                case Mnemonic.fisub: EmitCommonFpuInstruction(m.FSub, false, false, PrimitiveType.Real64); break;

                case Mnemonic.fisubr: EmitCommonFpuInstruction(m.FSub, true, false, PrimitiveType.Real64); break;

                case Mnemonic.fidiv: EmitCommonFpuInstruction(m.FDiv, false, false, PrimitiveType.Real64); break;

                case Mnemonic.fidivr: EmitCommonFpuInstruction(m.FDiv, true, false, PrimitiveType.Real64); break;

                case Mnemonic.fdivr: EmitCommonFpuInstruction(m.FDiv, true, false); break;

                case Mnemonic.fdivrp: EmitCommonFpuInstruction(m.FDiv, true, true); break;

                case Mnemonic.fild: RewriteFild(); break;

                case Mnemonic.fincstp: RewriteFincstp(); break;

                case Mnemonic.fist: RewriteFist(false); break;

                case Mnemonic.fistp: RewriteFist(true); break;

                case Mnemonic.fisttp: RewriteFistt(true); break;

                case Mnemonic.fld: RewriteFld(); break;

                case Mnemonic.fld1: RewriteFldConst(1.0); break;

                case Mnemonic.fldcw: RewriteFldcw(); break;

                case Mnemonic.fldenv: RewriteFldenv(); break;

                case Mnemonic.fldl2e: RewriteFldConst(Constant.LgE()); break;

                case Mnemonic.fldl2t: RewriteFldConst(Constant.Lg10()); break;

                case Mnemonic.fldlg2: RewriteFldConst(Constant.Log2()); break;

                case Mnemonic.fldln2: RewriteFldConst(Constant.Ln2()); break;

                case Mnemonic.fldpi: RewriteFldConst(Constant.Pi()); break;

                case Mnemonic.fldz: RewriteFldConst(0.0); break;

                case Mnemonic.fmul: EmitCommonFpuInstruction(m.FMul, false, false); break;

                case Mnemonic.fmulp: EmitCommonFpuInstruction(m.FMul, false, true); break;

                case Mnemonic.fninit: RewriteFninit(); break;

                case Mnemonic.fnop: m.Nop(); break;

                case Mnemonic.fnsetpm: m.Nop(); break;

                case Mnemonic.fpatan: RewriteFpatan(); break;

                case Mnemonic.fprem: RewriteFprem(); break;

                case Mnemonic.fprem1: RewriteFprem1(); break;

                case Mnemonic.fptan: RewriteFptan(); break;

                case Mnemonic.frndint: RewriteFUnary("__rndint"); break;

                case Mnemonic.frstor: RewriteFrstor(); break;

                case Mnemonic.fsave: RewriteFsave(); break;

                case Mnemonic.fscale: RewriteFscale(); break;

                case Mnemonic.fsin: RewriteFUnary("sin"); break;

                case Mnemonic.fsincos: RewriteFsincos(); break;

                case Mnemonic.fsqrt: RewriteFUnary("sqrt"); break;

                case Mnemonic.fst: RewriteFst(false); break;

                case Mnemonic.fstenv: RewriteFstenv(); break;

                case Mnemonic.fstcw: RewriterFstcw(); break;

                case Mnemonic.fstp: RewriteFst(true); break;

                case Mnemonic.fstsw: RewriteFstsw(); break;

                case Mnemonic.fsub: EmitCommonFpuInstruction(m.FSub, false, false); break;

                case Mnemonic.fsubp: EmitCommonFpuInstruction(m.FSub, false, true); break;

                case Mnemonic.fsubr: EmitCommonFpuInstruction(m.FSub, true, false); break;

                case Mnemonic.fsubrp: EmitCommonFpuInstruction(m.FSub, true, true); break;

                case Mnemonic.ftst: RewriteFtst(); break;

                case Mnemonic.fucom: RewriteFcom(0); break;

                case Mnemonic.fucomp: RewriteFcom(1); break;

                case Mnemonic.fucompp: RewriteFcom(2); break;

                case Mnemonic.fucomi: RewriteFcomi(false); break;

                case Mnemonic.fucomip: RewriteFcomi(true); break;

                case Mnemonic.fxam: RewriteFxam(); break;

                case Mnemonic.fxch: RewriteExchange(); break;

                case Mnemonic.fxtract: RewriteFxtract(); break;

                case Mnemonic.fyl2x: RewriteFyl2x(); break;

                case Mnemonic.fyl2xp1: RewriteFyl2xp1(); break;

                case Mnemonic.getsec: RewriteGetsec(); break;

                case Mnemonic.hlt: RewriteHlt(); break;

                case Mnemonic.icebp: RewriteIcebp(); break;

                case Mnemonic.idiv: RewriteDivide(m.SDiv, Domain.SignedInt); break;

                case Mnemonic.@in: RewriteIn(); break;

                case Mnemonic.imul: RewriteMultiply(Operator.SMul, Domain.SignedInt); break;

                case Mnemonic.inc: RewriteIncDec(1); break;

                case Mnemonic.insb: RewriteStringInstruction(); break;

                case Mnemonic.ins: RewriteStringInstruction(); break;

                case Mnemonic.invlpg: RewriteInvlpg(); break;

                case Mnemonic.@int: RewriteInt(); break;

                case Mnemonic.into: RewriteInto(); break;

                case Mnemonic.invd: RewriteInvd(); break;

                case Mnemonic.iret: RewriteIret(); break;

                case Mnemonic.jmp: RewriteJmp(); break;

                case Mnemonic.jmpe: RewriteJmpe(); break;

                case Mnemonic.ja: RewriteConditionalGoto(ConditionCode.UGT, instrCur.Operands[0]); break;

                case Mnemonic.jbe: RewriteConditionalGoto(ConditionCode.ULE, instrCur.Operands[0]); break;

                case Mnemonic.jc: RewriteConditionalGoto(ConditionCode.ULT, instrCur.Operands[0]); break;

                case Mnemonic.jcxz: RewriteJcxz(Registers.cx); break;

                case Mnemonic.jecxz: RewriteJcxz(Registers.ecx); break;

                case Mnemonic.jge: RewriteConditionalGoto(ConditionCode.GE, instrCur.Operands[0]); break;

                case Mnemonic.jg: RewriteConditionalGoto(ConditionCode.GT, instrCur.Operands[0]); break;

                case Mnemonic.jl: RewriteConditionalGoto(ConditionCode.LT, instrCur.Operands[0]); break;

                case Mnemonic.jle: RewriteConditionalGoto(ConditionCode.LE, instrCur.Operands[0]); break;

                case Mnemonic.jnc: RewriteConditionalGoto(ConditionCode.UGE, instrCur.Operands[0]); break;

                case Mnemonic.jno: RewriteConditionalGoto(ConditionCode.NO, instrCur.Operands[0]); break;

                case Mnemonic.jns: RewriteConditionalGoto(ConditionCode.NS, instrCur.Operands[0]); break;

                case Mnemonic.jnz: RewriteConditionalGoto(ConditionCode.NE, instrCur.Operands[0]); break;

                case Mnemonic.jo: RewriteConditionalGoto(ConditionCode.OV, instrCur.Operands[0]); break;

                case Mnemonic.jpe: RewriteConditionalGoto(ConditionCode.PE, instrCur.Operands[0]); break;

                case Mnemonic.jpo: RewriteConditionalGoto(ConditionCode.PO, instrCur.Operands[0]); break;

                case Mnemonic.jrcxz: RewriteJcxz(Registers.rcx); break;

                case Mnemonic.js: RewriteConditionalGoto(ConditionCode.SG, instrCur.Operands[0]); break;

                case Mnemonic.jz: RewriteConditionalGoto(ConditionCode.EQ, instrCur.Operands[0]); break;

                case Mnemonic.lahf: RewriteLahf(); break;

                case Mnemonic.lar: RewriteLar(); break;

                case Mnemonic.lds: RewriteLxs(Registers.ds); break;

                case Mnemonic.ldmxcsr: RewriteLdmxcsr(); break;

                case Mnemonic.stmxcsr: RewriteStmxcsr(); break;

                case Mnemonic.lea: RewriteLea(); break;

                case Mnemonic.leave: RewriteLeave(); break;

                case Mnemonic.les: RewriteLxs(Registers.es); break;

                case Mnemonic.lfence: RewriteLfence(); break;

                case Mnemonic.lfs: RewriteLxs(Registers.fs); break;

                case Mnemonic.lgs: RewriteLxs(Registers.gs); break;

                case Mnemonic.lgdt: RewriteLxdt("__lgdt"); break;

                case Mnemonic.lidt: RewriteLxdt("__lidt"); break;

                case Mnemonic.lldt: RewriteLxdt("__lldt"); break;

                case Mnemonic.lmsw: RewriteLmsw(); break;

                case Mnemonic.@lock: RewriteLock(); break;

                case Mnemonic.lods: RewriteStringInstruction(); break;

                case Mnemonic.lodsb: RewriteStringInstruction(); break;

                case Mnemonic.loop: RewriteLoop(0, ConditionCode.EQ); break;

                case Mnemonic.loope: RewriteLoop(FlagM.ZF, ConditionCode.EQ); break;

                case Mnemonic.loopne: RewriteLoop(FlagM.ZF, ConditionCode.NE); break;

                case Mnemonic.lsl: RewriteLsl(); break;

                case Mnemonic.lss: RewriteLxs(Registers.ss); break;

                case Mnemonic.ltr: RewriteLtr(); break;

                case Mnemonic.maskmovq: RewriteMaskmovq(); break;

                case Mnemonic.maxps: RewritePackedBinop("__maxps", PrimitiveType.Real32); break;

                case Mnemonic.mfence: RewriteMfence(); break;

                case Mnemonic.minpd: RewritePackedBinop("__minpd", PrimitiveType.Real64); break;

                case Mnemonic.minps: RewritePackedBinop("__minps", PrimitiveType.Real32); break;

                case Mnemonic.mov: RewriteMov(); break;

                case Mnemonic.movapd:
                case Mnemonic.movaps:
                case Mnemonic.vmovapd:
                case Mnemonic.vmovaps: RewriteMov(); break;

                case Mnemonic.vmread: RewriteVmread(); break;

                case Mnemonic.vmwrite: RewriteVmwrite(); break;

                case Mnemonic.movbe: RewriteMovbe(); break;

                case Mnemonic.movd: RewriteMovzx(); break;

                case Mnemonic.movdqa:
                case Mnemonic.vmovdqa:
                    RewriteMov(); break;

                case Mnemonic.movhpd: RewritePackedUnaryop("__movhpd", PrimitiveType.Real64, PrimitiveType.Real64); break;

                case Mnemonic.movhps: RewritePackedUnaryop("__movhps", PrimitiveType.Real32, PrimitiveType.Real64); break;

                case Mnemonic.movlpd: RewritePackedUnaryop("__movlpd", PrimitiveType.Real64, PrimitiveType.Real64); break;

                case Mnemonic.movlps: RewritePackedUnaryop("__movlps", PrimitiveType.Real32, PrimitiveType.Real64); break;

                case Mnemonic.movlhps: RewriteMovlhps(); break;

                case Mnemonic.movmskpd: RewriteMovmsk("__movmskpd", PrimitiveType.Real64); break;

                case Mnemonic.movmskps: RewriteMovmsk("__movmskps", PrimitiveType.Real32); break;

                case Mnemonic.movnti: RewriteMov(); break;

                case Mnemonic.movntps: RewriteMov(); break;

                case Mnemonic.movntq: RewriteMov(); break;

                case Mnemonic.movq: RewriteMov(); break;

                case Mnemonic.movs: RewriteStringInstruction(); break;

                case Mnemonic.movsb: RewriteStringInstruction(); break;

                case Mnemonic.movsd:
                case Mnemonic.vmovsd: RewriteMovssd(PrimitiveType.Real64); break;

                case Mnemonic.movss:
                case Mnemonic.vmovss: RewriteMovssd(PrimitiveType.Real32); break;

                case Mnemonic.movsx: RewriteMovsx(); break;

                case Mnemonic.movsxd: RewriteMovsx(); break;

                case Mnemonic.movups: RewriteMov(); break;

                case Mnemonic.movupd: RewriteMov(); break;

                case Mnemonic.movzx: RewriteMovzx(); break;

                case Mnemonic.mul: RewriteMultiply(Operator.UMul, Domain.UnsignedInt); break;

                case Mnemonic.mulpd: RewritePackedBinop("__mulpd", PrimitiveType.Real64); break;

                case Mnemonic.mulps: RewritePackedBinop("__mulps", PrimitiveType.Real32); break;

                case Mnemonic.mulsd: RewriteScalarBinop(m.FMul, PrimitiveType.Real64, false); break;

                case Mnemonic.vmulsd: RewriteScalarBinop(m.FMul, PrimitiveType.Real64, true); break;

                case Mnemonic.mulss: RewriteScalarBinop(m.FMul, PrimitiveType.Real32, false); break;

                case Mnemonic.vmulss: RewriteScalarBinop(m.FMul, PrimitiveType.Real32, true); break;

                case Mnemonic.neg: RewriteNeg(); break;

                case Mnemonic.nop: m.Nop(); break;

                case Mnemonic.not: RewriteNot(); break;

                case Mnemonic.or: RewriteLogical(BinaryOperator.Or); break;

                case Mnemonic.orpd: RewritePackedBinop("__orpd", PrimitiveType.Real64); break;

                case Mnemonic.orps: RewritePackedBinop("__orps", PrimitiveType.Real32); break;

                case Mnemonic.@out: RewriteOut(); break;

                case Mnemonic.@outs: RewriteStringInstruction(); break;

                case Mnemonic.@outsb: RewriteStringInstruction(); break;

                case Mnemonic.packssdw: RewritePackedBinop("__packssdw", PrimitiveType.Int32, new ArrayType(PrimitiveType.Int16, 0)); break;

                case Mnemonic.packuswb: RewritePackedBinop("__packuswb", PrimitiveType.UInt16, new ArrayType(PrimitiveType.UInt8, 0)); break;

                case Mnemonic.paddb: RewritePackedBinop("__paddb", PrimitiveType.Byte); break;

                case Mnemonic.paddd: RewritePackedBinop("__paddd", PrimitiveType.Word32); break;

                case Mnemonic.paddq:
                case Mnemonic.vpaddq: RewritePackedBinop("__paddq", PrimitiveType.Word64); break;

                case Mnemonic.paddsw: RewritePackedBinop("__paddsw", PrimitiveType.Word16); break;

                case Mnemonic.paddsb: RewritePackedBinop("__paddsb", PrimitiveType.SByte); break;

                case Mnemonic.paddusb: RewritePackedBinop("__paddusb", PrimitiveType.Byte); break;

                case Mnemonic.paddusw: RewritePackedBinop("__paddsw", PrimitiveType.Word16); break;

                case Mnemonic.paddw: RewritePackedBinop("__paddw", PrimitiveType.Word16); break;

                case Mnemonic.pand:
                case Mnemonic.vpand: RewritePackedLogical("__pand"); break;

                case Mnemonic.pandn:
                case Mnemonic.vpandn: RewritePackedLogical("__pandn"); break;

                case Mnemonic.pause: RewritePause(); break;

                case Mnemonic.palignr: RewritePalignr(); break;

                case Mnemonic.pavgb: RewritePavg("__pavgb", PrimitiveType.Byte); break;

                case Mnemonic.pavgw: RewritePavg("__pavgw", PrimitiveType.Byte); break;

                case Mnemonic.pcmpeqb: RewritePcmp("__pcmpeqb", PrimitiveType.Byte); break;

                case Mnemonic.pcmpeqd: RewritePcmp("__pcmpeqd", PrimitiveType.Word32); break;

                case Mnemonic.pcmpeqw: RewritePcmp("__pcmpeqw", PrimitiveType.Word16); break;

                case Mnemonic.pcmpgtb: RewritePcmp("__pcmpgtb", PrimitiveType.Byte); break;

                case Mnemonic.pcmpgtd: RewritePcmp("__pcmpgtd", PrimitiveType.Word32); break;

                case Mnemonic.pcmpgtw: RewritePcmp("__pcmpgtw", PrimitiveType.Word16); break;

                case Mnemonic.pextrw:
                case Mnemonic.vextrw:  RewritePextrw(); break;

                case Mnemonic.pinsrw:
                case Mnemonic.vpinsrw: RewritePinsrw(); break;

                case Mnemonic.pmaddwd: RewritePackedBinop("__pmaddwd", PrimitiveType.Word16, new ArrayType(PrimitiveType.Word32, 0)); break;

                case Mnemonic.pmaxsw: RewritePackedBinop("__pmaxsw", PrimitiveType.Int16); break;

                case Mnemonic.pmaxub: RewritePackedBinop("__pmaxub", PrimitiveType.UInt8); break;

                case Mnemonic.pminsw: RewritePackedBinop("__pminsw", PrimitiveType.Int16); break;

                case Mnemonic.pminub: RewritePackedBinop("__pminub", PrimitiveType.UInt8); break;

                case Mnemonic.pmovmskb: RewriteMovmsk("__pmovmskb", PrimitiveType.Byte); break;

                case Mnemonic.pmulhuw: RewritePackedBinop("__pmulhuw", PrimitiveType.UInt16, new ArrayType(PrimitiveType.UInt16, 8)); break;

                case Mnemonic.pmulhw: RewritePackedBinop("__pmulhw", PrimitiveType.Int16, new ArrayType(PrimitiveType.Int16, 8)); break;

                case Mnemonic.pmullw:
                case Mnemonic.vpmullw: RewritePackedBinop("__pmullw", PrimitiveType.Int16, new ArrayType(PrimitiveType.Int16, 8)); break;

                case Mnemonic.pmuludq: RewritePackedBinop("__pmuludq", PrimitiveType.UInt32, new ArrayType(PrimitiveType.UInt64, 0)); break;

                case Mnemonic.prefetchw: RewritePrefetch("__prefetchw"); break;

                case Mnemonic.psadbw: RewritePackedBinop("__psadbw", PrimitiveType.Byte, PrimitiveType.Word16); break;

                case Mnemonic.pslld: RewritePackedBinop("__pslld", PrimitiveType.Word32); break;

                case Mnemonic.psllq:
                case Mnemonic.vpsllq: RewritePackedBinop("__psllq", PrimitiveType.Word64); break;

                case Mnemonic.psllw: RewritePackedBinop("__psllw", PrimitiveType.Word16); break;

                case Mnemonic.psrad: RewritePackedBinop("__psrad", PrimitiveType.Int32); break;

                case Mnemonic.psraw: RewritePackedBinop("__psraw", PrimitiveType.Int16); break;

                case Mnemonic.psrlq: RewritePackedBinop("__psrlq", PrimitiveType.Word64); break;

                case Mnemonic.pop: RewritePop(); break;

                case Mnemonic.popa: RewritePopa(); break;

                case Mnemonic.popf: RewritePopf(); break;

                case Mnemonic.por: RewritePackedLogical("__por"); break;

                case Mnemonic.prefetchnta: RewritePrefetch("__prefetchnta"); break;

                case Mnemonic.prefetcht0: RewritePrefetch("__prefetcht0"); break;

                case Mnemonic.prefetcht1: RewritePrefetch("__prefetcht1"); break;

                case Mnemonic.prefetcht2: RewritePrefetch("__prefetcht2"); break;

                case Mnemonic.pshufd: RewritePshuf("__pshufd", PrimitiveType.Word32); break;

                case Mnemonic.pshufw: RewritePshuf("__pshufw", PrimitiveType.Word16); break;

                case Mnemonic.psrld: RewritePackedShift("__psrld", PrimitiveType.Word32); break;

                case Mnemonic.psrlw: RewritePackedShift("__psrlw", PrimitiveType.Word16); break;

                case Mnemonic.psubb: RewritePackedBinop("__psubb", PrimitiveType.Byte); break;

                case Mnemonic.psubd:
                case Mnemonic.vpsubd: RewritePackedBinop("__psubd", PrimitiveType.Word32); break;

                case Mnemonic.psubq: RewritePackedBinop("__psubq", PrimitiveType.Word64); break;

                case Mnemonic.psubsb: RewritePackedBinop("__psubsb", PrimitiveType.SByte); break;

                case Mnemonic.psubsw: RewritePackedBinop("__psubsw", PrimitiveType.Word16); break;

                case Mnemonic.psubusb: RewritePackedBinop("__psubusb", PrimitiveType.UInt8); break;

                case Mnemonic.psubusw: RewritePackedBinop("__psubusw", PrimitiveType.UInt16); break;

                case Mnemonic.psubw: RewritePackedBinop("__psubw", PrimitiveType.Word16); break;

                case Mnemonic.punpckhbw: RewritePunpckhbw(); break;

                case Mnemonic.punpckhdq: RewritePunpckhdq(); break;

                case Mnemonic.punpckhwd: RewritePunpckhwd(); break;

                case Mnemonic.punpcklbw: RewritePunpcklbw(); break;

                case Mnemonic.punpckldq: RewritePunpckldq(); break;

                case Mnemonic.punpcklwd: RewritePunpcklwd(); break;

                case Mnemonic.push: RewritePush(); break;

                case Mnemonic.pusha: RewritePusha(); break;

                case Mnemonic.pushf: RewritePushf(); break;

                case Mnemonic.pxor:
                case Mnemonic.vpxor: RewritePxor(); break;

                case Mnemonic.rcl: RewriteRotation(PseudoProcedure.RolC, true, true); break;

                case Mnemonic.rcpps: RewritePackedUnaryop("__rcpps", PrimitiveType.Real32); break;

                case Mnemonic.rcr: RewriteRotation(PseudoProcedure.RorC, true, false); break;

                case Mnemonic.rol: RewriteRotation(PseudoProcedure.Rol, false, true); break;

                case Mnemonic.ror: RewriteRotation(PseudoProcedure.Ror, false, false); break;

                case Mnemonic.rdmsr: RewriteRdmsr(); break;

                case Mnemonic.rdpmc: RewriteRdpmc(); break;

                case Mnemonic.rdtsc: RewriteRdtsc(); break;

                case Mnemonic.ret: RewriteRet(); break;

                case Mnemonic.retf: RewriteRet(); break;

                case Mnemonic.rsm: RewriteRsm(); break;

                case Mnemonic.rsqrtps: RewritePackedUnaryop("__rsqrtps", PrimitiveType.Real32); break;

                case Mnemonic.sahf: m.Assign(orw.FlagGroup(X86Instruction.DefCc(instrCur.Mnemonic)), orw.AluRegister(Registers.ah)); break;

                case Mnemonic.sar: RewriteBinOp(Operator.Sar); break;

                case Mnemonic.sbb: RewriteAdcSbb(m.ISub); break;

                case Mnemonic.scas: RewriteStringInstruction(); break;

                case Mnemonic.scasb: RewriteStringInstruction(); break;

                case Mnemonic.seta: RewriteSet(ConditionCode.UGT); break;

                case Mnemonic.setc: RewriteSet(ConditionCode.ULT); break;

                case Mnemonic.setbe: RewriteSet(ConditionCode.ULE); break;

                case Mnemonic.setg: RewriteSet(ConditionCode.GT); break;

                case Mnemonic.setge: RewriteSet(ConditionCode.GE); break;

                case Mnemonic.setl: RewriteSet(ConditionCode.LT); break;

                case Mnemonic.setle: RewriteSet(ConditionCode.LE); break;

                case Mnemonic.setnc: RewriteSet(ConditionCode.UGE); break;

                case Mnemonic.setno: RewriteSet(ConditionCode.NO); break;

                case Mnemonic.setns: RewriteSet(ConditionCode.NS); break;

                case Mnemonic.setnz: RewriteSet(ConditionCode.NE); break;

                case Mnemonic.setpe: RewriteSet(ConditionCode.PE); break;

                case Mnemonic.setpo: RewriteSet(ConditionCode.PO); break;

                case Mnemonic.seto: RewriteSet(ConditionCode.OV); break;

                case Mnemonic.sets: RewriteSet(ConditionCode.SG); break;

                case Mnemonic.setz: RewriteSet(ConditionCode.EQ); break;

                case Mnemonic.sfence: RewriteSfence(); break;

                case Mnemonic.sgdt: RewriteSxdt("__sgdt"); break;

                case Mnemonic.sha1msg2: RewriteSha1msg2(); break;

                case Mnemonic.shl: RewriteBinOp(BinaryOperator.Shl); break;

                case Mnemonic.shld: RewriteShxd("__shld"); break;

                case Mnemonic.shr: RewriteBinOp(BinaryOperator.Shr); break;

                case Mnemonic.shrd: RewriteShxd("__shrd"); break;

                case Mnemonic.sidt: RewriteSxdt("__sidt"); break;

                case Mnemonic.shufps:
                case Mnemonic.vshufps: RewritePackedTernaryop("__shufps", PrimitiveType.Real32); break;

                case Mnemonic.sldt: RewriteSxdt("__sldt"); break;

                case Mnemonic.smsw: RewriteSmsw(); break;

                case Mnemonic.sqrtps: RewritePackedUnaryop("__sqrtps", PrimitiveType.Real32); break;

                case Mnemonic.sqrtsd: RewriteSqrtsd(); break;

                case Mnemonic.stc: RewriteSetFlag(FlagM.CF, Constant.True()); break;

                case Mnemonic.std: RewriteSetFlag(FlagM.DF, Constant.True()); break;

                case Mnemonic.sti: RewriteSti(); break;

                case Mnemonic.stos: RewriteStringInstruction(); break;

                case Mnemonic.stosb: RewriteStringInstruction(); break;

                case Mnemonic.str: RewriteStr(); break;

                case Mnemonic.sub: RewriteAddSub(BinaryOperator.ISub); break;

                case Mnemonic.subsd: RewriteScalarBinop(m.FSub, PrimitiveType.Real64, false); break;

                case Mnemonic.vsubsd: RewriteScalarBinop(m.FSub, PrimitiveType.Real64, true); break;

                case Mnemonic.subss: RewriteScalarBinop(m.FSub, PrimitiveType.Real32, false); break;

                case Mnemonic.vsubss: RewriteScalarBinop(m.FSub, PrimitiveType.Real32, true); break;

                case Mnemonic.subpd: RewritePackedBinop("__subpd", PrimitiveType.Real64); break;

                case Mnemonic.subps: RewritePackedBinop("__subps", PrimitiveType.Real32); break;

                case Mnemonic.syscall: RewriteSyscall(); break;

                case Mnemonic.sysenter: RewriteSysenter(); break;

                case Mnemonic.sysexit: RewriteSysexit(); break;

                case Mnemonic.sysret: RewriteSysret(); break;

                case Mnemonic.ucomiss: RewriteComis(PrimitiveType.Real32); break;

                case Mnemonic.ucomisd: RewriteComis(PrimitiveType.Real64); break;

                case Mnemonic.unpckhps: RewriteUnpckhps(); break;

                case Mnemonic.ud0: iclass = InstrClass.Invalid; m.Invalid(); break;

                case Mnemonic.ud1: iclass = InstrClass.Invalid; m.Invalid(); break;

                case Mnemonic.ud2: iclass = InstrClass.Invalid; m.Invalid(); break;

                case Mnemonic.unpcklpd: RewritePackedBinop("__unpcklpd", PrimitiveType.Real64); break;

                case Mnemonic.unpcklps: RewritePackedBinop("__unpcklps", PrimitiveType.Real32); break;

                case Mnemonic.verr: RewriteVerrw("__verify_readable"); break;

                case Mnemonic.verw: RewriteVerrw("__verify_writeable"); break;

                case Mnemonic.test: RewriteTest(); break;

                case Mnemonic.wait: RewriteWait(); break;

                case Mnemonic.wbinvd: RewriteWbinvd(); break;

                case Mnemonic.wrmsr: RewriteWrsmr(); break;

                case Mnemonic.xadd: RewriteXadd(); break;

                case Mnemonic.xchg: RewriteExchange(); break;

                case Mnemonic.xgetbv: RewriteXgetbv(); break;

                case Mnemonic.xsetbv: RewriteXsetbv(); break;

                case Mnemonic.xlat: RewriteXlat(); break;

                case Mnemonic.xor: RewriteLogical(BinaryOperator.Xor); break;

                case Mnemonic.xorpd:
                case Mnemonic.vxorpd: RewritePackedBinop("__xorpd", PrimitiveType.Word64); break;

                case Mnemonic.xorps: RewritePackedBinop("__xorps", PrimitiveType.Word32); break;

                case Mnemonic.BOR_exp: RewriteFUnary("exp"); break;

                case Mnemonic.BOR_ln: RewriteFUnary("log"); break;
                }
                var len = (int)(dasm.Current.Address - addr) + dasm.Current.Length;
                yield return(m.MakeCluster(addr, len, iclass));
            }
        }
        private void C(Expression e)
        {
            var carry = binder.EnsureFlagGroup(Registers.C);

            m.Assign(carry, m.Cond(e));
        }
Exemple #29
0
        private void SetFlags(Expression e, FlagM changed, FlagM zeroed, FlagM set)
        {
            if (e == null)
            {
                Invalid();
                return;
            }
            uint uChanged = (uint)changed;

            if (uChanged != 0)
            {
                var grfChanged = binder.EnsureFlagGroup(this.arch.GetFlagGroup(Registers.psw, uChanged));
                m.Assign(grfChanged, m.Cond(e));
            }
            uint grfMask = 1;

            while (grfMask <= (uint)zeroed)
            {
                if ((grfMask & (uint)zeroed) != 0)
                {
                    var grfZeroed = binder.EnsureFlagGroup(this.arch.GetFlagGroup(Registers.psw, grfMask));
                    m.Assign(grfZeroed, 0);
                }
                grfMask <<= 1;
            }
            grfMask = 1;
            while (grfMask <= (uint)set)
            {
                if ((grfMask & (uint)set) != 0)
                {
                    var grfZeroed = binder.EnsureFlagGroup(this.arch.GetFlagGroup(Registers.psw, grfMask));
                    m.Assign(grfZeroed, 1);
                }
                grfMask <<= 1;
            }
        }
Exemple #30
0
        private Expression SrcOp(MachineOperand op, Func <int, int> immediateFn = null)
        {
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                var id = binder.EnsureRegister(regOp.Register);
                return(id);
            }
            var immOp = op as ImmediateOperand;

            if (immOp != null)
            {
                return(Constant.Word32(immediateFn(immOp.Value.ToInt32())));
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                return(addrOp.Address);
            }
            var mem = op as MemoryOperand;

            if (mem != null)
            {
                Identifier reg;
                switch (mem.mode)
                {
                default:
                    throw new NotImplementedException(mem.mode.ToString());

                case AddressingMode.Indirect:
                    return(m.Mem(mem.Width, binder.EnsureRegister(mem.reg)));

                case AddressingMode.IndirectPreDecr:
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(reg, m.ISubS(reg, mem.Width.Size));
                    return(m.Mem(mem.Width, reg));

                case AddressingMode.IndirectPostIncr:
                    var t = binder.CreateTemporary(mem.Width);
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(t, m.Mem(mem.Width, reg));
                    m.Assign(reg, m.IAddS(reg, t.DataType.Size));
                    return(t);

                case AddressingMode.IndirectDisplacement:
                    reg = binder.EnsureRegister(mem.reg);
                    return(m.Mem(
                               mem.Width,
                               m.IAddS(reg, mem.disp)));

                case AddressingMode.IndexedIndirect:
                    return(m.Mem(mem.Width, m.IAdd(
                                     binder.EnsureRegister(Registers.r0),
                                     binder.EnsureRegister(mem.reg))));

                case AddressingMode.PcRelativeDisplacement:
                    var addr = instr.Address.ToUInt32();
                    if (mem.Width.Size == 4)
                    {
                        addr &= ~3u;
                    }
                    addr += (uint)(mem.disp + 4);
                    return(m.Mem(mem.Width, Address.Ptr32(addr)));
                }
            }
            throw new NotImplementedException(op.GetType().Name);
        }