/* * the C0 bit becomes the CF (carry) flag, the C2 bit becomes the PF(parity) flag, and the C3 bit becomes the ZF (zero) flag. */ // > 0 // < 1 // = 40 // inordered 45 public FstswChainMatcher(X86Instruction[] instrs, OperandRewriter orw) { this.instrs = instrs; this.orw = orw; this.zappedInstructions = new Dictionary<int, Opcode>(); this.rewritten = new List<Instruction>(); }
public void Setup() { program = new Program(); program.Image = new LoadedImage(Address.Ptr32(0x10000), new byte[4]); var procAddress = Address.Ptr32(0x10000000); instr = new X86Instruction(Opcode.nop, PrimitiveType.Word32, PrimitiveType.Word32) { Address = procAddress, }; proc = Procedure.Create(procAddress, arch.CreateFrame()); state = (X86State) arch.CreateProcessorState(); orw = new OperandRewriter32(arch, proc.Frame, new FakeRewriterHost(program)); }
public void Setup() { var mem = new MemoryArea(Address.Ptr32(0x10000), new byte[4]); program = new Program { SegmentMap = new SegmentMap( mem.BaseAddress, new ImageSegment(".text", mem, AccessMode.ReadExecute)) }; var procAddress = Address.Ptr32(0x10000000); instr = new X86Instruction(Opcode.nop, PrimitiveType.Word32, PrimitiveType.Word32) { Address = procAddress, }; proc = Procedure.Create(procAddress, arch.CreateFrame()); state = (X86State) arch.CreateProcessorState(); orw = new OperandRewriter32(arch, new ExpressionEmitter(), proc.Frame, new FakeRewriterHost(program)); }
public void Setup() { arch = new IntelArchitecture(ProcessorMode.Real); var image = new LoadedImage(Address.Ptr32(0x10000), new byte[4]); var prog = new Program( image, image.CreateImageMap(), arch, null); var procAddress = Address.Ptr32(0x10000000); instr = new X86Instruction(Opcode.nop, PrimitiveType.Word16, PrimitiveType.Word16) { Address = procAddress, }; proc = Procedure.Create(procAddress, arch.CreateFrame()); orw = new OperandRewriter16(arch, proc.Frame, new FakeRewriterHost(prog)); state = (X86State)arch.CreateProcessorState(); }
public Expression Transform(X86Instruction instr, MachineOperand op, PrimitiveType opWidth, X86State state) { var reg = op as RegisterOperand; if (reg != null) return AluRegister(reg); var mem = op as MemoryOperand; if (mem != null) return CreateMemoryAccess(instr, mem, opWidth, state); var imm = op as ImmediateOperand; if (imm != null) return CreateConstant(imm, opWidth); var fpu = op as FpuOperand; if (fpu != null) return FpuRegister(fpu.StNumber, state); var addr = op as AddressOperand; if (addr != null) return addr.Address; throw new NotImplementedException(string.Format("Operand {0}", op)); }
public void Setup() { arch = new X86ArchitectureReal(); var mem = new MemoryArea(Address.Ptr32(0x10000), new byte[4]); var prog = new Program( new SegmentMap( mem.BaseAddress, new ImageSegment( "code", mem, AccessMode.ReadWriteExecute)), arch, new DefaultPlatform(null, arch)); var procAddress = Address.Ptr32(0x10000000); instr = new X86Instruction(Opcode.nop, PrimitiveType.Word16, PrimitiveType.Word16) { Address = procAddress, }; proc = Procedure.Create(procAddress, arch.CreateFrame()); orw = new OperandRewriter16(arch, proc.Frame, new FakeRewriterHost(prog)); state = (X86State)arch.CreateProcessorState(); }
private string DumpInstr(X86Instruction instr) { return($"{instr.Address} XX {instr.ToString().ToUpper()}"); }
public Expression CreateMemoryAccess(X86Instruction instr, MemoryOperand mem, DataType dt, X86State state) { var exp = ImportedProcedure(instr.Address, mem.Width, mem); if (exp != null) return new ProcedureConstant(arch.PointerType, exp); Expression expr = EffectiveAddressExpression(instr, mem, state); if (IsSegmentedAccessRequired || (mem.DefaultSegment != Registers.ds && mem.DefaultSegment != Registers.ss)) { Expression seg = ReplaceCodeSegment(mem.DefaultSegment, state); if (seg == null) seg = AluRegister(mem.DefaultSegment); return new SegmentedAccess(MemoryIdentifier.GlobalMemory, seg, expr, dt); } else { return new MemoryAccess(MemoryIdentifier.GlobalMemory, expr, dt); } }
/// <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); ric.Class = RtlClass.Linear; 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.illegal: ric.Class = 0; emitter.Invalid(); break; case Opcode.aaa: RewriteAaa(); break; case Opcode.aad: RewriteAad(); break; case Opcode.aam: RewriteAam(); break; case Opcode.aas: RewriteAas(); 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.bound: RewriteBound(); 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.fabs: RewriteFabs(); break; case Opcode.fadd: EmitCommonFpuInstruction(Operator.FAdd, false, false); break; case Opcode.faddp: EmitCommonFpuInstruction(Operator.FAdd, false, true); break; case Opcode.fbld: RewriteFbld(); break; case Opcode.fbstp: RewriteFbstp(); 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.fdecstp: RewriteFdecstp(); break; case Opcode.fdiv: EmitCommonFpuInstruction(Operator.FDiv, false, false); break; case Opcode.fdivp: EmitCommonFpuInstruction(Operator.FDiv, false, true); break; case Opcode.ffree: RewriteFfree(); break; case Opcode.fiadd: EmitCommonFpuInstruction(Operator.FAdd, false, false, PrimitiveType.Real64); break; case Opcode.ficom: RewriteFicom(false); break; case Opcode.ficomp: RewriteFicom(true); 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.fidivr: EmitCommonFpuInstruction(Operator.FDiv, true, 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.fincstp: RewriteFincstp(); break; case Opcode.fist: RewriteFist(false); break; case Opcode.fistp: RewriteFist(true); break; case Opcode.fld: RewriteFld(); break; case Opcode.fld1: RewriteFldConst(1.0); break; case Opcode.fldcw: RewriteFldcw(); break; case Opcode.fldenv: RewriteFldenv(); break; case Opcode.fldl2t: RewriteFldConst(Constant.Lg10()); 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.fprem: RewriteFprem(); break; case Opcode.frndint: RewriteFUnary("__rndint"); break; case Opcode.frstor: RewriteFrstor(); break; case Opcode.fsave: RewriteFsave(); break; case Opcode.fscale: RewriteFscale(); 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.fstenv: RewriteFstenv(); break; case Opcode.fstcw: RewriterFstcw(); break; case Opcode.fstp: RewriteFst(true); break; case Opcode.fstsw: RewriteFstsw(); break; case Opcode.fsub: EmitCommonFpuInstruction(Operator.FSub, false, false); break; case Opcode.fsubp: EmitCommonFpuInstruction(Operator.FSub, false, true); break; case Opcode.fsubr: EmitCommonFpuInstruction(Operator.FSub, true, false); break; case Opcode.fsubrp: EmitCommonFpuInstruction(Operator.FSub, 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.into: RewriteInto(); 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: emitter.Nop(); break; 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.pcmpeqb: RewritePcmpeqb(); 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(X86Instruction.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.setno: RewriteSet(ConditionCode.NO); break; case Opcode.setns: RewriteSet(ConditionCode.NS); break; case Opcode.setnz: RewriteSet(ConditionCode.NE); break; case Opcode.setpe: RewriteSet(ConditionCode.PE); break; case Opcode.setpo: RewriteSet(ConditionCode.PO); 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: RewriteSti(); break; 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: RewriteWait(); break; 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; case Opcode.BOR_exp: RewriteFUnary("exp"); break; case Opcode.BOR_ln: RewriteFUnary("log"); break; } yield return(ric); } }
/// <summary> /// A jump to 0xFFFF:0x0000 in real mode is a reboot. /// </summary> /// <param name="instrCur"></param> /// <returns></returns> private bool IsRealModeReboot(X86Instruction instrCur) { var addrOp = instrCur.op1 as X86AddressOperand; bool isRealModeReboot = addrOp != null && addrOp.Address.ToLinear() == 0xFFFF0; return isRealModeReboot; }
protected virtual void RenderOperand( MachineOperand operand, X86Instruction instr, MachineInstructionRenderer renderer, MachineInstructionRendererOptions options) { switch (operand) { case RegisterOperand reg: RenderRegister(reg.Register.Name, renderer); break; case ImmediateOperand imm: RenderImmediate(imm, instr, renderer); break; case MemoryOperand memOp: var flags = options.Flags; if (NeedsExplicitMemorySize(instr)) { flags |= MachineInstructionRendererFlags.ExplicitOperandSize; } if (memOp.Base == Registers.rip) { var addr = instr.Address + instr.Length + memOp.Offset !.ToInt32(); if ((flags & MachineInstructionRendererFlags.ResolvePcRelativeAddress) != 0) { renderer.WriteString("["); renderer.WriteAddress(addr.ToString(), addr); renderer.WriteString("]"); renderer.AddAnnotation(memOp.ToString()); } else { RenderMemory(memOp, renderer, flags); renderer.AddAnnotation(addr.ToString()); } } else { RenderMemory(memOp, renderer, flags); } break; case AddressOperand addrOp: if (addrOp.Address.Selector.HasValue) { renderer.WriteString("far"); renderer.WriteString(" "); renderer.WriteString(FormatUnsignedValue(addrOp.Address.Selector.Value, "{0:X4}")); renderer.WriteChar(':'); renderer.WriteString(FormatUnsignedValue(addrOp.Address.Offset, "{0:X4}")); } else { renderer.WriteAddress(FormatUnsignedValue(addrOp.Address.ToLinear(), "{0:X4}"), addrOp.Address); } break; case FpuOperand fpu: renderer.WriteFormat("st({0})", fpu.StNumber); break; default: throw new NotImplementedException(operand.GetType().Name); } }
/// <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); break; case Mnemonic.addsd: case Mnemonic.vaddsd: RewriteScalarBinop(m.FAdd, PrimitiveType.Real64); 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.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.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.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); break; case Mnemonic.divss: RewriteScalarBinop(m.FDiv, PrimitiveType.Real32); 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.ffree: RewriteFfree(); 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.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.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.@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.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(); 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.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.@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.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.movd: RewriteMovzx(); break; case Mnemonic.movdqa: 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.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.mulss: RewriteScalarBinop(m.FMul, PrimitiveType.Real32); break; case Mnemonic.mulsd: RewriteScalarBinop(m.FMul, PrimitiveType.Real64); 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.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.vshufps: RewritePackedTernaryop("__vshufps", PrimitiveType.Real32); break; case Mnemonic.sldt: RewriteSxdt("__sldt"); 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.sub: RewriteAddSub(BinaryOperator.ISub); break; case Mnemonic.subsd: RewriteScalarBinop(m.FSub, PrimitiveType.Real64); break; case Mnemonic.subss: RewriteScalarBinop(m.FSub, PrimitiveType.Real32); 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.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.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)); } }
/// <summary> /// Memory accesses are translated into expressions, performing simplifications /// where possible. /// </summary> public Expression EffectiveAddressExpression(X86Instruction instr, MemoryOperand mem) { Expression?eIndex = null; Expression?eBase = null; Expression?expr = null; bool ripRelative = false; if (mem.Base != RegisterStorage.None) { if (mem.Base == Registers.rip) { ripRelative = true; } else { eBase = AluRegister(mem.Base); if (expr != null) { expr = m.IAdd(eBase, expr); } else { expr = eBase; } } } if (mem.Offset !.IsValid) { if (ripRelative) { expr = instr.Address + (instr.Length + mem.Offset.ToInt64()); } else if (expr != null) { BinaryOperator op = Operator.IAdd; long l = mem.Offset.ToInt64(); if (l < 0 && l > -0x800) { l = -l; op = Operator.ISub; } DataType dt = (eBase != null) ? eBase.DataType : eIndex !.DataType; Constant cOffset = Constant.Create(dt, l); expr = new BinaryExpression(op, dt, expr, cOffset); } else { expr = mem.Offset; } } if (mem.Index != RegisterStorage.None) { eIndex = AluRegister(mem.Index); if (mem.Scale != 0 && mem.Scale != 1) { eIndex = m.IMul(eIndex, Constant.Create(mem.Index.DataType, mem.Scale)); } expr = m.IAdd(expr !, eIndex); } if (!IsSegmentedAccessRequired && expr is Constant c && mem.SegOverride == RegisterStorage.None) { return(arch.MakeAddressFromConstant(c, false) !); } return(expr !); }
/// <summary> /// Rewrites the current instruction as a string instruction. /// </summary> /// <returns>False if the current instruction is not a string /// instruction. This can happen when disassembling data where /// a "rep" prefix is followed by some other junk byte. /// </returns> private bool RewriteStringInstruction() { bool incSi = false; bool incDi = false; var incOperator = GetIncrementOperator(); Identifier regDX; PseudoProcedure ppp; switch (instrCur.code) { default: return(false); case Opcode.cmps: case Opcode.cmpsb: emitter.Assign( orw.FlagGroup(X86Instruction.DefCc(Opcode.cmp)), emitter.Cond(emitter.ISub(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(X86Instruction.DefCc(Opcode.cmp)), emitter.Cond(emitter.ISub(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(true); } if (incSi) { emitter.Assign(RegSi, incOperator(RegSi, instrCur.dataWidth.Size)); } if (incDi) { emitter.Assign(RegDi, incOperator(RegDi, instrCur.dataWidth.Size)); } return(true); }
/// <summary> /// Memory accesses are translated into expressions. /// </summary> /// <param name="mem"></param> /// <param name="state"></param> /// <returns></returns> public Expression EffectiveAddressExpression(X86Instruction instr, MemoryOperand mem, X86State state) { Expression eIndex = null; Expression eBase = null; Expression expr = null; PrimitiveType type = PrimitiveType.CreateWord(mem.Width.Size); bool ripRelative = false; if (mem.Base != RegisterStorage.None) { if (mem.Base == Registers.rip) { ripRelative = true; } else { eBase = AluRegister(mem.Base); if (expr != null) { expr = new BinaryExpression(Operator.IAdd, eBase.DataType, eBase, expr); } else { expr = eBase; } } } if (mem.Offset.IsValid) { if (ripRelative) { expr = instr.Address + (instr.Length + mem.Offset.ToInt64()); } else if (expr != null) { BinaryOperator op = Operator.IAdd; long l = mem.Offset.ToInt64(); if (l < 0 && l > -0x800) { l = -l; op = Operator.ISub; } DataType dt = (eBase != null) ? eBase.DataType : eIndex.DataType; Constant cOffset = Constant.Create(dt, l); expr = new BinaryExpression(op, dt, expr, cOffset); } else { expr = mem.Offset; } } if (mem.Index != RegisterStorage.None) { eIndex = AluRegister(mem.Index); if (mem.Scale != 0 && mem.Scale != 1) { eIndex = new BinaryExpression( Operator.IMul, eIndex.DataType, eIndex, Constant.Create(mem.Width, mem.Scale)); } expr = new BinaryExpression(Operator.IAdd, expr.DataType, expr, eIndex); } return(expr); }
protected override void RenderMnemonic(X86Instruction instr, StringBuilder sb) { switch (instr.Mnemonic) { case Mnemonic.retf: sb.Append("lret"); return; case Mnemonic.jmp: case Mnemonic.call: if (IsFar(instr.Operands[0])) { sb.Append("l"); sb.Append(instr.MnemonicAsString); return; } else { sb.Append(instr.MnemonicAsString); } break; case Mnemonic.bound: case Mnemonic.enter: sb.Append(instr.MnemonicAsString); return; case Mnemonic.cbw: sb.Append("cbtw"); return; case Mnemonic.cdq: sb.Append("cltd"); return; case Mnemonic.cdqe: sb.Append("cltq"); return; case Mnemonic.cqo: sb.Append("cqto"); return; case Mnemonic.cwd: sb.Append("cwtd"); return; case Mnemonic.cwde: sb.Append("cwtl"); return; case Mnemonic.cmps: case Mnemonic.ins: case Mnemonic.lods: case Mnemonic.movs: case Mnemonic.outs: case Mnemonic.stos: sb.Append(instr.MnemonicAsString); sb.Append(MnemonicSuffix(instr.dataWidth)); return; case Mnemonic.movsx: sb.Append("movs"); sb.Append(MnemonicSuffix(instr.Operands[1])); sb.Append(MnemonicSuffix(instr.Operands[0])); return; case Mnemonic.movzx: sb.Append("movz"); sb.Append(MnemonicSuffix(instr.Operands[1])); sb.Append(MnemonicSuffix(instr.Operands[0])); return; default: sb.Append(instr.MnemonicAsString); break; } if (base.NeedsExplicitMemorySize(instr)) { char suffix = MnemonicSuffix(instr.Operands[0]); sb.Append(suffix); } }
protected override void RenderOperand(MachineOperand operand, X86Instruction instr, MachineInstructionRenderer renderer, MachineInstructionRendererOptions options) { switch (operand) { case RegisterOperand reg: if (instr.Mnemonic == Mnemonic.call || instr.Mnemonic == Mnemonic.jmp) { renderer.WriteChar('*'); } this.RenderRegister(reg.Register.Name, renderer); break; case ImmediateOperand imm: renderer.WriteChar('$'); RenderImmediate(imm, instr, renderer); break; case MemoryOperand mem: if (mem.Width is PrimitiveType pt && pt.Domain == Domain.SegPointer) { renderer.WriteChar('*'); } if (mem.SegOverride != RegisterStorage.None) { RenderRegister(mem.SegOverride.Name, renderer); renderer.WriteChar(':'); } if (mem.Offset is not null && !mem.Offset.IsZero) { string sOffset; if (mem.Base == RegisterStorage.None && mem.Index == RegisterStorage.None) { sOffset = FormatUnsignedValue(mem.Offset.ToUInt64(), "{0:X}"); } else { sOffset = FormatSignedValue(mem.Offset.ToInt64(), false); } renderer.WriteString(sOffset); } if (mem.Base != RegisterStorage.None) { renderer.WriteChar('('); RenderRegister(mem.Base.Name, renderer); } if (mem.Index != RegisterStorage.None) { if (mem.Base == RegisterStorage.None) { renderer.WriteChar('('); } renderer.WriteChar(','); RenderRegister(mem.Index.Name, renderer); if (mem.Scale != 0) { renderer.WriteFormat(",{0}", mem.Scale); } } renderer.WriteChar(')'); break; case AddressOperand aop: var addr = aop.Address; if (options.SymbolResolver(addr, out string?name, out long symOffset)) { base.RenderSymbolReference(addr, name !, symOffset, renderer); } else if (addr.Selector.HasValue) { switch (addr.DataType.BitSize) { case 32: renderer.WriteFormat("$0x{0:X}, $0x{1:X}", addr.Selector.Value, addr.Offset & 0xFFFF); break; case 48: renderer.WriteFormat("$0x{0:X}, $0x{1:X}", addr.Selector.Value, addr.Offset); break; } } else { renderer.WriteAddress(FormatUnsignedValue(aop.Address.Offset, "${0}"), addr); } break; default: throw new NotImplementedException($"Not implemeted operand type {operand.GetType().Name}"); } }
public void EmitStringInstruction(X86Instruction instr, CodeEmitter emitter) { this.emitter = emitter; bool incSi = false; bool incDi = false; this.instrCur = instr; switch (instrCur.code) { default: throw new ApplicationException("NYI"); case Mnemonic.cmps: case Mnemonic.cmpsb: emitter.Assign( orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)), new ConditionOf( new BinaryExpression(Operator.ISub, instrCur.dataWidth, MemSi(), MemDi()))); incSi = true; incDi = true; break; case Mnemonic.lods: case Mnemonic.lodsb: emitter.Assign(RegAl, MemSi()); incSi = true; break; case Mnemonic.movs: case Mnemonic.movsb: { Identifier tmp = frame.CreateTemporary(instrCur.dataWidth); emitter.Assign(tmp, MemSi()); emitter.Store(MemDi(), tmp); incSi = true; incDi = true; break; } case Mnemonic.ins: case Mnemonic.insb: { Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth); emitter.Store(MemDi(), emitter.PseudoProc("__in", instrCur.dataWidth, regDX)); incDi = true; break; } case Mnemonic.outs: case Mnemonic.outsb: { Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth); emitter.SideEffect("__out" + RegAl.DataType.Prefix, regDX, RegAl); incSi = true; break; } case Mnemonic.scas: case Mnemonic.scasb: emitter.Assign( orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)), new ConditionOf( new BinaryExpression(Operator.ISub, instrCur.dataWidth, RegAl, MemDi()))); incDi = true; break; case Mnemonic.stos: case Mnemonic.stosb: emitter.Store(MemDi(), RegAl); incDi = true; break; } if (incSi) { emitter.Assign(RegSi, new BinaryExpression(Operator.IAdd, instrCur.addrWidth, RegSi, Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size))); } if (incDi) { emitter.Assign(RegDi, new BinaryExpression(Operator.IAdd, instrCur.addrWidth, RegDi, Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size))); } }
public void Execute(X86Instruction instr) { if (instr.repPrefix == 2 && !ignoreRep) { // repne switch (instr.code) { case Opcode.scasb: Repne(); return; } throw new NotImplementedException(); } switch (instr.code) { default: throw new NotImplementedException(string.Format("Instruction emulation for {0} not implemented yet.", instr)); case Opcode.adc: Adc(instr.op1, instr.op2); return; case Opcode.add: Add(instr.op1, instr.op2); return; case Opcode.and: And(instr.op1, instr.op2); return; case Opcode.call: Call(instr.op1); return; case Opcode.cmp: Cmp(instr.op1, instr.op2); return; case Opcode.dec: Dec(instr.op1); return; case Opcode.hlt: running = false; return; case Opcode.inc: Inc(instr.op1); return; case Opcode.ja: if ((Flags & (Cmask | Zmask)) == 0) { InstructionPointer = ((AddressOperand)instr.op1).Address; } return; case Opcode.jbe: if ((Flags & (Cmask | Zmask)) != 0) { InstructionPointer = ((AddressOperand)instr.op1).Address; } return; case Opcode.jc: if ((Flags & Cmask) != 0) { InstructionPointer = ((AddressOperand)instr.op1).Address; } return; case Opcode.jmp: Jump(instr.op1); return; case Opcode.jnc: if ((Flags & Cmask) == 0) { InstructionPointer = ((AddressOperand)instr.op1).Address; } return; case Opcode.jnz: if ((Flags & Zmask) == 0) { InstructionPointer = ((AddressOperand)instr.op1).Address; } return; case Opcode.jz: if ((Flags & Zmask) != 0) { InstructionPointer = ((AddressOperand)instr.op1).Address; } return; case Opcode.lea: Write(instr.op1, GetEffectiveAddress((MemoryOperand)instr.op2)); break; case Opcode.loop: Loop(instr.op1); break; case Opcode.mov: Write(instr.op1, Read(instr.op2)); break; case Opcode.or: Or(instr.op1, instr.op2); return; case Opcode.pop: Write(instr.op1, Pop()); return; case Opcode.popa: Popa(); return; case Opcode.push: Push(Read(instr.op1)); return; case Opcode.pusha: Pusha(); return; case Opcode.rol: Rol(instr.op1, instr.op2); return; case Opcode.scasb: Scasb(); return; case Opcode.shl: Shl(instr.op1, instr.op2); return; case Opcode.shr: Shr(instr.op1, instr.op2); return; case Opcode.sub: Sub(instr.op1, instr.op2); return; case Opcode.xor: Xor(instr.op1, instr.op2); return; case Opcode.xchg: Xchg(instr.op1, instr.op2); return; } }
private X86Instruction CreateMov(RegisterStorage regDst, RegisterStorage regSrc) { X86Instruction inst = new X86Instruction( Opcode.mov, PrimitiveType.Word16, PrimitiveType.Word16, new RegisterOperand(regDst), new RegisterOperand(regSrc)); return inst; }
public Expression CreateMemoryAccess(X86Instruction instr, MemoryOperand memoryOperand, X86State state) { return(CreateMemoryAccess(instr, memoryOperand, memoryOperand.Width, state)); }
/// <summary> /// Rewrites the current instruction as a string instruction. /// </summary> /// If a rep prefix is present, converts it into a loop: /// <code> /// while ([e]cx != 0) /// [string instruction] /// --ecx; /// if (zF) ; only cmps[b] and scas[b] /// goto follow; /// follow: ... /// </code> /// </summary> private void RewriteStringInstruction() { var topOfLoop = instrCur.Address; Identifier regCX = null; if (instrCur.repPrefix != 0) { regCX = orw.AluRegister(Registers.rcx, instrCur.addrWidth); m.BranchInMiddleOfInstruction(m.Eq0(regCX), instrCur.Address + instrCur.Length, RtlClass.ConditionalTransfer); } bool incSi = false; bool incDi = false; var incOperator = GetIncrementOperator(); Identifier regDX; switch (instrCur.code) { default: return; case Opcode.cmps: case Opcode.cmpsb: m.Assign( orw.FlagGroup(X86Instruction.DefCc(Opcode.cmp)), m.Cond(m.ISub(MemSi(), MemDi()))); incSi = true; incDi = true; break; case Opcode.lods: case Opcode.lodsb: m.Assign(RegAl, MemSi()); incSi = true; break; case Opcode.movs: case Opcode.movsb: Identifier tmp = binder.CreateTemporary(instrCur.dataWidth); m.Assign(tmp, MemSi()); m.Assign(MemDi(), tmp); incSi = true; incDi = true; break; case Opcode.ins: case Opcode.insb: regDX = binder.EnsureRegister(Registers.dx); m.Assign(MemDi(), host.PseudoProcedure("__in", instrCur.dataWidth, regDX)); incDi = true; break; case Opcode.outs: case Opcode.outsb: regDX = binder.EnsureRegister(Registers.dx); m.SideEffect(host.PseudoProcedure("__out" + RegAl.DataType.Prefix, VoidType.Instance, regDX, RegAl)); incSi = true; break; case Opcode.scas: case Opcode.scasb: m.Assign( orw.FlagGroup(X86Instruction.DefCc(Opcode.cmp)), m.Cond(m.ISub(RegAl, MemDi()))); incDi = true; break; case Opcode.stos: case Opcode.stosb: m.Assign(MemDi(), RegAl); incDi = true; break; } if (incSi) { m.Assign(RegSi, incOperator(RegSi, instrCur.dataWidth.Size)); } if (incDi) { m.Assign(RegDi, incOperator(RegDi, instrCur.dataWidth.Size)); } if (instrCur.repPrefix == 0) { return; } m.Assign(regCX, m.ISub(regCX, 1)); switch (instrCur.code) { case Opcode.cmps: case Opcode.cmpsb: case Opcode.scas: case Opcode.scasb: { var cc = (instrCur.repPrefix == 2) ? ConditionCode.NE : ConditionCode.EQ; m.Branch(new TestCondition(cc, orw.FlagGroup(FlagM.ZF)).Invert(), topOfLoop, RtlClass.ConditionalTransfer); break; } default: m.Goto(topOfLoop); break; } }
private X86Instruction CreatePush(RegisterStorage reg) { X86Instruction inst = new X86Instruction( Opcode.push, reg.DataType, reg.DataType, new RegisterOperand(reg)); return inst; }
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 = binder.EnsureSequence( Registers.dx, multiplicator.Storage, PrimitiveType.Word32); break; case 4: multiplicator = orw.AluRegister(Registers.eax); product = binder.EnsureSequence( Registers.edx, multiplicator.Storage, PrimitiveType.Word64); break; case 8: multiplicator = orw.AluRegister(Registers.rax); product = binder.EnsureSequence( Registers.rdx, multiplicator.Storage, PrimitiveType.Word64); break; default: throw new ApplicationException(string.Format("Unexpected operand size: {0}", instrCur.op1.Width)); } ; m.Assign( product, new BinaryExpression( op, PrimitiveType.Create(resultDomain, product.DataType.Size), SrcOp(instrCur.op1), multiplicator)); EmitCcInstr(product, X86Instruction.DefCc(instrCur.code)); return; case 2: EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op1), SrcOp(instrCur.op2), CopyFlags.EmitCc); return; case 3: EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op2), SrcOp(instrCur.op3), CopyFlags.EmitCc); return; default: throw new ArgumentException("Invalid number of operands"); } }
public void Execute(X86Instruction instr) { switch (instr.code) { default: throw new NotImplementedException(string.Format("Instruction emulation for {0} not implemented yet.", instr)); case Opcode.adc: Adc(instr.op1, instr.op2); return; case Opcode.add: Add(instr.op1, instr.op2); return; case Opcode.and: And(instr.op1, instr.op2); return; case Opcode.call: Call(instr.op1); return; case Opcode.cmp: Cmp(instr.op1, instr.op2); return; case Opcode.dec: Dec(instr.op1); return; case Opcode.hlt: running = false; return; case Opcode.inc: Inc(instr.op1); return; case Opcode.ja: if ((Flags & (Cmask | Zmask)) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return; case Opcode.jbe: if ((Flags & (Cmask | Zmask)) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return; case Opcode.jc: if ((Flags & Cmask) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return; case Opcode.jmp: Jump(instr.op1); return; case Opcode.jnc: if ((Flags & Cmask) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return; case Opcode.jnz: if ((Flags & Zmask) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return; case Opcode.jz: if ((Flags & Zmask) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return; case Opcode.lea: Write(instr.op1, GetEffectiveAddress((MemoryOperand)instr.op2)); break; case Opcode.loop: Loop(instr.op1); break; case Opcode.mov: Write(instr.op1, Read(instr.op2)); break; case Opcode.or: Or(instr.op1, instr.op2); return; case Opcode.pop: Write(instr.op1, Pop()); return; case Opcode.popa: Popa(); return; case Opcode.push: Push(Read(instr.op1)); return; case Opcode.pusha: Pusha(); return; case Opcode.repne: Repne(); return; case Opcode.rol: Rol(instr.op1, instr.op2); return; case Opcode.scasb: Scasb(); return; case Opcode.shl: Shl(instr.op1, instr.op2); return; case Opcode.shr: Shr(instr.op1, instr.op2); return; case Opcode.sub: Sub(instr.op1, instr.op2); return; case Opcode.xor: Xor(instr.op1, instr.op2); return; case Opcode.xchg: Xchg(instr.op1, instr.op2); return; } }
public Expression CreateMemoryAccess(X86Instruction instr, MemoryOperand memoryOperand, X86State state) { return CreateMemoryAccess(instr, memoryOperand, memoryOperand.Width, state); }
/// <summary> /// Memory accesses are translated into expressions. /// </summary> /// <param name="mem"></param> /// <param name="state"></param> /// <returns></returns> public Expression EffectiveAddressExpression(X86Instruction instr, MemoryOperand mem, X86State state) { Expression eIndex = null; Expression eBase = null; Expression expr = null; PrimitiveType type = PrimitiveType.CreateWord(mem.Width.Size); bool ripRelative = false; if (mem.Base != RegisterStorage.None) { if (mem.Base == Registers.rip) { ripRelative = true; } else { eBase = AluRegister(mem.Base); if (expr != null) { expr = new BinaryExpression(Operator.IAdd, eBase.DataType, eBase, expr); } else { expr = eBase; } } } if (mem.Offset.IsValid) { if (ripRelative) { expr = instr.Address + (instr.Length + mem.Offset.ToInt64()); } else if (expr != null) { BinaryOperator op = Operator.IAdd; long l = mem.Offset.ToInt64(); if (l < 0 && l > -0x800) { l = -l; op = Operator.ISub; } DataType dt = (eBase != null) ? eBase.DataType : eIndex.DataType; Constant cOffset = Constant.Create(dt, l); expr = new BinaryExpression(op, dt, expr, cOffset); } else { expr = mem.Offset; } } if (mem.Index != RegisterStorage.None) { eIndex = AluRegister(mem.Index); if (mem.Scale != 0 && mem.Scale != 1) { eIndex = new BinaryExpression( Operator.IMul, eIndex.DataType, eIndex, Constant.Create(mem.Width, mem.Scale)); } expr = new BinaryExpression(Operator.IAdd, expr.DataType, expr, eIndex); } return expr; }
/// <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.len = instrCur.Length; this.rtlInstructions = new List <RtlInstruction>(); this.rtlc = RtlClass.Linear; m = new RtlEmitter(rtlInstructions); orw = arch.ProcessorMode.CreateOperandRewriter(arch, m, binder, host); switch (instrCur.code) { default: host.Warn( dasm.Current.Address, "Rewriting x86 opcode '{0}' is not supported yet.", instrCur.code); goto case Opcode.illegal; case Opcode.illegal: rtlc = RtlClass.Invalid; m.Invalid(); break; case Opcode.aaa: RewriteAaa(); break; case Opcode.aad: RewriteAad(); break; case Opcode.aam: RewriteAam(); break; case Opcode.aas: RewriteAas(); break; case Opcode.adc: RewriteAdcSbb(m.IAdd); break; case Opcode.add: RewriteAddSub(Operator.IAdd); break; case Opcode.addss: RewriteScalarBinop(m.FAdd, PrimitiveType.Real32); break; case Opcode.addsd: case Opcode.vaddsd: RewriteScalarBinop(m.FAdd, PrimitiveType.Real64); break; case Opcode.addps: RewritePackedBinop("__addps", PrimitiveType.Real32); break; case Opcode.aesimc: RewriteAesimc(); break; case Opcode.and: RewriteLogical(Operator.And); break; case Opcode.arpl: RewriteArpl(); break; case Opcode.bound: RewriteBound(); 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: m.Assign(orw.FlagGroup(FlagM.CF), m.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.cvtpi2ps: RewriteCvtPackedToReal(PrimitiveType.Real32); break; case Opcode.cvtsi2sd: case Opcode.vcvtsi2sd: RewriteCvtToReal(PrimitiveType.Real64); break; case Opcode.cvtsi2ss: case Opcode.vcvtsi2ss: RewriteCvtToReal(PrimitiveType.Real32); break; case Opcode.cvttsd2si: RewriteCvtts2si(PrimitiveType.Real64); break; case Opcode.cvttss2si: RewriteCvtts2si(PrimitiveType.Real32); break; case Opcode.cvttps2pi: RewriteCvttps2pi(); 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(m.UDiv, Domain.UnsignedInt); break; case Opcode.divps: RewritePackedBinop("__divps", PrimitiveType.Real32); break; case Opcode.divsd: RewriteScalarBinop(m.FDiv, PrimitiveType.Real64); break; case Opcode.divss: RewriteScalarBinop(m.FDiv, PrimitiveType.Real32); break; case Opcode.f2xm1: RewriteF2xm1(); break; case Opcode.enter: RewriteEnter(); break; case Opcode.fabs: RewriteFabs(); break; case Opcode.fadd: EmitCommonFpuInstruction(m.FAdd, false, false); break; case Opcode.faddp: EmitCommonFpuInstruction(m.FAdd, false, true); break; case Opcode.fbld: RewriteFbld(); break; case Opcode.fbstp: RewriteFbstp(); 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.fdecstp: RewriteFdecstp(); break; case Opcode.fdiv: EmitCommonFpuInstruction(m.FDiv, false, false); break; case Opcode.fdivp: EmitCommonFpuInstruction(m.FDiv, false, true); break; case Opcode.ffree: RewriteFfree(); break; case Opcode.fiadd: EmitCommonFpuInstruction(m.FAdd, false, false, PrimitiveType.Real64); break; case Opcode.ficom: RewriteFicom(false); break; case Opcode.ficomp: RewriteFicom(true); break; case Opcode.fimul: EmitCommonFpuInstruction(m.FMul, false, false, PrimitiveType.Real64); break; case Opcode.fisub: EmitCommonFpuInstruction(m.FSub, false, false, PrimitiveType.Real64); break; case Opcode.fisubr: EmitCommonFpuInstruction(m.FSub, true, false, PrimitiveType.Real64); break; case Opcode.fidiv: EmitCommonFpuInstruction(m.FDiv, false, false, PrimitiveType.Real64); break; case Opcode.fidivr: EmitCommonFpuInstruction(m.FDiv, true, false, PrimitiveType.Real64); break; case Opcode.fdivr: EmitCommonFpuInstruction(m.FDiv, true, false); break; case Opcode.fdivrp: EmitCommonFpuInstruction(m.FDiv, true, true); break; case Opcode.fild: RewriteFild(); break; case Opcode.fincstp: RewriteFincstp(); break; case Opcode.fist: RewriteFist(false); break; case Opcode.fistp: RewriteFist(true); break; case Opcode.fld: RewriteFld(); break; case Opcode.fld1: RewriteFldConst(1.0); break; case Opcode.fldcw: RewriteFldcw(); break; case Opcode.fldenv: RewriteFldenv(); break; case Opcode.fldl2e: RewriteFldConst(Constant.LgE()); break; case Opcode.fldl2t: RewriteFldConst(Constant.Lg10()); break; case Opcode.fldlg2: RewriteFldConst(Constant.Log2()); 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(m.FMul, false, false); break; case Opcode.fmulp: EmitCommonFpuInstruction(m.FMul, false, true); break; case Opcode.fninit: RewriteFninit(); break; case Opcode.fpatan: RewriteFpatan(); break; case Opcode.fprem: RewriteFprem(); break; case Opcode.fptan: RewriteFptan(); break; case Opcode.frndint: RewriteFUnary("__rndint"); break; case Opcode.frstor: RewriteFrstor(); break; case Opcode.fsave: RewriteFsave(); break; case Opcode.fscale: RewriteFscale(); 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.fstenv: RewriteFstenv(); break; case Opcode.fstcw: RewriterFstcw(); break; case Opcode.fstp: RewriteFst(true); break; case Opcode.fstsw: RewriteFstsw(); break; case Opcode.fsub: EmitCommonFpuInstruction(m.FSub, false, false); break; case Opcode.fsubp: EmitCommonFpuInstruction(m.FSub, false, true); break; case Opcode.fsubr: EmitCommonFpuInstruction(m.FSub, true, false); break; case Opcode.fsubrp: EmitCommonFpuInstruction(m.FSub, true, true); break; case Opcode.ftst: RewriteFtst(); break; case Opcode.fucomi: RewrteFucomi(false); break; case Opcode.fucomip: RewrteFucomi(true); break; case Opcode.fucompp: RewriteFcom(2); break; case Opcode.fxam: RewriteFxam(); break; case Opcode.fxch: RewriteExchange(); break; case Opcode.fyl2x: RewriteFyl2x(); break; case Opcode.fyl2xp1: RewriteFyl2xp1(); break; case Opcode.hlt: RewriteHlt(); break; case Opcode.idiv: RewriteDivide(m.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.into: RewriteInto(); 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.lfence: RewriteLfence(); 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.mfence: RewriteMfence(); break; case Opcode.mov: RewriteMov(); break; case Opcode.movapd: case Opcode.movaps: case Opcode.vmovapd: case Opcode.vmovaps: RewriteMov(); break; case Opcode.movd: RewriteMovzx(); break; case Opcode.movdqa: RewriteMov(); break; case Opcode.movlhps: RewriteMovlhps(); break; case Opcode.movq: RewriteMov(); break; case Opcode.movs: RewriteStringInstruction(); break; case Opcode.movsb: RewriteStringInstruction(); break; case Opcode.movsd: case Opcode.vmovsd: RewriteMovssd(PrimitiveType.Real64); break; case Opcode.movss: case Opcode.vmovss: RewriteMovssd(PrimitiveType.Real32); break; case Opcode.movsx: RewriteMovsx(); break; case Opcode.movups: RewriteMov(); break; case Opcode.movupd: RewriteMov(); break; case Opcode.movzx: RewriteMovzx(); break; case Opcode.mul: RewriteMultiply(Operator.UMul, Domain.UnsignedInt); break; case Opcode.mulpd: RewritePackedBinop("__mulpd", PrimitiveType.Real64); break; case Opcode.mulps: RewritePackedBinop("__mulps", PrimitiveType.Real32); break; case Opcode.mulss: RewriteScalarBinop(m.FMul, PrimitiveType.Real32); break; case Opcode.mulsd: RewriteScalarBinop(m.FMul, PrimitiveType.Real64); break; case Opcode.neg: RewriteNeg(); break; case Opcode.nop: m.Nop(); break; 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.pause: RewritePause(); break; case Opcode.palignr: RewritePalignr(); break; case Opcode.pcmpeqb: RewritePcmpeqb(); break; case Opcode.pop: RewritePop(); break; case Opcode.popa: RewritePopa(); break; case Opcode.popf: RewritePopf(); break; case Opcode.prefetchnta: RewritePrefetch("__prefetchnta"); break; case Opcode.prefetcht0: RewritePrefetch("__prefetcht0"); break; case Opcode.prefetcht1: RewritePrefetch("__prefetcht1"); break; case Opcode.prefetcht2: RewritePrefetch("__prefetcht2"); 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.ret: RewriteRet(); break; case Opcode.retf: RewriteRet(); break; case Opcode.sahf: m.Assign(orw.FlagGroup(X86Instruction.DefCc(instrCur.code)), orw.AluRegister(Registers.ah)); break; case Opcode.sar: RewriteBinOp(Operator.Sar); break; case Opcode.sbb: RewriteAdcSbb(m.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.setno: RewriteSet(ConditionCode.NO); break; case Opcode.setns: RewriteSet(ConditionCode.NS); break; case Opcode.setnz: RewriteSet(ConditionCode.NE); break; case Opcode.setpe: RewriteSet(ConditionCode.PE); break; case Opcode.setpo: RewriteSet(ConditionCode.PO); 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: RewriteSti(); break; case Opcode.stos: RewriteStringInstruction(); break; case Opcode.stosb: RewriteStringInstruction(); break; case Opcode.sub: RewriteAddSub(BinaryOperator.ISub); break; case Opcode.subsd: RewriteScalarBinop(m.FSub, PrimitiveType.Real64); break; case Opcode.subss: RewriteScalarBinop(m.FSub, PrimitiveType.Real32); break; case Opcode.subps: RewritePackedBinop("__subps", PrimitiveType.Real32); break; case Opcode.ucomiss: RewriteComis(PrimitiveType.Real32); break; case Opcode.ucomisd: RewriteComis(PrimitiveType.Real64); break; case Opcode.test: RewriteTest(); break; case Opcode.wait: RewriteWait(); break; case Opcode.xadd: RewriteXadd(); break; case Opcode.xchg: RewriteExchange(); break; case Opcode.xgetbv: RewriteXgetbv(); break; case Opcode.xsetbv: RewriteXsetbv(); break; case Opcode.xlat: RewriteXlat(); break; case Opcode.xor: RewriteLogical(BinaryOperator.Xor); break; case Opcode.xorpd: case Opcode.vxorpd: RewritePackedBinop("__xorpd", PrimitiveType.Word64); break; case Opcode.xorps: RewritePackedBinop("__xorps", PrimitiveType.Word32); break; case Opcode.BOR_exp: RewriteFUnary("exp"); break; case Opcode.BOR_ln: RewriteFUnary("log"); break; } yield return(new RtlInstructionCluster(addr, len, rtlInstructions.ToArray()) { Class = rtlc }); } }