示例#1
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, IntelInstruction.DefCc(instrCur.code));
            }
            if ((flags & CopyFlags.SetCfIf0) != 0)
            {
                emitter.Assign(orw.FlagGroup(FlagM.CF), emitter.Eq0(dst));
            }
        }
示例#2
0
        private void RewriteCmp()
        {
            Expression op1 = SrcOp(instrCur.op1);
            Expression op2 = SrcOp(instrCur.op2, instrCur.op1.Width);

            emitter.Assign(
                orw.FlagGroup(IntelInstruction.DefCc(Opcode.cmp)),
                new ConditionOf(emitter.ISub(op1, op2)));
        }
示例#3
0
        private void RewriteMultiply(BinaryOperator op, Domain resultDomain)
        {
            Expression product;

            switch (instrCur.Operands)
            {
            case 1:
                Identifier multiplicator;

                switch (instrCur.op1.Width.Size)
                {
                case 1:
                    multiplicator = orw.AluRegister(Registers.al);
                    product       = orw.AluRegister(Registers.ax);
                    break;

                case 2:
                    multiplicator = orw.AluRegister(Registers.ax);
                    product       = frame.EnsureSequence(
                        orw.AluRegister(Registers.dx), multiplicator, PrimitiveType.Word32);
                    break;

                case 4:
                    multiplicator = orw.AluRegister(Registers.eax);
                    product       = frame.EnsureSequence(
                        orw.AluRegister(Registers.edx), multiplicator, PrimitiveType.Word64);
                    break;

                default:
                    throw new ApplicationException(string.Format("Unexpected operand size: {0}", instrCur.op1.Width));
                }
                ;
                emitter.Assign(
                    product,
                    new BinaryExpression(
                        op,
                        PrimitiveType.Create(resultDomain, product.DataType.Size),
                        SrcOp(instrCur.op1),
                        multiplicator));
                EmitCcInstr(product, IntelInstruction.DefCc(instrCur.code));
                return;

            case 2:
                EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op1), SrcOp(instrCur.op2),
                          CopyFlags.ForceBreak | CopyFlags.EmitCc);
                return;

            case 3:
                EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op2), SrcOp(instrCur.op3),
                          CopyFlags.ForceBreak | CopyFlags.EmitCc);
                return;

            default:
                throw new ArgumentException("Invalid number of operands");
            }
        }
示例#4
0
        private void RewriteXadd()
        {
            var dst = SrcOp(instrCur.op1);
            var src = SrcOp(instrCur.op2);

            emitter.Assign(
                dst,
                PseudoProc("__xadd", instrCur.op1.Width, dst, src));
            EmitCcInstr(dst, IntelInstruction.DefCc(instrCur.code));
        }
示例#5
0
        private void RewriteTest()
        {
            var src = new BinaryExpression(Operator.And,
                                           instrCur.op1.Width,
                                           SrcOp(instrCur.op1),
                                           SrcOp(instrCur.op2));

            EmitCcInstr(src, (IntelInstruction.DefCc(instrCur.code) & ~FlagM.CF));
            emitter.Assign(orw.FlagGroup(FlagM.CF), Constant.False());
        }
示例#6
0
        private void RewriteDivide(BinaryOperator op, Domain domain)
        {
            if (instrCur.Operands != 1)
            {
                throw new ArgumentOutOfRangeException("Intel DIV/IDIV instructions only take one operand");
            }
            Identifier regDividend;
            Identifier regQuotient;
            Identifier regRemainder;

            switch (instrCur.dataWidth.Size)
            {
            case 1:
                regQuotient  = orw.AluRegister(Registers.al);
                regDividend  = orw.AluRegister(Registers.ax);
                regRemainder = orw.AluRegister(Registers.ah);
                break;

            case 2:
                regQuotient  = orw.AluRegister(Registers.ax);
                regRemainder = orw.AluRegister(Registers.dx);
                regDividend  = frame.EnsureSequence(regRemainder, regQuotient, PrimitiveType.Word32);
                break;

            case 4:
                regQuotient  = orw.AluRegister(Registers.eax);
                regRemainder = orw.AluRegister(Registers.edx);
                regDividend  = frame.EnsureSequence(regRemainder, regQuotient, PrimitiveType.Word64);
                break;

            default:
                throw new ArgumentOutOfRangeException(string.Format("{0}-byte divisions not supported.", instrCur.dataWidth.Size));
            }
            ;
            PrimitiveType p = ((PrimitiveType)regRemainder.DataType).MaskDomain(domain);

            emitter.Assign(
                regRemainder, new BinaryExpression(Operator.IMod, p,
                                                   regDividend,
                                                   SrcOp(instrCur.op1)));
            emitter.Assign(
                regQuotient, new BinaryExpression(op, p, regDividend,
                                                  SrcOp(instrCur.op1)));
            EmitCcInstr(regQuotient, IntelInstruction.DefCc(instrCur.code));
        }
