private Expression RewriteOp(MachineOperand op, PrimitiveType?dt = null) { dt ??= op.Width ?? instr.dataWidth !; switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case MemoryOperand mop: Expression ea; if (mop.Base != null) { ea = binder.EnsureRegister(mop.Base); if (mop.PostIncrement) { var tmp = binder.CreateTemporary(dt); m.Assign(tmp, m.Mem(op.Width !, ea)); m.Assign(ea, m.IAdd(ea, m.Int16((short)dt.Size))); return(tmp); } else if (mop.Base == Registers.pc) { ea = instr.Address + mop.Offset; var tmp = binder.CreateTemporary(dt); m.Assign(tmp, m.Mem(dt, ea)); return(tmp); } else if (mop.Offset != 0) { var tmp = binder.CreateTemporary(dt); m.Assign(tmp, m.Mem(dt, m.IAdd(ea, m.Int16(mop.Offset)))); return(tmp); } else { var tmp = binder.CreateTemporary(dt); m.Assign(tmp, m.Mem(dt, ea)); return(tmp); } } else { var tmp = binder.CreateTemporary(dt); ea = Address.Ptr16((ushort)mop.Offset); m.Assign(tmp, m.Mem(dt, ea)); return(tmp); } case ImmediateOperand iop: return(iop.Value); case AddressOperand aop: return(aop.Address); } throw new NotImplementedException(op.ToString()); }
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; if (mem.Base != null) { ea = binder.EnsureRegister(mem.Base); if (mem.Index != null) { var idx = binder.EnsureRegister(mem.Index); ea = m.IAdd( ea, m.Cast(PrimitiveType.Int16, idx)); } else if (mem.Offset != null) { ea = m.IAdd( ea, m.Int16((sbyte)mem.Offset.ToByte())); } } else { ea = arch.MakeAddressFromConstant(mem.Offset); } var tmp = binder.CreateTemporary(mem.Width); m.Assign(tmp, m.Mem(mem.Width, ea)); return(tmp); } throw new NotImplementedException(op.GetType().Name); }
private void RewriteMem(int iOp, Expression src, Action <Expression, Expression> write, Expression seg) { var op = instr.operands[iOp]; var mop = (MemoryOperand)op; var baseReg = binder.EnsureRegister(mop.Base); Expression ea = baseReg; if (mop.PreDecrement) { m.Assign(baseReg, m.ISub(baseReg, Constant.Int16(1))); } else if (mop.Displacement != 0) { ea = m.IAdd(ea, m.Int16(mop.Displacement)); } Expression val; if (seg != null) { val = m.SegMem(mop.Width, seg, ea); } else { val = m.Mem(mop.Width, ea); } write(val, src); if (mop.PostIncrement) { m.Assign(baseReg, m.IAdd(baseReg, Constant.Int16(1))); } }
private void RewriteCp(Func <Expression, Expression, Expression> incDec, bool repeat) { var addr = dasm.Current.Address; var a = frame.EnsureRegister(Registers.a); var bc = frame.EnsureRegister(Registers.bc); var hl = frame.EnsureRegister(Registers.hl); var z = FlagGroup(FlagM.ZF); emitter.Assign(z, emitter.Cond(emitter.ISub(a, emitter.LoadB(hl)))); emitter.Assign(hl, incDec(hl, emitter.Int16(1))); emitter.Assign(bc, emitter.ISub(bc, 1)); if (repeat) { emitter.BranchInMiddleOfInstruction(emitter.Eq0(bc), addr + dasm.Current.Length, RtlClass.ConditionalTransfer); emitter.Branch(emitter.Test(ConditionCode.NE, z), addr, RtlClass.ConditionalTransfer); } }
private void RewriteCp(Func <Expression, Expression, Expression> incDec, bool repeat) { var addr = dasm.Current.Address; var a = binder.EnsureRegister(Registers.a); var bc = binder.EnsureRegister(Registers.bc); var hl = binder.EnsureRegister(Registers.hl); var z = FlagGroup(FlagM.ZF); m.Assign(z, m.Cond(m.ISub(a, m.Mem8(hl)))); m.Assign(hl, incDec(hl, m.Int16(1))); m.Assign(bc, m.ISubS(bc, 1)); if (repeat) { m.BranchInMiddleOfInstruction(m.Eq0(bc), addr + dasm.Current.Length, InstrClass.ConditionalTransfer); m.Branch(m.Test(ConditionCode.NE, z), addr, InstrClass.ConditionalTransfer); } }
private Expression RewriteSrc(MachineOperand op) { switch (op) { case RegisterOperand reg: return(binder.EnsureRegister(reg.Register)); case AddressOperand addr: return(addr.Address); case ImmediateOperand imm: return(imm.Value); case MemoryOperand mem: Expression ea; if (mem.Base != null) { ea = binder.EnsureRegister(mem.Base); if (mem.Index != null) { var idx = binder.EnsureRegister(mem.Index); ea = m.IAdd( ea, m.Convert(idx, idx.DataType, PrimitiveType.Int16)); } else if (mem.Offset != null) { ea = m.IAdd( ea, m.Int16((sbyte)mem.Offset.ToByte())); } } else { ea = arch.MakeAddressFromConstant(mem.Offset, false); } 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(MachineOperand op) { switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case MemoryOperand mop: Expression ea = binder.EnsureRegister(mop.Base); if (mop.PostIncrement) { var tmp = binder.CreateTemporary(op.Width); m.Assign(tmp, m.Mem(op.Width, ea)); m.Assign(ea, m.IAdd(ea, m.Int16((short)op.Width.Size))); return(tmp); } else if (mop.Offset != 0) { var tmp = binder.CreateTemporary(op.Width); m.Assign(tmp, m.Mem(op.Width, m.IAdd(ea, m.Int16(mop.Offset)))); return(tmp); } else { var tmp = binder.CreateTemporary(op.Width); m.Assign(tmp, m.Mem(op.Width, ea)); return(tmp); } case ImmediateOperand iop: return(iop.Value); case AddressOperand aop: return(aop.Address); } throw new NotImplementedException(op.ToString()); }