private void MaybeUpdateFlags(Expression opDst) { if (instr.ArchitectureDetail.UpdateFlags) { m.Assign(frame.EnsureFlagGroup(A32Registers.cpsr, 0x1111, "NZCV", PrimitiveType.Byte), m.Cond(opDst)); } }
/// <summary> /// Breaks up very common case of x86: /// <code> /// op [memaddr], reg /// </code> /// into the equivalent: /// <code> /// tmp := [memaddr] op reg; /// store([memaddr], tmp); /// </code> /// </summary> /// <param name="opDst"></param> /// <param name="src"></param> /// <param name="forceBreak">if true, forcibly splits the assignments in two if the destination is a memory store.</param> /// <returns>Returns the destination of the copy.</returns> public void EmitCopy(MachineOperand opDst, Expression src, CopyFlags flags) { Expression dst = SrcOp(opDst); Identifier idDst = dst as Identifier; if (idDst != null || (flags & CopyFlags.ForceBreak) == 0) { emitter.Assign(dst, src); } else { Identifier tmp = frame.CreateTemporary(opDst.Width); emitter.Assign(tmp, src); var ea = orw.CreateMemoryAccess(instrCur, (MemoryOperand)opDst, state); emitter.Assign(ea, tmp); dst = tmp; } if ((flags & CopyFlags.EmitCc) != 0) { EmitCcInstr(dst, X86Instruction.DefCc(instrCur.code)); } if ((flags & CopyFlags.SetCfIf0) != 0) { emitter.Assign(orw.FlagGroup(FlagM.CF), emitter.Eq0(dst)); } }
private void RewriteLoad(MipsInstruction instr) { var opSrc = RewriteOperand(instr.op2); var opDst = RewriteOperand(instr.op1); emitter.Assign(opDst, emitter.Cast(arch.WordWidth, opSrc)); }
private void Push(Expression exp) { var sp = binder.EnsureRegister(arch.StackRegister); m.Assign(sp, m.ISub(sp, m.Int32(8))); m.Assign(m.Mem(exp.DataType, sp), exp); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (instrs.MoveNext()) { var instr = instrs.Current; var rtlCluster = new RtlInstructionCluster(instr.Address, instr.Length); emitter = new RtlEmitter(rtlCluster.Instructions); switch (instr.Opcode) { default: throw new AddressCorrelatedException( instr.Address, "Rewriting of PDP-11 instruction {0} not supported yet.", instr.Opcode); case Opcodes.xor: var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op2); emitter.Assign(dst, emitter.Xor(dst, src)); emitter.Assign( frame.EnsureFlagGroup((uint)(FlagM.NF | FlagM.ZF), "NZ", PrimitiveType.Byte), emitter.Cond(dst)); emitter.Assign(frame.EnsureFlagGroup((uint)FlagM.CF, "C", PrimitiveType.Bool), Constant.False()); emitter.Assign(frame.EnsureFlagGroup((uint)FlagM.VF, "V", PrimitiveType.Bool), Constant.False()); break; } yield return(rtlCluster); } }
/// <summary> /// Generates assignments, with special-case logic to break up /// instructions where the destination is a memory address. /// </summary> /// <remarks> /// The special case breaks instructions that write to memory /// like this: /// <code> /// op [memaddr], reg /// </code> /// into into the equivalent: /// <code> /// tmp := [memaddr] op reg; /// store([memaddr], tmp); /// </code> /// This makes analysis easier for the subsequent phases of the /// decompiler. /// </remarks> public void EmitCopy(MachineOperand opDst, Expression src, CopyFlags flags) { Expression dst = SrcOp(opDst); if (dst is Identifier idDst) { AssignToRegister(idDst, src); } else { var tmp = binder.CreateTemporary(opDst.Width); m.Assign(tmp, src); var ea = orw.CreateMemoryAccess(instrCur, (MemoryOperand)opDst, state); m.Assign(ea, tmp); dst = tmp; } if ((flags & CopyFlags.EmitCc) != 0) { EmitCcInstr(dst, X86Instruction.DefCc(instrCur.Mnemonic)); } if ((flags & CopyFlags.SetCfIf0) != 0) { m.Assign(orw.FlagGroup(FlagM.CF), m.Eq0(dst)); } }
private Expression DstOperand(int iOperand, Expression src) { switch (instr.Operands[iOperand]) { case RegisterOperand rop: var dst = binder.EnsureRegister(rop.Register); m.Assign(dst, src); return(dst); case ImmediateOperand imm: return(imm.Value); case MemoryOperand mem: var ea = EffectiveAddress(mem); m.Assign(m.Mem(mem.Width, ea), src); return(src); case RegisterRange range: var extReg = ExtendedRegister(range); m.Assign(extReg, src); return(extReg); default: throw new NotImplementedException($"Operand type {instr.Operands[iOperand].GetType().Name}."); } }
private void RewriteAndNot() { var src1 = Operand(instr.Operands[1]); var dst = Operand(instr.Operands[0]); m.Assign(dst, m.And(dst, m.Comp(src1))); }
private void Rewrite3(Func <Expression, Expression, Expression> fn) { var dst = Rewrite(instrCur.Operands[0]); var src1 = Rewrite(instrCur.Operands[1]); var src2 = Rewrite(instrCur.Operands[2]); m.Assign(dst, fn(src1, src2)); }
private void EmitCc(Expression dst) { m.Assign( binder.EnsureFlagGroup( arch.Registers.psr, 0xF, "NZVC", PrimitiveType.Byte), m.Cond(dst)); }
private Expression RewriteSrc(MachineOperand op) { var reg = op as RegisterOperand; if (reg != null) { return(binder.EnsureRegister(reg.Register)); } var addr = op as AddressOperand; if (addr != null) { return(addr.Address); } var imm = op as ImmediateOperand; if (imm != null) { return(imm.Value); } var mem = op as MemoryOperand; if (mem != null) { Expression ea = RewriteSrcEa(mem); var tmp = binder.CreateTemporary(mem.Width); m.Assign(tmp, m.Mem(mem.Width, ea)); return(tmp); } throw new NotImplementedException(op.GetType().Name); }
private Expression RewriteOp(int iOp) { switch (instr.Operands[iOp]) { case RegisterOperand r: if (r.Register == arch.Registers.GpRegs[0]) { return(Constant.Zero(r.Register.DataType)); } else { return(binder.EnsureRegister(r.Register)); } case ImmediateOperand i: return(i.Value); case LeftImmediateOperand l: return(l.Value); case AddressOperand a: return(a.Address); case MemoryOperand mem: Identifier rb = binder.EnsureRegister(mem.Base); Expression ea = rb; if (mem.Index != null) { if (mem.Index != arch.Registers.GpRegs[0]) { var idx = binder.EnsureRegister(mem.Index); ea = m.IAdd(ea, idx); } } else if (mem.Offset != 0) { ea = m.IAddS(ea, mem.Offset); } if (instr.BaseReg == AddrRegMod.mb) { m.Assign(rb, ea); ea = rb; } else if (instr.BaseReg == AddrRegMod.ma) { var tmp = binder.CreateTemporary(rb.DataType); m.Assign(tmp, ea); m.Assign(rb, tmp); ea = tmp; } return(m.Mem(mem.Width, ea)); } throw new NotImplementedException($"Unimplemented PA-RISC operand type {instr.Operands[iOp].GetType()}."); }
private void RewriteIntrinsic(string intrinsicName, bool isIntrinsic) { var dst = Op(0); var args = Enumerable.Range(1, instrCur.Operands.Length - 1) .Select(i => Op(i)) .ToArray(); m.Assign(dst, host.Intrinsic(intrinsicName, isIntrinsic, dst.DataType, args)); }
private void MaybeSignExtend(Expression dst, Expression src, DataType dt) { if (dt != null && dt.BitSize < dst.DataType.BitSize) { src = m.Cast(arch.NaturalSignedInteger, m.Cast(dt, src)); } m.Assign(dst, src); }
void CheckForLoopExit() { if (lend == null) { return; } if (instr.Address.ToLinear() + (uint)instr.Length == lend.ToLinear()) { var addrNext = instr.Address + instr.Length; var lcount = binder.EnsureRegister(Registers.LCOUNT); m.BranchInMiddleOfInstruction(m.Eq0(lcount), addrNext, InstrClass.ConditionalTransfer); m.Assign(lcount, m.ISub(lcount, 1)); m.Goto(this.lbegin); lbegin = null; lend = null; } }
private void RewriteLet() { Expression lhs = ExpectLValue(); Expect((byte)Token.eq); Expression rhs = ParseExpr(); emitter.Assign(lhs, rhs); }
private void EmitCc(Expression dst) { emitter.Assign( frame.EnsureFlagGroup( Registers.psr, 0xF, "NZVC", PrimitiveType.Byte), emitter.Cond(dst)); }
private void RewriteBinary(MipsInstruction instr, Func <Expression, Expression, Expression> fn) { Expression dst, left, right; if (instr.Operands.Length == 2) { dst = Rewrite(instr.Operands[0]); left = dst; right = Rewrite(instr.Operands[1]); } else { dst = Rewrite(instr.Operands[0]); left = Rewrite(instr.Operands[1]); right = Rewrite(instr.Operands[2]); } m.Assign(dst, fn(left, right)); }
public override List <RtlInstruction> InlineCall( IServiceProvider services, Address addrCallee, Address addrContinuation, EndianImageReader rdr, IStorageBinder binder) { var dasm = CreateDisassembler(services, rdr, new X86Options()); var instrs = dasm.Take(2).ToArray(); if (instrs.Length < 2) { return(null); } // Detect the pattern // mov <reg>,[esp+0] // ret // which is used by i386 ELF binaries to capture // the value in the EIP register. if (instrs[0].Mnemonic == Mnemonic.mov && instrs[1].Mnemonic == Mnemonic.ret) { if (!(instrs[0].Operands[1] is MemoryOperand mop)) { return(null); } if (mop.Base != StackRegister) { return(null); } if (mop.Offset != null && mop.Offset.IsValid && !mop.Offset.IsIntegerZero) { return(null); } if (mop.Index != null && mop.Index != RegisterStorage.None) { return(null); } if (instrs[1].Operands.Length > 0) { return(null); } var reg = binder.EnsureRegister(((RegisterOperand)instrs[0].Operands[0]).Register); var rtls = new List <RtlInstruction>(); var m = new RtlEmitter(rtls); m.Assign(reg, addrContinuation); return(rtls); } return(null); }
private Expression Operand(ArmInstructionOperand op) { switch (op.Type) { case ArmInstructionOperandType.Register: var reg = frame.EnsureRegister(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value]); return(MaybeShiftOperand(reg, op)); case ArmInstructionOperandType.Immediate: return(Constant.Word32(op.ImmediateValue.Value)); case ArmInstructionOperandType.Memory: Expression baseReg = Reg(op.MemoryValue.BaseRegister); Expression ea = baseReg; if (op.MemoryValue.BaseRegister == ArmRegister.PC) // PC-relative address { if (op.MemoryValue.Displacement != 0) { var dst = (uint)((int)instrs.Current.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u; return(emitter.Load(SizeFromLoadStore(instr), Address.Ptr32(dst))); } } if (op.MemoryValue.Displacement != 0 && instrs.Current.IsLastOperand(op)) { var offset = Constant.Int32(op.MemoryValue.Displacement); ea = op.MemoryValue.IndexRegisterScale < 0 ? emitter.ISub(ea, offset) : emitter.IAdd(ea, offset); } if (instrs.Current.IsLastOperand(op) && instr.ArchitectureDetail.WriteBack) { emitter.Assign(baseReg, ea); ea = baseReg; } return(emitter.Load(SizeFromLoadStore(instr), ea)); } throw new NotImplementedException(op.Type.ToString()); }
private Expression RewriteSrc(MachineOperand op) { var memOp = op as MemoryOperand; if (memOp != null) { var r = frame.EnsureRegister(memOp.Register); var tmp = frame.CreateTemporary(op.Width); if (memOp.Mode == AddressMode.AutoIncr) { emitter.Assign(tmp, emitter.Load(op.Width, r)); emitter.Assign(r, emitter.IAdd(r, memOp.Width.Size)); return(tmp); } return(tmp); } var regOp = op as RegisterOperand; if (regOp != null) { return(frame.EnsureRegister(regOp.Register)); } throw new NotImplementedException(); }
public void EmitCc(Expression exp, string szhvnc) { // SZIH XVNC var mask = 1u << 7; uint grf = 0; foreach (var c in szhvnc) { switch (c) { case '*': case 'S': case 'Z': case 'I': case 'H': case 'X': case 'V': case 'N': case 'C': grf |= mask; break; case '0': m.Assign( binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, mask)), Constant.False()); break; case '1': m.Assign( binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, mask)), Constant.True()); break; } mask >>= 1; } if (grf != 0) { m.Assign( binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, grf)), m.Cond(exp)); } }
private void SetFlags(Expression?e, FlagGroupStorage changed) { if (e == null) { Invalid(); return; } if (changed != null) { var grfChanged = binder.EnsureFlagGroup(changed); m.Assign(grfChanged, m.Cond(e)); } }
private Expression Assign(Expression dst, Expression src) { var excessBits = dst.DataType.BitSize - src.DataType.BitSize; if (excessBits > 0) { if (!(src is Identifier || src is Constant)) { var tmp = binder.CreateTemporary(src.DataType); m.Assign(tmp, src); src = tmp; } var seq = m.Dpb(dst, src, 0); m.Assign(dst, seq); return(seq.Expressions[1]); } else { m.Assign(dst, src); return(dst); } }
private Expression OpSrc(MachineOperand op) { switch (op) { case RegisterOperand reg: return(binder.EnsureRegister(reg.Register)); case ImmediateOperand imm: return(imm.Value); case MemoryOperand mem: Expression ea; if (mem.Base != null) { var regBase = binder.EnsureRegister(mem.Base); if (mem.PostIncrement) { ea = binder.CreateTemporary(regBase.DataType); m.Assign(ea, regBase); } else if (mem.PreDecrement) { m.Assign(regBase, m.ISubS(regBase, mem.Width.Size)); ea = regBase; } else { ea = m.AddSubSignedInt(regBase, mem.Offset); } } else { ea = Address.Ptr16((ushort)mem.Offset); } return(m.Mem(mem.Width ?? (DataType)VoidType.Instance, ea)); } throw new NotImplementedException(); }
private void NZCV(Expression test) { var nzcv = NZCV(); m.Assign(nzcv, test); }
/// <summary> /// Iterator that yields one RtlIntructionCluster for each x86 instruction. /// </summary> /// <returns></returns> public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { instrCur = dasm.Current; var addr = instrCur.Address; this.rtlInstructions = new List <RtlInstruction>(); this.iclass = instrCur.InstructionClass; m = new RtlEmitter(rtlInstructions); orw = arch.ProcessorMode.CreateOperandRewriter(arch, m, binder, host); switch (instrCur.Mnemonic) { default: EmitUnitTest(); host.Warn( dasm.Current.Address, "x86 instruction '{0}' is not supported yet.", instrCur.Mnemonic); goto case Mnemonic.illegal; case Mnemonic.illegal: iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.aaa: RewriteAaa(); break; case Mnemonic.aad: RewriteAad(); break; case Mnemonic.aam: RewriteAam(); break; case Mnemonic.aas: RewriteAas(); break; case Mnemonic.adc: RewriteAdcSbb(m.IAdd); break; case Mnemonic.add: RewriteAddSub(Operator.IAdd); break; case Mnemonic.addss: RewriteScalarBinop(m.FAdd, PrimitiveType.Real32, false); break; case Mnemonic.vaddss: RewriteScalarBinop(m.FAdd, PrimitiveType.Real32, true); break; case Mnemonic.addsd: RewriteScalarBinop(m.FAdd, PrimitiveType.Real64, false); break; case Mnemonic.vaddsd: RewriteScalarBinop(m.FAdd, PrimitiveType.Real64, true); break; case Mnemonic.addps: RewritePackedBinop("__addps", PrimitiveType.Real32); break; case Mnemonic.addpd: RewritePackedBinop("__addpd", PrimitiveType.Real64); break; case Mnemonic.aesimc: RewriteAesimc(); break; case Mnemonic.and: RewriteLogical(Operator.And); break; case Mnemonic.andnps: RewriteAndnps(); break; case Mnemonic.andpd: RewritePackedBinop("__andpd", PrimitiveType.Real64); break; case Mnemonic.andps: RewritePackedBinop("__andps", PrimitiveType.Real32); break; case Mnemonic.arpl: RewriteArpl(); break; case Mnemonic.bound: RewriteBound(); break; case Mnemonic.bsf: RewriteBsf(); break; case Mnemonic.bsr: RewriteBsr(); break; case Mnemonic.bswap: RewriteBswap(); break; case Mnemonic.bt: RewriteBt(); break; case Mnemonic.btc: RewriteBtc(); break; case Mnemonic.btr: RewriteBtr(); break; case Mnemonic.bts: RewriteBts(); break; case Mnemonic.call: RewriteCall(instrCur.Operands[0], instrCur.Operands[0].Width); break; case Mnemonic.cbw: RewriteCbw(); break; case Mnemonic.cdq: RewriteCdq(); break; case Mnemonic.cdqe: RewriteCdqe(); break; case Mnemonic.cqo: RewriteCqo(); break; case Mnemonic.clc: RewriteSetFlag(FlagM.CF, Constant.False()); break; case Mnemonic.cld: RewriteSetFlag(FlagM.DF, Constant.False()); break; case Mnemonic.cli: RewriteCli(); break; case Mnemonic.clts: RewriteClts(); break; case Mnemonic.cmc: m.Assign(orw.FlagGroup(FlagM.CF), m.Not(orw.FlagGroup(FlagM.CF))); break; case Mnemonic.cmova: RewriteConditionalMove(ConditionCode.UGT, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovbe: RewriteConditionalMove(ConditionCode.ULE, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovc: RewriteConditionalMove(ConditionCode.ULT, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovge: RewriteConditionalMove(ConditionCode.GE, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovg: RewriteConditionalMove(ConditionCode.GT, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovl: RewriteConditionalMove(ConditionCode.LT, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovle: RewriteConditionalMove(ConditionCode.LE, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovnc: RewriteConditionalMove(ConditionCode.UGE, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovno: RewriteConditionalMove(ConditionCode.NO, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovns: RewriteConditionalMove(ConditionCode.NS, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovnz: RewriteConditionalMove(ConditionCode.NE, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovo: RewriteConditionalMove(ConditionCode.OV, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovpe: RewriteConditionalMove(ConditionCode.PE, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovpo: RewriteConditionalMove(ConditionCode.PO, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovs: RewriteConditionalMove(ConditionCode.SG, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmovz: RewriteConditionalMove(ConditionCode.EQ, instrCur.Operands[0], instrCur.Operands[1]); break; case Mnemonic.cmpxchg: RewriteCmpxchg(); break; case Mnemonic.cmpxchg8b: RewriteCmpxchgNb("__cmpxchg8b", Registers.edx, Registers.eax, Registers.ecx, Registers.ebx); break; case Mnemonic.cmpxchg16b: RewriteCmpxchgNb("__cmpxchg16b", Registers.rdx, Registers.rax, Registers.rcx, Registers.rbx); break; case Mnemonic.cmp: RewriteCmp(); break; case Mnemonic.cmps: RewriteStringInstruction(); break; case Mnemonic.cmppd: RewriteCmpp("__cmppd", PrimitiveType.Real64); break; case Mnemonic.cmpps: RewriteCmpp("__cmpps", PrimitiveType.Real32); break; case Mnemonic.cmpsb: RewriteStringInstruction(); break; case Mnemonic.comisd: RewriteComis(PrimitiveType.Real64); break; case Mnemonic.comiss: RewriteComis(PrimitiveType.Real32); break; case Mnemonic.cpuid: RewriteCpuid(); break; case Mnemonic.cvtpi2ps: RewriteCvtPackedToReal(PrimitiveType.Real32); break; case Mnemonic.cvtps2pi: RewriteCvtps2pi("__cvtps2pi", PrimitiveType.Real32, PrimitiveType.Int32); break; case Mnemonic.cvtps2pd: RewriteCvtps2pi("__cvtps2pd", PrimitiveType.Real32, PrimitiveType.Real64); break; case Mnemonic.cvtdq2ps: RewriteCvtps2pi("__cvtdq2ps", PrimitiveType.Int64, PrimitiveType.Real32); break; case Mnemonic.cvtsd2si: RewriteCvts2si(PrimitiveType.Real64); break; case Mnemonic.cvtsd2ss: RewriteCvtToReal(PrimitiveType.Real32); break; case Mnemonic.cvtsi2ss: case Mnemonic.vcvtsi2ss: RewriteCvtToReal(PrimitiveType.Real32); break; case Mnemonic.cvtsi2sd: case Mnemonic.vcvtsi2sd: RewriteCvtToReal(PrimitiveType.Real64); break; case Mnemonic.cvtss2sd: RewriteCvtToReal(PrimitiveType.Real64); break; case Mnemonic.cvtss2si: RewriteCvts2si(PrimitiveType.Real32); break; case Mnemonic.cvttsd2si: RewriteCvtts2si(PrimitiveType.Real64); break; case Mnemonic.cvttss2si: RewriteCvtts2si(PrimitiveType.Real32); break; case Mnemonic.cvttps2pi: RewriteCvttps2pi(); break; case Mnemonic.cwd: RewriteCwd(); break; case Mnemonic.cwde: RewriteCwde(); break; case Mnemonic.daa: EmitDaaDas("__daa"); break; case Mnemonic.das: EmitDaaDas("__das"); break; case Mnemonic.dec: RewriteIncDec(-1); break; case Mnemonic.div: RewriteDivide(m.UDiv, Domain.UnsignedInt); break; case Mnemonic.divps: RewritePackedBinop("__divps", PrimitiveType.Real32); break; case Mnemonic.divsd: RewriteScalarBinop(m.FDiv, PrimitiveType.Real64, false); break; case Mnemonic.vdivsd: RewriteScalarBinop(m.FDiv, PrimitiveType.Real64, true); break; case Mnemonic.divss: RewriteScalarBinop(m.FDiv, PrimitiveType.Real32, false); break; case Mnemonic.vdivss: RewriteScalarBinop(m.FDiv, PrimitiveType.Real32, true); break; case Mnemonic.f2xm1: RewriteF2xm1(); break; case Mnemonic.emms: RewriteEmms(); break; case Mnemonic.enter: RewriteEnter(); break; case Mnemonic.fabs: RewriteFabs(); break; case Mnemonic.fadd: EmitCommonFpuInstruction(m.FAdd, false, false); break; case Mnemonic.faddp: EmitCommonFpuInstruction(m.FAdd, false, true); break; case Mnemonic.fbld: RewriteFbld(); break; case Mnemonic.fbstp: RewriteFbstp(); break; case Mnemonic.fchs: EmitFchs(); break; case Mnemonic.fclex: RewriteFclex(); break; case Mnemonic.fcmovb: RewriteFcmov(FlagM.CF, ConditionCode.GE); break; case Mnemonic.fcmovbe: RewriteFcmov(FlagM.CF | FlagM.ZF, ConditionCode.GT); break; case Mnemonic.fcmove: RewriteFcmov(FlagM.ZF, ConditionCode.NE); break; case Mnemonic.fcmovnb: RewriteFcmov(FlagM.CF | FlagM.ZF, ConditionCode.GE); break; case Mnemonic.fcmovnbe: RewriteFcmov(FlagM.CF | FlagM.ZF, ConditionCode.LE); break; case Mnemonic.fcmovne: RewriteFcmov(FlagM.ZF, ConditionCode.EQ); break; case Mnemonic.fcmovnu: RewriteFcmov(FlagM.PF, ConditionCode.IS_NAN); break; case Mnemonic.fcmovu: RewriteFcmov(FlagM.PF, ConditionCode.NOT_NAN); break; case Mnemonic.fcom: RewriteFcom(0); break; case Mnemonic.fcomi: RewriteFcomi(false); break; case Mnemonic.fcomip: RewriteFcomi(true); break; case Mnemonic.fcomp: RewriteFcom(1); break; case Mnemonic.fcompp: RewriteFcom(2); break; case Mnemonic.fcos: RewriteFUnary("cos"); break; case Mnemonic.fdecstp: RewriteFdecstp(); break; case Mnemonic.fdiv: EmitCommonFpuInstruction(m.FDiv, false, false); break; case Mnemonic.fdivp: EmitCommonFpuInstruction(m.FDiv, false, true); break; case Mnemonic.femms: RewriteFemms(); break; case Mnemonic.ffree: RewriteFfree(false); break; case Mnemonic.ffreep: RewriteFfree(true); break; case Mnemonic.fiadd: EmitCommonFpuInstruction(m.FAdd, false, false, PrimitiveType.Real64); break; case Mnemonic.ficom: RewriteFicom(false); break; case Mnemonic.ficomp: RewriteFicom(true); break; case Mnemonic.fimul: EmitCommonFpuInstruction(m.FMul, false, false, PrimitiveType.Real64); break; case Mnemonic.fisub: EmitCommonFpuInstruction(m.FSub, false, false, PrimitiveType.Real64); break; case Mnemonic.fisubr: EmitCommonFpuInstruction(m.FSub, true, false, PrimitiveType.Real64); break; case Mnemonic.fidiv: EmitCommonFpuInstruction(m.FDiv, false, false, PrimitiveType.Real64); break; case Mnemonic.fidivr: EmitCommonFpuInstruction(m.FDiv, true, false, PrimitiveType.Real64); break; case Mnemonic.fdivr: EmitCommonFpuInstruction(m.FDiv, true, false); break; case Mnemonic.fdivrp: EmitCommonFpuInstruction(m.FDiv, true, true); break; case Mnemonic.fild: RewriteFild(); break; case Mnemonic.fincstp: RewriteFincstp(); break; case Mnemonic.fist: RewriteFist(false); break; case Mnemonic.fistp: RewriteFist(true); break; case Mnemonic.fisttp: RewriteFistt(true); break; case Mnemonic.fld: RewriteFld(); break; case Mnemonic.fld1: RewriteFldConst(1.0); break; case Mnemonic.fldcw: RewriteFldcw(); break; case Mnemonic.fldenv: RewriteFldenv(); break; case Mnemonic.fldl2e: RewriteFldConst(Constant.LgE()); break; case Mnemonic.fldl2t: RewriteFldConst(Constant.Lg10()); break; case Mnemonic.fldlg2: RewriteFldConst(Constant.Log2()); break; case Mnemonic.fldln2: RewriteFldConst(Constant.Ln2()); break; case Mnemonic.fldpi: RewriteFldConst(Constant.Pi()); break; case Mnemonic.fldz: RewriteFldConst(0.0); break; case Mnemonic.fmul: EmitCommonFpuInstruction(m.FMul, false, false); break; case Mnemonic.fmulp: EmitCommonFpuInstruction(m.FMul, false, true); break; case Mnemonic.fninit: RewriteFninit(); break; case Mnemonic.fnop: m.Nop(); break; case Mnemonic.fnsetpm: m.Nop(); break; case Mnemonic.fpatan: RewriteFpatan(); break; case Mnemonic.fprem: RewriteFprem(); break; case Mnemonic.fprem1: RewriteFprem1(); break; case Mnemonic.fptan: RewriteFptan(); break; case Mnemonic.frndint: RewriteFUnary("__rndint"); break; case Mnemonic.frstor: RewriteFrstor(); break; case Mnemonic.fsave: RewriteFsave(); break; case Mnemonic.fscale: RewriteFscale(); break; case Mnemonic.fsin: RewriteFUnary("sin"); break; case Mnemonic.fsincos: RewriteFsincos(); break; case Mnemonic.fsqrt: RewriteFUnary("sqrt"); break; case Mnemonic.fst: RewriteFst(false); break; case Mnemonic.fstenv: RewriteFstenv(); break; case Mnemonic.fstcw: RewriterFstcw(); break; case Mnemonic.fstp: RewriteFst(true); break; case Mnemonic.fstsw: RewriteFstsw(); break; case Mnemonic.fsub: EmitCommonFpuInstruction(m.FSub, false, false); break; case Mnemonic.fsubp: EmitCommonFpuInstruction(m.FSub, false, true); break; case Mnemonic.fsubr: EmitCommonFpuInstruction(m.FSub, true, false); break; case Mnemonic.fsubrp: EmitCommonFpuInstruction(m.FSub, true, true); break; case Mnemonic.ftst: RewriteFtst(); break; case Mnemonic.fucom: RewriteFcom(0); break; case Mnemonic.fucomp: RewriteFcom(1); break; case Mnemonic.fucompp: RewriteFcom(2); break; case Mnemonic.fucomi: RewriteFcomi(false); break; case Mnemonic.fucomip: RewriteFcomi(true); break; case Mnemonic.fxam: RewriteFxam(); break; case Mnemonic.fxch: RewriteExchange(); break; case Mnemonic.fxtract: RewriteFxtract(); break; case Mnemonic.fyl2x: RewriteFyl2x(); break; case Mnemonic.fyl2xp1: RewriteFyl2xp1(); break; case Mnemonic.getsec: RewriteGetsec(); break; case Mnemonic.hlt: RewriteHlt(); break; case Mnemonic.icebp: RewriteIcebp(); break; case Mnemonic.idiv: RewriteDivide(m.SDiv, Domain.SignedInt); break; case Mnemonic.@in: RewriteIn(); break; case Mnemonic.imul: RewriteMultiply(Operator.SMul, Domain.SignedInt); break; case Mnemonic.inc: RewriteIncDec(1); break; case Mnemonic.insb: RewriteStringInstruction(); break; case Mnemonic.ins: RewriteStringInstruction(); break; case Mnemonic.invlpg: RewriteInvlpg(); break; case Mnemonic.@int: RewriteInt(); break; case Mnemonic.into: RewriteInto(); break; case Mnemonic.invd: RewriteInvd(); break; case Mnemonic.iret: RewriteIret(); break; case Mnemonic.jmp: RewriteJmp(); break; case Mnemonic.jmpe: RewriteJmpe(); break; case Mnemonic.ja: RewriteConditionalGoto(ConditionCode.UGT, instrCur.Operands[0]); break; case Mnemonic.jbe: RewriteConditionalGoto(ConditionCode.ULE, instrCur.Operands[0]); break; case Mnemonic.jc: RewriteConditionalGoto(ConditionCode.ULT, instrCur.Operands[0]); break; case Mnemonic.jcxz: RewriteJcxz(Registers.cx); break; case Mnemonic.jecxz: RewriteJcxz(Registers.ecx); break; case Mnemonic.jge: RewriteConditionalGoto(ConditionCode.GE, instrCur.Operands[0]); break; case Mnemonic.jg: RewriteConditionalGoto(ConditionCode.GT, instrCur.Operands[0]); break; case Mnemonic.jl: RewriteConditionalGoto(ConditionCode.LT, instrCur.Operands[0]); break; case Mnemonic.jle: RewriteConditionalGoto(ConditionCode.LE, instrCur.Operands[0]); break; case Mnemonic.jnc: RewriteConditionalGoto(ConditionCode.UGE, instrCur.Operands[0]); break; case Mnemonic.jno: RewriteConditionalGoto(ConditionCode.NO, instrCur.Operands[0]); break; case Mnemonic.jns: RewriteConditionalGoto(ConditionCode.NS, instrCur.Operands[0]); break; case Mnemonic.jnz: RewriteConditionalGoto(ConditionCode.NE, instrCur.Operands[0]); break; case Mnemonic.jo: RewriteConditionalGoto(ConditionCode.OV, instrCur.Operands[0]); break; case Mnemonic.jpe: RewriteConditionalGoto(ConditionCode.PE, instrCur.Operands[0]); break; case Mnemonic.jpo: RewriteConditionalGoto(ConditionCode.PO, instrCur.Operands[0]); break; case Mnemonic.jrcxz: RewriteJcxz(Registers.rcx); break; case Mnemonic.js: RewriteConditionalGoto(ConditionCode.SG, instrCur.Operands[0]); break; case Mnemonic.jz: RewriteConditionalGoto(ConditionCode.EQ, instrCur.Operands[0]); break; case Mnemonic.lahf: RewriteLahf(); break; case Mnemonic.lar: RewriteLar(); break; case Mnemonic.lds: RewriteLxs(Registers.ds); break; case Mnemonic.ldmxcsr: RewriteLdmxcsr(); break; case Mnemonic.stmxcsr: RewriteStmxcsr(); break; case Mnemonic.lea: RewriteLea(); break; case Mnemonic.leave: RewriteLeave(); break; case Mnemonic.les: RewriteLxs(Registers.es); break; case Mnemonic.lfence: RewriteLfence(); break; case Mnemonic.lfs: RewriteLxs(Registers.fs); break; case Mnemonic.lgs: RewriteLxs(Registers.gs); break; case Mnemonic.lgdt: RewriteLxdt("__lgdt"); break; case Mnemonic.lidt: RewriteLxdt("__lidt"); break; case Mnemonic.lldt: RewriteLxdt("__lldt"); break; case Mnemonic.lmsw: RewriteLmsw(); break; case Mnemonic.@lock: RewriteLock(); break; case Mnemonic.lods: RewriteStringInstruction(); break; case Mnemonic.lodsb: RewriteStringInstruction(); break; case Mnemonic.loop: RewriteLoop(0, ConditionCode.EQ); break; case Mnemonic.loope: RewriteLoop(FlagM.ZF, ConditionCode.EQ); break; case Mnemonic.loopne: RewriteLoop(FlagM.ZF, ConditionCode.NE); break; case Mnemonic.lsl: RewriteLsl(); break; case Mnemonic.lss: RewriteLxs(Registers.ss); break; case Mnemonic.ltr: RewriteLtr(); break; case Mnemonic.maskmovq: RewriteMaskmovq(); break; case Mnemonic.maxps: RewritePackedBinop("__maxps", PrimitiveType.Real32); break; case Mnemonic.mfence: RewriteMfence(); break; case Mnemonic.minpd: RewritePackedBinop("__minpd", PrimitiveType.Real64); break; case Mnemonic.minps: RewritePackedBinop("__minps", PrimitiveType.Real32); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.movapd: case Mnemonic.movaps: case Mnemonic.vmovapd: case Mnemonic.vmovaps: RewriteMov(); break; case Mnemonic.vmread: RewriteVmread(); break; case Mnemonic.vmwrite: RewriteVmwrite(); break; case Mnemonic.movbe: RewriteMovbe(); break; case Mnemonic.movd: RewriteMovzx(); break; case Mnemonic.movdqa: case Mnemonic.vmovdqa: RewriteMov(); break; case Mnemonic.movhpd: RewritePackedUnaryop("__movhpd", PrimitiveType.Real64, PrimitiveType.Real64); break; case Mnemonic.movhps: RewritePackedUnaryop("__movhps", PrimitiveType.Real32, PrimitiveType.Real64); break; case Mnemonic.movlpd: RewritePackedUnaryop("__movlpd", PrimitiveType.Real64, PrimitiveType.Real64); break; case Mnemonic.movlps: RewritePackedUnaryop("__movlps", PrimitiveType.Real32, PrimitiveType.Real64); break; case Mnemonic.movlhps: RewriteMovlhps(); break; case Mnemonic.movmskpd: RewriteMovmsk("__movmskpd", PrimitiveType.Real64); break; case Mnemonic.movmskps: RewriteMovmsk("__movmskps", PrimitiveType.Real32); break; case Mnemonic.movnti: RewriteMov(); break; case Mnemonic.movntps: RewriteMov(); break; case Mnemonic.movntq: RewriteMov(); break; case Mnemonic.movq: RewriteMov(); break; case Mnemonic.movs: RewriteStringInstruction(); break; case Mnemonic.movsb: RewriteStringInstruction(); break; case Mnemonic.movsd: case Mnemonic.vmovsd: RewriteMovssd(PrimitiveType.Real64); break; case Mnemonic.movss: case Mnemonic.vmovss: RewriteMovssd(PrimitiveType.Real32); break; case Mnemonic.movsx: RewriteMovsx(); break; case Mnemonic.movsxd: RewriteMovsx(); break; case Mnemonic.movups: RewriteMov(); break; case Mnemonic.movupd: RewriteMov(); break; case Mnemonic.movzx: RewriteMovzx(); break; case Mnemonic.mul: RewriteMultiply(Operator.UMul, Domain.UnsignedInt); break; case Mnemonic.mulpd: RewritePackedBinop("__mulpd", PrimitiveType.Real64); break; case Mnemonic.mulps: RewritePackedBinop("__mulps", PrimitiveType.Real32); break; case Mnemonic.mulsd: RewriteScalarBinop(m.FMul, PrimitiveType.Real64, false); break; case Mnemonic.vmulsd: RewriteScalarBinop(m.FMul, PrimitiveType.Real64, true); break; case Mnemonic.mulss: RewriteScalarBinop(m.FMul, PrimitiveType.Real32, false); break; case Mnemonic.vmulss: RewriteScalarBinop(m.FMul, PrimitiveType.Real32, true); break; case Mnemonic.neg: RewriteNeg(); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.not: RewriteNot(); break; case Mnemonic.or: RewriteLogical(BinaryOperator.Or); break; case Mnemonic.orpd: RewritePackedBinop("__orpd", PrimitiveType.Real64); break; case Mnemonic.orps: RewritePackedBinop("__orps", PrimitiveType.Real32); break; case Mnemonic.@out: RewriteOut(); break; case Mnemonic.@outs: RewriteStringInstruction(); break; case Mnemonic.@outsb: RewriteStringInstruction(); break; case Mnemonic.packssdw: RewritePackedBinop("__packssdw", PrimitiveType.Int32, new ArrayType(PrimitiveType.Int16, 0)); break; case Mnemonic.packuswb: RewritePackedBinop("__packuswb", PrimitiveType.UInt16, new ArrayType(PrimitiveType.UInt8, 0)); break; case Mnemonic.paddb: RewritePackedBinop("__paddb", PrimitiveType.Byte); break; case Mnemonic.paddd: RewritePackedBinop("__paddd", PrimitiveType.Word32); break; case Mnemonic.paddq: case Mnemonic.vpaddq: RewritePackedBinop("__paddq", PrimitiveType.Word64); break; case Mnemonic.paddsw: RewritePackedBinop("__paddsw", PrimitiveType.Word16); break; case Mnemonic.paddsb: RewritePackedBinop("__paddsb", PrimitiveType.SByte); break; case Mnemonic.paddusb: RewritePackedBinop("__paddusb", PrimitiveType.Byte); break; case Mnemonic.paddusw: RewritePackedBinop("__paddsw", PrimitiveType.Word16); break; case Mnemonic.paddw: RewritePackedBinop("__paddw", PrimitiveType.Word16); break; case Mnemonic.pand: case Mnemonic.vpand: RewritePackedLogical("__pand"); break; case Mnemonic.pandn: case Mnemonic.vpandn: RewritePackedLogical("__pandn"); break; case Mnemonic.pause: RewritePause(); break; case Mnemonic.palignr: RewritePalignr(); break; case Mnemonic.pavgb: RewritePavg("__pavgb", PrimitiveType.Byte); break; case Mnemonic.pavgw: RewritePavg("__pavgw", PrimitiveType.Byte); break; case Mnemonic.pcmpeqb: RewritePcmp("__pcmpeqb", PrimitiveType.Byte); break; case Mnemonic.pcmpeqd: RewritePcmp("__pcmpeqd", PrimitiveType.Word32); break; case Mnemonic.pcmpeqw: RewritePcmp("__pcmpeqw", PrimitiveType.Word16); break; case Mnemonic.pcmpgtb: RewritePcmp("__pcmpgtb", PrimitiveType.Byte); break; case Mnemonic.pcmpgtd: RewritePcmp("__pcmpgtd", PrimitiveType.Word32); break; case Mnemonic.pcmpgtw: RewritePcmp("__pcmpgtw", PrimitiveType.Word16); break; case Mnemonic.pextrw: case Mnemonic.vextrw: RewritePextrw(); break; case Mnemonic.pinsrw: case Mnemonic.vpinsrw: RewritePinsrw(); break; case Mnemonic.pmaddwd: RewritePackedBinop("__pmaddwd", PrimitiveType.Word16, new ArrayType(PrimitiveType.Word32, 0)); break; case Mnemonic.pmaxsw: RewritePackedBinop("__pmaxsw", PrimitiveType.Int16); break; case Mnemonic.pmaxub: RewritePackedBinop("__pmaxub", PrimitiveType.UInt8); break; case Mnemonic.pminsw: RewritePackedBinop("__pminsw", PrimitiveType.Int16); break; case Mnemonic.pminub: RewritePackedBinop("__pminub", PrimitiveType.UInt8); break; case Mnemonic.pmovmskb: RewriteMovmsk("__pmovmskb", PrimitiveType.Byte); break; case Mnemonic.pmulhuw: RewritePackedBinop("__pmulhuw", PrimitiveType.UInt16, new ArrayType(PrimitiveType.UInt16, 8)); break; case Mnemonic.pmulhw: RewritePackedBinop("__pmulhw", PrimitiveType.Int16, new ArrayType(PrimitiveType.Int16, 8)); break; case Mnemonic.pmullw: case Mnemonic.vpmullw: RewritePackedBinop("__pmullw", PrimitiveType.Int16, new ArrayType(PrimitiveType.Int16, 8)); break; case Mnemonic.pmuludq: RewritePackedBinop("__pmuludq", PrimitiveType.UInt32, new ArrayType(PrimitiveType.UInt64, 0)); break; case Mnemonic.prefetchw: RewritePrefetch("__prefetchw"); break; case Mnemonic.psadbw: RewritePackedBinop("__psadbw", PrimitiveType.Byte, PrimitiveType.Word16); break; case Mnemonic.pslld: RewritePackedBinop("__pslld", PrimitiveType.Word32); break; case Mnemonic.psllq: case Mnemonic.vpsllq: RewritePackedBinop("__psllq", PrimitiveType.Word64); break; case Mnemonic.psllw: RewritePackedBinop("__psllw", PrimitiveType.Word16); break; case Mnemonic.psrad: RewritePackedBinop("__psrad", PrimitiveType.Int32); break; case Mnemonic.psraw: RewritePackedBinop("__psraw", PrimitiveType.Int16); break; case Mnemonic.psrlq: RewritePackedBinop("__psrlq", PrimitiveType.Word64); break; case Mnemonic.pop: RewritePop(); break; case Mnemonic.popa: RewritePopa(); break; case Mnemonic.popf: RewritePopf(); break; case Mnemonic.por: RewritePackedLogical("__por"); break; case Mnemonic.prefetchnta: RewritePrefetch("__prefetchnta"); break; case Mnemonic.prefetcht0: RewritePrefetch("__prefetcht0"); break; case Mnemonic.prefetcht1: RewritePrefetch("__prefetcht1"); break; case Mnemonic.prefetcht2: RewritePrefetch("__prefetcht2"); break; case Mnemonic.pshufd: RewritePshuf("__pshufd", PrimitiveType.Word32); break; case Mnemonic.pshufw: RewritePshuf("__pshufw", PrimitiveType.Word16); break; case Mnemonic.psrld: RewritePackedShift("__psrld", PrimitiveType.Word32); break; case Mnemonic.psrlw: RewritePackedShift("__psrlw", PrimitiveType.Word16); break; case Mnemonic.psubb: RewritePackedBinop("__psubb", PrimitiveType.Byte); break; case Mnemonic.psubd: case Mnemonic.vpsubd: RewritePackedBinop("__psubd", PrimitiveType.Word32); break; case Mnemonic.psubq: RewritePackedBinop("__psubq", PrimitiveType.Word64); break; case Mnemonic.psubsb: RewritePackedBinop("__psubsb", PrimitiveType.SByte); break; case Mnemonic.psubsw: RewritePackedBinop("__psubsw", PrimitiveType.Word16); break; case Mnemonic.psubusb: RewritePackedBinop("__psubusb", PrimitiveType.UInt8); break; case Mnemonic.psubusw: RewritePackedBinop("__psubusw", PrimitiveType.UInt16); break; case Mnemonic.psubw: RewritePackedBinop("__psubw", PrimitiveType.Word16); break; case Mnemonic.punpckhbw: RewritePunpckhbw(); break; case Mnemonic.punpckhdq: RewritePunpckhdq(); break; case Mnemonic.punpckhwd: RewritePunpckhwd(); break; case Mnemonic.punpcklbw: RewritePunpcklbw(); break; case Mnemonic.punpckldq: RewritePunpckldq(); break; case Mnemonic.punpcklwd: RewritePunpcklwd(); break; case Mnemonic.push: RewritePush(); break; case Mnemonic.pusha: RewritePusha(); break; case Mnemonic.pushf: RewritePushf(); break; case Mnemonic.pxor: case Mnemonic.vpxor: RewritePxor(); break; case Mnemonic.rcl: RewriteRotation(PseudoProcedure.RolC, true, true); break; case Mnemonic.rcpps: RewritePackedUnaryop("__rcpps", PrimitiveType.Real32); break; case Mnemonic.rcr: RewriteRotation(PseudoProcedure.RorC, true, false); break; case Mnemonic.rol: RewriteRotation(PseudoProcedure.Rol, false, true); break; case Mnemonic.ror: RewriteRotation(PseudoProcedure.Ror, false, false); break; case Mnemonic.rdmsr: RewriteRdmsr(); break; case Mnemonic.rdpmc: RewriteRdpmc(); break; case Mnemonic.rdtsc: RewriteRdtsc(); break; case Mnemonic.ret: RewriteRet(); break; case Mnemonic.retf: RewriteRet(); break; case Mnemonic.rsm: RewriteRsm(); break; case Mnemonic.rsqrtps: RewritePackedUnaryop("__rsqrtps", PrimitiveType.Real32); break; case Mnemonic.sahf: m.Assign(orw.FlagGroup(X86Instruction.DefCc(instrCur.Mnemonic)), orw.AluRegister(Registers.ah)); break; case Mnemonic.sar: RewriteBinOp(Operator.Sar); break; case Mnemonic.sbb: RewriteAdcSbb(m.ISub); break; case Mnemonic.scas: RewriteStringInstruction(); break; case Mnemonic.scasb: RewriteStringInstruction(); break; case Mnemonic.seta: RewriteSet(ConditionCode.UGT); break; case Mnemonic.setc: RewriteSet(ConditionCode.ULT); break; case Mnemonic.setbe: RewriteSet(ConditionCode.ULE); break; case Mnemonic.setg: RewriteSet(ConditionCode.GT); break; case Mnemonic.setge: RewriteSet(ConditionCode.GE); break; case Mnemonic.setl: RewriteSet(ConditionCode.LT); break; case Mnemonic.setle: RewriteSet(ConditionCode.LE); break; case Mnemonic.setnc: RewriteSet(ConditionCode.UGE); break; case Mnemonic.setno: RewriteSet(ConditionCode.NO); break; case Mnemonic.setns: RewriteSet(ConditionCode.NS); break; case Mnemonic.setnz: RewriteSet(ConditionCode.NE); break; case Mnemonic.setpe: RewriteSet(ConditionCode.PE); break; case Mnemonic.setpo: RewriteSet(ConditionCode.PO); break; case Mnemonic.seto: RewriteSet(ConditionCode.OV); break; case Mnemonic.sets: RewriteSet(ConditionCode.SG); break; case Mnemonic.setz: RewriteSet(ConditionCode.EQ); break; case Mnemonic.sfence: RewriteSfence(); break; case Mnemonic.sgdt: RewriteSxdt("__sgdt"); break; case Mnemonic.sha1msg2: RewriteSha1msg2(); break; case Mnemonic.shl: RewriteBinOp(BinaryOperator.Shl); break; case Mnemonic.shld: RewriteShxd("__shld"); break; case Mnemonic.shr: RewriteBinOp(BinaryOperator.Shr); break; case Mnemonic.shrd: RewriteShxd("__shrd"); break; case Mnemonic.sidt: RewriteSxdt("__sidt"); break; case Mnemonic.shufps: case Mnemonic.vshufps: RewritePackedTernaryop("__shufps", PrimitiveType.Real32); break; case Mnemonic.sldt: RewriteSxdt("__sldt"); break; case Mnemonic.smsw: RewriteSmsw(); break; case Mnemonic.sqrtps: RewritePackedUnaryop("__sqrtps", PrimitiveType.Real32); break; case Mnemonic.sqrtsd: RewriteSqrtsd(); break; case Mnemonic.stc: RewriteSetFlag(FlagM.CF, Constant.True()); break; case Mnemonic.std: RewriteSetFlag(FlagM.DF, Constant.True()); break; case Mnemonic.sti: RewriteSti(); break; case Mnemonic.stos: RewriteStringInstruction(); break; case Mnemonic.stosb: RewriteStringInstruction(); break; case Mnemonic.str: RewriteStr(); break; case Mnemonic.sub: RewriteAddSub(BinaryOperator.ISub); break; case Mnemonic.subsd: RewriteScalarBinop(m.FSub, PrimitiveType.Real64, false); break; case Mnemonic.vsubsd: RewriteScalarBinop(m.FSub, PrimitiveType.Real64, true); break; case Mnemonic.subss: RewriteScalarBinop(m.FSub, PrimitiveType.Real32, false); break; case Mnemonic.vsubss: RewriteScalarBinop(m.FSub, PrimitiveType.Real32, true); break; case Mnemonic.subpd: RewritePackedBinop("__subpd", PrimitiveType.Real64); break; case Mnemonic.subps: RewritePackedBinop("__subps", PrimitiveType.Real32); break; case Mnemonic.syscall: RewriteSyscall(); break; case Mnemonic.sysenter: RewriteSysenter(); break; case Mnemonic.sysexit: RewriteSysexit(); break; case Mnemonic.sysret: RewriteSysret(); break; case Mnemonic.ucomiss: RewriteComis(PrimitiveType.Real32); break; case Mnemonic.ucomisd: RewriteComis(PrimitiveType.Real64); break; case Mnemonic.unpckhps: RewriteUnpckhps(); break; case Mnemonic.ud0: iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.ud1: iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.ud2: iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.unpcklpd: RewritePackedBinop("__unpcklpd", PrimitiveType.Real64); break; case Mnemonic.unpcklps: RewritePackedBinop("__unpcklps", PrimitiveType.Real32); break; case Mnemonic.verr: RewriteVerrw("__verify_readable"); break; case Mnemonic.verw: RewriteVerrw("__verify_writeable"); break; case Mnemonic.test: RewriteTest(); break; case Mnemonic.wait: RewriteWait(); break; case Mnemonic.wbinvd: RewriteWbinvd(); break; case Mnemonic.wrmsr: RewriteWrsmr(); break; case Mnemonic.xadd: RewriteXadd(); break; case Mnemonic.xchg: RewriteExchange(); break; case Mnemonic.xgetbv: RewriteXgetbv(); break; case Mnemonic.xsetbv: RewriteXsetbv(); break; case Mnemonic.xlat: RewriteXlat(); break; case Mnemonic.xor: RewriteLogical(BinaryOperator.Xor); break; case Mnemonic.xorpd: case Mnemonic.vxorpd: RewritePackedBinop("__xorpd", PrimitiveType.Word64); break; case Mnemonic.xorps: RewritePackedBinop("__xorps", PrimitiveType.Word32); break; case Mnemonic.BOR_exp: RewriteFUnary("exp"); break; case Mnemonic.BOR_ln: RewriteFUnary("log"); break; } var len = (int)(dasm.Current.Address - addr) + dasm.Current.Length; yield return(m.MakeCluster(addr, len, iclass)); } }
private void C(Expression e) { var carry = binder.EnsureFlagGroup(Registers.C); m.Assign(carry, m.Cond(e)); }
private void SetFlags(Expression e, FlagM changed, FlagM zeroed, FlagM set) { if (e == null) { Invalid(); return; } uint uChanged = (uint)changed; if (uChanged != 0) { var grfChanged = binder.EnsureFlagGroup(this.arch.GetFlagGroup(Registers.psw, uChanged)); m.Assign(grfChanged, m.Cond(e)); } uint grfMask = 1; while (grfMask <= (uint)zeroed) { if ((grfMask & (uint)zeroed) != 0) { var grfZeroed = binder.EnsureFlagGroup(this.arch.GetFlagGroup(Registers.psw, grfMask)); m.Assign(grfZeroed, 0); } grfMask <<= 1; } grfMask = 1; while (grfMask <= (uint)set) { if ((grfMask & (uint)set) != 0) { var grfZeroed = binder.EnsureFlagGroup(this.arch.GetFlagGroup(Registers.psw, grfMask)); m.Assign(grfZeroed, 1); } grfMask <<= 1; } }
private Expression SrcOp(MachineOperand op, Func <int, int> immediateFn = null) { var regOp = op as RegisterOperand; if (regOp != null) { var id = binder.EnsureRegister(regOp.Register); return(id); } var immOp = op as ImmediateOperand; if (immOp != null) { return(Constant.Word32(immediateFn(immOp.Value.ToInt32()))); } var addrOp = op as AddressOperand; if (addrOp != null) { return(addrOp.Address); } var mem = op as MemoryOperand; if (mem != null) { Identifier reg; switch (mem.mode) { default: throw new NotImplementedException(mem.mode.ToString()); case AddressingMode.Indirect: return(m.Mem(mem.Width, binder.EnsureRegister(mem.reg))); case AddressingMode.IndirectPreDecr: reg = binder.EnsureRegister(mem.reg); m.Assign(reg, m.ISubS(reg, mem.Width.Size)); return(m.Mem(mem.Width, reg)); case AddressingMode.IndirectPostIncr: var t = binder.CreateTemporary(mem.Width); reg = binder.EnsureRegister(mem.reg); m.Assign(t, m.Mem(mem.Width, reg)); m.Assign(reg, m.IAddS(reg, t.DataType.Size)); return(t); case AddressingMode.IndirectDisplacement: reg = binder.EnsureRegister(mem.reg); return(m.Mem( mem.Width, m.IAddS(reg, mem.disp))); case AddressingMode.IndexedIndirect: return(m.Mem(mem.Width, m.IAdd( binder.EnsureRegister(Registers.r0), binder.EnsureRegister(mem.reg)))); case AddressingMode.PcRelativeDisplacement: var addr = instr.Address.ToUInt32(); if (mem.Width.Size == 4) { addr &= ~3u; } addr += (uint)(mem.disp + 4); return(m.Mem(mem.Width, Address.Ptr32(addr))); } } throw new NotImplementedException(op.GetType().Name); }