示例#7
0
        private void RewriteLogical(BinaryOperator op)
        {
            if (instrCur.code == Opcode.and)
            {
                var r = instrCur.op1 as RegisterOperand;
                if (r != null && r.Register == arch.StackRegister &&
                    instrCur.op2 is ImmediateOperand)
                {
                    emitter.SideEffect(PseudoProc("__align", VoidType.Instance, SrcOp(instrCur.op1)));
                    return;
                }
            }

            EmitBinOp(
                op,
                instrCur.op1,
                instrCur.op1.Width,
                SrcOp(instrCur.op1),
                SrcOp(instrCur.op2),
                CopyFlags.ForceBreak);
            EmitCcInstr(SrcOp(instrCur.op1), (IntelInstruction.DefCc(instrCur.code) & ~FlagM.CF));
            emitter.Assign(orw.FlagGroup(FlagM.CF), Constant.False());
        }
示例#8
0
        private void RewriteStringInstruction()
        {
            bool incSi       = false;
            bool incDi       = false;
            var  incOperator = GetIncrementOperator();

            Identifier      regDX;
            PseudoProcedure ppp;

            switch (instrCur.code)
            {
            default:
                throw new NotSupportedException(string.Format("'{0}' is not an x86 string instruction.", instrCur.code));

            case Opcode.cmps:
            case Opcode.cmpsb:
                emitter.Assign(
                    orw.FlagGroup(IntelInstruction.DefCc(Opcode.cmp)),
                    new ConditionOf(
                        new BinaryExpression(Operator.ISub, instrCur.dataWidth, MemSi(), MemDi())));
                incSi = true;
                incDi = true;
                break;

            case Opcode.lods:
            case Opcode.lodsb:
                emitter.Assign(RegAl, MemSi());
                incSi = true;
                break;

            case Opcode.movs:
            case Opcode.movsb:
                Identifier tmp = frame.CreateTemporary(instrCur.dataWidth);
                emitter.Assign(tmp, MemSi());
                emitter.Assign(MemDi(), tmp);
                incSi = true;
                incDi = true;
                break;

            case Opcode.ins:
            case Opcode.insb:
                regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                ppp   = host.EnsurePseudoProcedure("__in", instrCur.dataWidth, 1);
                emitter.Assign(MemDi(), emitter.Fn(ppp, regDX));
                incDi = true;
                break;

            case Opcode.outs:
            case Opcode.outsb:
                regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                ppp   = host.EnsurePseudoProcedure("__out" + RegAl.DataType.Prefix, VoidType.Instance, 2);
                emitter.SideEffect(emitter.Fn(ppp, regDX, RegAl));
                incSi = true;
                break;

            case Opcode.scas:
            case Opcode.scasb:
                emitter.Assign(
                    orw.FlagGroup(IntelInstruction.DefCc(Opcode.cmp)),
                    new ConditionOf(
                        new BinaryExpression(Operator.ISub,
                                             instrCur.dataWidth,
                                             RegAl,
                                             MemDi())));
                incDi = true;
                break;

            case Opcode.stos:
            case Opcode.stosb:
                emitter.Assign(MemDi(), RegAl);
                incDi = true;
                break;

            case Opcode.ret:
                // "AMD recommends to avoid the penalty by adding rep prefix instead of nop
                // because it saves decode bandwidth."
                RewriteRet();
                return;
            }

            if (incSi)
            {
                emitter.Assign(RegSi,
                               new BinaryExpression(incOperator,
                                                    instrCur.addrWidth,
                                                    RegSi,
                                                    Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size)));
            }

            if (incDi)
            {
                emitter.Assign(RegDi,
                               new BinaryExpression(incOperator,
                                                    instrCur.addrWidth,
                                                    RegDi,
                                                    Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size)));
            }
        }
