private void RewriteRot(string intrinsic) { rtlc = RtlClass.Linear; var op1 = SrcOp(instr.op1); m.Assign(op1, host.PseudoProcedure(intrinsic, op1.DataType, op1, m.Int32(1))); }
private void RewriteRol() { var src = RewriteOp(0); var c = binder.EnsureFlagGroup(C); var dst = RewriteOpDst(0, m.Fn(CommonOps.RolC, src, m.Int32(1), c)); EmitCc(NZC, dst); }
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); }
private void RewriteShift1(Func <Expression, Expression, Expression> fn) { var dst = Reg(0); var src = Reg(1); m.Assign(dst, fn(src, m.Int32(1))); C(dst); }
private void RewriteRor() { var c = binder.EnsureFlagGroup(arch.C); var reg = RewriteOp(0); m.Assign(reg, m.Fn(CommonOps.RorC, reg, m.Int32(1), c)); EmitFlags(reg, CmpFlags); }
private void RewritePopm() { int c = ((ImmediateOperand)instr.Operands[0]).Value.ToInt32(); int iReg = ((RegisterOperand)instr.Operands[1]).Register.Number - c + 1; if (iReg < 0) { Invalid(); return; } var sp = binder.EnsureRegister(Registers.sp); while (c > 0) { m.Assign(binder.EnsureRegister(Registers.GpRegisters[iReg]), m.Mem16(sp)); m.Assign(sp, m.IAdd(sp, m.Int32(2))); ++iReg; --c; } }
private void RewriteRot(string intrinsic) { var op1 = SrcOp(instr.Operands[0]); m.Assign(op1, host.PseudoProcedure(intrinsic, op1.DataType, op1, m.Int32(1))); }
private void RewriteRor() { var c = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.sreg, (uint)FlagM.CF)); var reg = RewriteOp(0); m.Assign(reg, host.PseudoProcedure(PseudoProcedure.RorC, PrimitiveType.Byte, reg, m.Int32(1), c)); EmitFlags(reg, CmpFlags); }
private void RewriteRol() { var src = RewriteOp(0); var c = binder.EnsureFlagGroup(C); var dst = RewriteOpDst(0, host.PseudoProcedure(PseudoProcedure.RolC, PrimitiveType.Word32, src, m.Int32(1), c)); EmitCc(NZC, dst); }
public Expression RewriteUnary( MachineOperand operand, Address addrInstr, PrimitiveType dataWidth, Func <Expression, Expression> opGen) { switch (operand) { case RegisterOperand reg: { Expression r = binder.EnsureRegister(reg.Register); if (r.DataType.BitSize > dataWidth.BitSize) { var tmpLo = binder.CreateTemporary(dataWidth); var tmpHi = binder.CreateTemporary(PrimitiveType.CreateWord(r.DataType.BitSize - dataWidth.BitSize)); m.Assign(tmpLo, opGen(m.Convert(r, r.DataType, dataWidth))); m.Assign(tmpHi, m.Slice(tmpHi.DataType, r, dataWidth.BitSize)); m.Assign(r, m.Seq(tmpHi, tmpLo)); return(tmpLo); } else { m.Assign(r, opGen(r)); return(r); } } case M68kAddressOperand addr: { var access = m.Mem(dataWidth, addr.Address); return(EmitStore(access, opGen(access))); } case MemoryOperand mem: { var access = RewriteMemoryAccess(mem, dataWidth, addrInstr); return(EmitStore(access, opGen(access))); } case PostIncrementMemoryOperand post: { var r = binder.EnsureRegister(post.Register); var access = m.Mem(dataWidth, r); var tmp = EmitStore(access, opGen(access)); m.Assign(r, m.IAddS(r, dataWidth.Size)); return(tmp); } case PredecrementMemoryOperand pre: { var r = binder.EnsureRegister(pre.Register); m.Assign(r, m.ISubS(r, dataWidth.Size)); var access = m.Mem(dataWidth, r); return(EmitStore(access, opGen(access))); } case IndirectIndexedOperand indidx: { Expression ea = binder.EnsureRegister(indidx.ARegister); if (indidx.Imm8 != 0) { ea = m.IAddS(ea, indidx.Imm8); } Expression ix = binder.EnsureRegister(indidx.XRegister); if (indidx.Scale > 1) { ix = m.IMul(ix, Constant.Int32(indidx.Scale)); } var access = m.Mem(dataWidth, m.IAdd(ea, ix)); return(EmitStore(access, opGen(access))); } case IndexedOperand indop: { Expression ea = Combine(indop.BaseDisplacement, indop.Base, addrInstr); if (indop.postindex) { ea = m.Mem32(ea); } if (indop.Index != null) { var idx = Combine(null, indop.Index, addrInstr); if (indop.index_reg_width !.BitSize != 32) { idx = m.Slice(PrimitiveType.Int16, idx, 0); idx = m.Convert(idx, PrimitiveType.Int16, PrimitiveType.Int32); } if (indop.IndexScale > 1) { idx = m.IMul(idx, m.Int32(indop.IndexScale)); } ea = Combine(ea, idx); } if (indop.preindex) { ea = m.Mem32(ea); } ea = Combine(ea, indop.OuterDisplacement); var access = m.Mem(DataWidth, ea); return(EmitStore(access, opGen(access))); } } throw new AddressCorrelatedException( addrInstr, "Unimplemented RewriteUnary for operand {0} of type {1}.", operand.ToString(), operand.GetType().Name); }
private void RewriteRor() { var c = binder.EnsureFlagGroup(arch.C); var reg = RewriteOp(0); m.Assign(reg, host.Intrinsic(IntrinsicProcedure.RorC, true, PrimitiveType.Byte, reg, m.Int32(1), c)); EmitFlags(reg, CmpFlags); }
} // the data width of the current instruction being rewritten. /// <summary> /// Rewrite operands being used as sources. /// </summary> /// <param name="operand"></param> /// <param name="addrInstr">Address of the current instruction</param> /// <returns></returns> public Expression RewriteSrc(MachineOperand operand, Address addrInstr, bool addressAsAddress = false) { var reg = operand as RegisterOperand; if (reg != null) { Expression r = binder.EnsureRegister(reg.Register); if (DataWidth != null && DataWidth.Size != reg.Width.Size) { r = m.Cast(DataWidth, r); } return(r); } var imm = operand as M68kImmediateOperand; if (imm != null) { if (imm.Width.Domain == Domain.Real) { return(imm.Constant.CloneExpression()); } if (DataWidth != null && DataWidth.BitSize > imm.Width.BitSize) { return(Constant.Create(DataWidth, imm.Constant.ToInt64())); } else { return(Constant.Create(imm.Width, imm.Constant.ToUInt32())); } } var mem = operand as MemoryOperand; if (mem != null) { return(RewriteMemoryAccess(mem, DataWidth, addrInstr)); } var addr = operand as M68kAddressOperand; if (addr != null) { if (addressAsAddress) { return(addr.Address); } else { return(m.Mem(DataWidth, addr.Address)); } } var pre = operand as PredecrementMemoryOperand; if (pre != null) { var ea = binder.EnsureRegister(pre.Register); m.Assign(ea, m.ISub(ea, m.Int32(DataWidth.Size))); return(m.Mem(DataWidth, ea)); } var post = operand as PostIncrementMemoryOperand; if (post != null) { var r = binder.EnsureRegister(post.Register); var tmp = binder.CreateTemporary(DataWidth); m.Assign(tmp, m.Mem(DataWidth, r)); m.Assign(r, m.IAdd(r, m.Int32(DataWidth.Size))); return(tmp); } var indidx = operand as IndirectIndexedOperand; if (indidx != null) { Expression ea = RewriteIndirectBaseRegister(indidx, addrInstr); Expression ix = binder.EnsureRegister(indidx.XRegister); if (indidx.XWidth.Size != 4) { ix = m.Cast(PrimitiveType.Int32, m.Cast(PrimitiveType.Int16, ix)); } if (indidx.Scale > 1) { ix = m.IMul(ix, Constant.Int32(indidx.Scale)); } return(m.Mem(DataWidth, m.IAdd(ea, ix))); } var indop = operand as IndexedOperand; if (indop != null) { Expression ea = Combine(indop.Base, indop.base_reg); if (indop.postindex) { ea = m.Mem32(ea); } if (indop.index_reg != null) { var idx = Combine(null, indop.index_reg); if (indop.index_reg_width.BitSize != 32) { idx = m.Cast(PrimitiveType.Word32, m.Cast(PrimitiveType.Int16, idx)); } if (indop.index_scale > 1) { idx = m.IMul(idx, indop.index_scale); } ea = Combine(ea, idx); } if (indop.preindex) { ea = m.Mem32(ea); } ea = Combine(ea, indop.outer); return(m.Mem(DataWidth, ea)); } throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name); }
public Expression RewriteUnary( MachineOperand operand, Address addrInstr, PrimitiveType dataWidth, Func <Expression, Expression> opGen) { var reg = operand as RegisterOperand; if (reg != null) { Expression r = binder.EnsureRegister(reg.Register); if (r.DataType.Size > dataWidth.Size) { var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(m.Cast(dataWidth, r))); m.Assign(r, m.Dpb(r, tmp, 0)); return(tmp); } else { m.Assign(r, opGen(r)); return(r); } } var addr = operand as M68kAddressOperand; if (addr != null) { var load = m.Mem(dataWidth, addr.Address); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(load)); m.Assign(load, tmp); return(tmp); } var mem = operand as MemoryOperand; if (mem != null) { var load = RewriteMemoryAccess(mem, dataWidth, addrInstr); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(load)); m.Assign(RewriteMemoryAccess(mem, dataWidth, addrInstr), tmp); return(tmp); } var post = operand as PostIncrementMemoryOperand; if (post != null) { var r = binder.EnsureRegister(post.Register); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(m.Mem(dataWidth, r))); m.Assign(m.Mem(dataWidth, r), tmp); m.Assign(r, m.IAddS(r, dataWidth.Size)); return(tmp); } var pre = operand as PredecrementMemoryOperand; if (pre != null) { var r = binder.EnsureRegister(pre.Register); m.Assign(r, m.ISubS(r, dataWidth.Size)); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(m.Mem(dataWidth, r))); m.Assign(m.Mem(dataWidth, r), tmp); return(tmp); } var indidx = operand as IndirectIndexedOperand; if (indidx != null) { Expression ea = binder.EnsureRegister(indidx.ARegister); if (indidx.Imm8 != 0) { ea = m.IAddS(ea, indidx.Imm8); } Expression ix = binder.EnsureRegister(indidx.XRegister); if (indidx.Scale > 1) { ix = m.IMul(ix, Constant.Int32(indidx.Scale)); } var load = m.Mem(dataWidth, m.IAdd(ea, ix)); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(load)); m.Assign(load, tmp); return(tmp); } var indop = operand as IndexedOperand; if (indop != null) { Expression ea = Combine(indop.Base, indop.base_reg); if (indop.postindex) { ea = m.Mem32(ea); } if (indop.index_reg != null) { var idx = Combine(null, indop.index_reg); if (indop.index_reg_width.BitSize != 32) { idx = m.Cast(PrimitiveType.Word32, m.Cast(PrimitiveType.Int16, idx)); } if (indop.index_scale > 1) { idx = m.IMul(idx, m.Int32(indop.index_scale)); } ea = Combine(ea, idx); } if (indop.preindex) { ea = m.Mem32(ea); } ea = Combine(ea, indop.outer); var load = m.Mem(DataWidth, ea); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(load)); m.Assign(load, tmp); return(tmp); } throw new AddressCorrelatedException( addrInstr, "Unimplemented RewriteUnary for operand {0} of type {1}.", operand.ToString(), operand.GetType().Name); }
private void RewriteRot(IntrinsicProcedure intrinsic) { var op1 = SrcOp(instr.Operands[0]); m.Assign(op1, m.Fn(intrinsic, op1, m.Int32(1))); }