public Expression RewriteMoveDst(MachineOperand opDst, Address addrInstr, PrimitiveType dataWidth, Expression src) { var reg = opDst as RegisterOperand; if (reg != null) { var r = frame.EnsureRegister(reg.Register); if (r.DataType.Size > dataWidth.Size) { var tmp = frame.CreateTemporary(dataWidth); m.Assign(r, m.Dpb(r, src, 0, dataWidth.BitSize)); return tmp; } else { m.Assign(r, src); return r; } } var mem = opDst as MemoryOperand; if (mem != null) { src = Spill(src, frame.EnsureRegister(mem.Base)); var load = RewriteMemoryAccess(mem, dataWidth,addrInstr); var tmp = frame.CreateTemporary(dataWidth); m.Assign(load, src); return tmp; } var post = opDst as PostIncrementMemoryOperand; if (post != null) { var r = frame.EnsureRegister(post.Register); var rExp = Spill(src, r); var load = m.Load(dataWidth, r); m.Assign(load, rExp); m.Assign(r, m.IAdd(r, dataWidth.Size)); return src; } var pre = opDst as PredecrementMemoryOperand; if (pre != null) { var r = frame.EnsureRegister(pre.Register); m.Assign(r, m.ISub(r, dataWidth.Size)); var rExp = Spill(src, r); var load = m.Load(dataWidth, rExp); m.Assign(load, src); return src; } var indidx = opDst as IndirectIndexedOperand; if (indidx != null) { var a = frame.EnsureRegister(indidx.ARegister); var x = frame.EnsureRegister(indidx.XRegister); var load = m.Load(dataWidth, m.IAdd(a, x)); m.Assign(load, src); return src; } var mAddr = opDst as M68kAddressOperand; if (mAddr != null) { m.Assign( m.Load( dataWidth, Constant.Word32(mAddr.Address.ToUInt32())), src); return src; } throw new NotImplementedException("Unimplemented RewriteMoveDst for operand type " + opDst.GetType().Name); }
public PrimitiveType DataWidth { get; set; } // 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 = frame.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 (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.Load(DataWidth, addr.Address); } var pre = operand as PredecrementMemoryOperand; if (pre != null) { var ea = frame.EnsureRegister(pre.Register); m.Assign(ea, m.ISub(ea, DataWidth.Size)); return m.Load(DataWidth, ea); } var post = operand as PostIncrementMemoryOperand; if (post != null) { var r = frame.EnsureRegister(post.Register); var tmp = frame.CreateTemporary(DataWidth); m.Assign(tmp, m.Load(DataWidth, r)); m.Assign(r, m.IAdd(r, DataWidth.Size)); return tmp; } var indidx = operand as IndirectIndexedOperand; if (indidx != null) { Expression ea = frame.EnsureRegister(indidx.ARegister); if (indidx.Imm8 != 0) ea = m.IAdd(ea, Constant.Int32(indidx.Imm8)); Expression ix = frame.EnsureRegister(indidx.XRegister); if (indidx.Scale > 1) ix = m.IMul(ix, Constant.Int32(indidx.Scale)); return m.Load(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.LoadDw(ea); } if (indop.index_reg != null) { var idx = Combine(null, indop.index_reg); if (indop.index_scale > 1) idx = m.IMul(idx, indop.index_scale); ea = Combine(ea, idx); } if (indop.preindex) { ea = m.LoadDw(ea); } ea = Combine(ea, indop.outer); return m.Load(DataWidth, ea); } throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name); }
public Expression GetEffectiveAddress(MachineOperand op) { var mem = op as MemoryOperand; if (mem != null) { if (mem.Base == null) { return mem.Offset; } else if (mem.Base == Registers.pc) { return di.Address + mem.Offset.ToInt32(); } else if (mem.Offset == null) { return frame.EnsureRegister(mem.Base); } else { return emitter.IAdd( frame.EnsureRegister(mem.Base), Constant.Int32(mem.Offset.ToInt32())); } } var addrOp = di.op1 as AddressOperand; if (addrOp != null) { return addrOp.Address; } var indIdx = di.op1 as IndirectIndexedOperand; if (indIdx != null) { var a = frame.EnsureRegister(indIdx.ARegister); var x = frame.EnsureRegister(indIdx.XRegister); return emitter.IAdd(a, x); //$REVIEW: woefully incomplete... } throw new NotImplementedException(string.Format("{0} ({1})", op, op.GetType().Name)); }