示例#9
0
        /// <summary>
        /// Iterator that yields one RtlIntructionCluster for each x86 instruction.
        /// </summary>
        /// <returns></returns>
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                instrCur = dasm.Current;
                ric      = new RtlInstructionCluster(instrCur.Address, instrCur.Length);
                emitter  = new RtlEmitter(ric.Instructions);
                orw      = arch.ProcessorMode.CreateOperandRewriter(arch, frame, host);
                switch (instrCur.code)
                {
                default:
                    throw new AddressCorrelatedException(
                              instrCur.Address,
                              "Rewriting x86 opcode '{0}' is not supported yet.",
                              instrCur.code);

                case Opcode.aaa: RewriteAaa(); break;

                case Opcode.aam: RewriteAam(); break;

                case Opcode.adc: RewriteAdcSbb(BinaryOperator.IAdd); break;

                case Opcode.add: RewriteAddSub(BinaryOperator.IAdd); break;

                case Opcode.and: RewriteLogical(BinaryOperator.And); break;

                case Opcode.arpl: RewriteArpl(); break;

                case Opcode.bsr: RewriteBsr(); break;

                case Opcode.bswap: RewriteBswap(); break;

                case Opcode.bt: RewriteBt(); break;

                case Opcode.btr: RewriteBtr(); break;

                case Opcode.bts: RewriteBts(); break;

                case Opcode.call: RewriteCall(instrCur.op1, instrCur.op1.Width); break;

                case Opcode.cbw: RewriteCbw(); break;

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

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

                case Opcode.cli: RewriteCli(); break;

                case Opcode.cmc: emitter.Assign(orw.FlagGroup(FlagM.CF), emitter.Not(orw.FlagGroup(FlagM.CF))); break;

                case Opcode.cmova: RewriteConditionalMove(ConditionCode.UGT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovbe: RewriteConditionalMove(ConditionCode.ULE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovc: RewriteConditionalMove(ConditionCode.ULT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovge: RewriteConditionalMove(ConditionCode.GE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovg: RewriteConditionalMove(ConditionCode.GT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovl: RewriteConditionalMove(ConditionCode.LT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovle: RewriteConditionalMove(ConditionCode.LE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovnc: RewriteConditionalMove(ConditionCode.UGE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovno: RewriteConditionalMove(ConditionCode.NO, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovns: RewriteConditionalMove(ConditionCode.NS, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovnz: RewriteConditionalMove(ConditionCode.NE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovo: RewriteConditionalMove(ConditionCode.OV, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovpe: RewriteConditionalMove(ConditionCode.PE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovpo: RewriteConditionalMove(ConditionCode.PO, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovs: RewriteConditionalMove(ConditionCode.SG, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovz: RewriteConditionalMove(ConditionCode.EQ, instrCur.op1, instrCur.op2); break;

                case Opcode.cmpxchg: RewriteCmpxchg(); break;

                case Opcode.cmp: RewriteCmp(); break;

                case Opcode.cmps: RewriteStringInstruction(); break;

                case Opcode.cmpsb: RewriteStringInstruction(); break;

                case Opcode.cpuid: RewriteCpuid(); break;

                case Opcode.cvttsd2si: RewriteCvttsd2si(); break;

                case Opcode.cwd: RewriteCwd(); break;

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

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

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

                case Opcode.div: RewriteDivide(Operator.UDiv, Domain.UnsignedInt); break;

                case Opcode.enter: RewriteEnter(); break;

                case Opcode.fadd: EmitCommonFpuInstruction(Operator.FAdd, false, false); break;

                case Opcode.faddp: EmitCommonFpuInstruction(Operator.FAdd, false, true); break;

                case Opcode.fchs: EmitFchs(); break;

                case Opcode.fclex: RewriteFclex(); break;

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

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

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

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

                case Opcode.fdiv: EmitCommonFpuInstruction(Operator.FDiv, false, false); break;

                case Opcode.fdivp: EmitCommonFpuInstruction(Operator.FDiv, false, true); break;

                case Opcode.fiadd: EmitCommonFpuInstruction(Operator.FAdd, false, false, PrimitiveType.Real64); break;

                case Opcode.fimul: EmitCommonFpuInstruction(Operator.FMul, false, false, PrimitiveType.Real64); break;

                case Opcode.fisub: EmitCommonFpuInstruction(Operator.FSub, false, false, PrimitiveType.Real64); break;

                case Opcode.fisubr: EmitCommonFpuInstruction(Operator.FSub, true, false, PrimitiveType.Real64); break;

                case Opcode.fidiv: EmitCommonFpuInstruction(Operator.FDiv, false, false, PrimitiveType.Real64); break;

                case Opcode.fdivr: EmitCommonFpuInstruction(Operator.FDiv, true, false); break;

                case Opcode.fdivrp: EmitCommonFpuInstruction(Operator.FDiv, true, true); break;

                case Opcode.fild: RewriteFild(); break;

                case Opcode.fistp: RewriteFistp(); break;

                case Opcode.fld: RewriteFld(); break;

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

                case Opcode.fldcw: RewriteFldcw(); break;

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

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

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

                case Opcode.fmul: EmitCommonFpuInstruction(Operator.FMul, false, false); break;

                case Opcode.fmulp: EmitCommonFpuInstruction(Operator.FMul, false, true); break;

                case Opcode.fpatan: RewriteFpatan(); break;

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

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

                case Opcode.fsincos: RewriteFsincos(); break;

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

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

                case Opcode.fstcw: RewriterFstcw(); break;

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

                case Opcode.fstsw: RewriteFstsw(); break;

                case Opcode.fsub: EmitCommonFpuInstruction(Operator.ISub, false, false); break;

                case Opcode.fsubp: EmitCommonFpuInstruction(Operator.ISub, false, true); break;

                case Opcode.fsubr: EmitCommonFpuInstruction(Operator.ISub, true, false); break;

                case Opcode.fsubrp: EmitCommonFpuInstruction(Operator.ISub, true, true); break;

                case Opcode.ftst: RewriteFtst(); break;

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

                case Opcode.fxam: RewriteFxam(); break;

                case Opcode.fxch: RewriteExchange(); break;

                case Opcode.fyl2x: RewriteFyl2x(); break;

                case Opcode.hlt: RewriteHlt(); break;

                case Opcode.idiv: RewriteDivide(Operator.SDiv, Domain.SignedInt); break;

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

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

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

                case Opcode.insb: RewriteStringInstruction(); break;

                case Opcode.ins: RewriteStringInstruction(); break;

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

                case Opcode.iret: RewriteIret(); break;

                case Opcode.jmp: RewriteJmp(); break;

                case Opcode.ja: RewriteConditionalGoto(ConditionCode.UGT, instrCur.op1); break;

                case Opcode.jbe: RewriteConditionalGoto(ConditionCode.ULE, instrCur.op1); break;

                case Opcode.jc: RewriteConditionalGoto(ConditionCode.ULT, instrCur.op1); break;

                case Opcode.jcxz: RewriteJcxz(); break;

                case Opcode.jge: RewriteConditionalGoto(ConditionCode.GE, instrCur.op1); break;

                case Opcode.jg: RewriteConditionalGoto(ConditionCode.GT, instrCur.op1); break;

                case Opcode.jl: RewriteConditionalGoto(ConditionCode.LT, instrCur.op1); break;

                case Opcode.jle: RewriteConditionalGoto(ConditionCode.LE, instrCur.op1); break;

                case Opcode.jnc: RewriteConditionalGoto(ConditionCode.UGE, instrCur.op1); break;

                case Opcode.jno: RewriteConditionalGoto(ConditionCode.NO, instrCur.op1); break;

                case Opcode.jns: RewriteConditionalGoto(ConditionCode.NS, instrCur.op1); break;

                case Opcode.jnz: RewriteConditionalGoto(ConditionCode.NE, instrCur.op1); break;

                case Opcode.jo: RewriteConditionalGoto(ConditionCode.OV, instrCur.op1); break;

                case Opcode.jpe: RewriteConditionalGoto(ConditionCode.PE, instrCur.op1); break;

                case Opcode.jpo: RewriteConditionalGoto(ConditionCode.PO, instrCur.op1); break;

                case Opcode.js: RewriteConditionalGoto(ConditionCode.SG, instrCur.op1); break;

                case Opcode.jz: RewriteConditionalGoto(ConditionCode.EQ, instrCur.op1); break;

                case Opcode.lahf: RewriteLahf(); break;

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

                case Opcode.lea: RewriteLea(); break;

                case Opcode.leave: RewriteLeave(); break;

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

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

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

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

                case Opcode.lods: RewriteStringInstruction(); break;

                case Opcode.lodsb: RewriteStringInstruction(); break;

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

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

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

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

                case Opcode.mov: RewriteMov(); break;

                case Opcode.movd: RewriteMovzx(); break;

                case Opcode.movdqa: RewriteMov(); break;

                case Opcode.movq: RewriteMov(); break;

                case Opcode.movs: RewriteStringInstruction(); break;

                case Opcode.movsb: RewriteStringInstruction(); break;

                case Opcode.movsx: RewriteMovsx(); break;

                case Opcode.movzx: RewriteMovzx(); break;

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

                case Opcode.neg: RewriteNeg(); break;

                case Opcode.nop: continue;

                case Opcode.not: RewriteNot(); break;

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

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

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

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

                case Opcode.palignr: RewritePalignr(); break;

                case Opcode.pop: RewritePop(); break;

                case Opcode.popa: RewritePopa(); break;

                case Opcode.popf: RewritePopf(); break;

                case Opcode.pshufd: RewritePshufd(); break;

                case Opcode.punpcklbw: RewritePunpcklbw(); break;

                case Opcode.punpcklwd: RewritePunpcklwd(); break;

                case Opcode.push: RewritePush(); break;

                case Opcode.pusha: RewritePusha(); break;

                case Opcode.pushf: RewritePushf(); break;

                case Opcode.pxor: RewritePxor(); break;

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

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

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

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

                case Opcode.rdtsc: RewriteRdtsc(); break;

                case Opcode.rep: RewriteRep(); break;

                case Opcode.repne: RewriteRep(); break;

                case Opcode.ret: RewriteRet(); break;

                case Opcode.retf: RewriteRet(); break;

                case Opcode.sahf: emitter.Assign(orw.FlagGroup(IntelInstruction.DefCc(instrCur.code)), orw.AluRegister(Registers.ah)); break;

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

                case Opcode.sbb: RewriteAdcSbb(BinaryOperator.ISub); break;

                case Opcode.scas: RewriteStringInstruction(); break;

                case Opcode.scasb: RewriteStringInstruction(); break;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                case Opcode.sti: break; //$TODO:

                case Opcode.stos: RewriteStringInstruction(); break;

                case Opcode.stosb: RewriteStringInstruction(); break;

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

                case Opcode.test: RewriteTest(); break;

                case Opcode.wait: break;        // used to slow down FPU.

                case Opcode.xadd: RewriteXadd(); break;

                case Opcode.xchg: RewriteExchange(); break;

                case Opcode.xgetbv: RewriteXgetbv(); break;

                case Opcode.xlat: RewriteXlat(); break;

                case Opcode.xor: RewriteLogical(BinaryOperator.Xor); break;
                }
                yield return(ric);
            }
        }