private Expression RewriteMemoryOperand(MemoryOperand mem) { Expression ea; if (mem.Base != null) { ea = binder.EnsureRegister(mem.Base); if (mem.Index != null) { Expression index = binder.EnsureRegister(mem.Index); if (mem.Shift > 0) { index = m.IMul(index, 1 << mem.Shift); } ea = m.IAdd(ea, index); } if (mem.Offset != 0) { ea = m.AddSubSignedInt(ea, mem.Offset); } } else { ea = Address.Ptr32((uint)mem.Offset); if (mem.Index != null) { var idx = binder.EnsureRegister(mem.Index); ea = m.IAdd(ea, idx); } } return(m.Mem(mem.Width, ea)); }
/// <summary> /// Rewrites the effective address of a memory load. /// </summary> /// <param name="mem"></param> /// <returns></returns> private Expression RewriteSrcEa(MemoryOperand mem) { Expression ea; if (mem.Base != null) { ea = binder.EnsureRegister(mem.Base); if (mem.Increment < 0) { m.Assign(ea, m.AddSubSignedInt(ea, mem.Increment)); } if (mem.Offset != null) { ea = m.IAdd(ea, mem.Offset); } if (mem.Increment > 0) { var tmp = binder.CreateTemporary(ea.DataType); m.Assign(tmp, ea); m.Assign(ea, m.AddSubSignedInt(ea, mem.Increment)); ea = tmp; } } else { ea = arch.MakeAddressFromConstant(mem.Offset !, false); } return(ea); }
private Expression Rewrite(MachineOperand op) { switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case ImmediateOperand imm: return(imm.Value); case AddressOperand addr: return(addr.Address); case IndirectOperand mem: Expression ea; if (mem.Base == arch.pc) { ea = dasm.Current.Address + mem.Offset; } else { ea = binder.EnsureRegister(mem.Base); ea = m.AddSubSignedInt(ea, mem.Offset); } return(m.Mem(op.Width, ea)); } throw new NotImplementedException($"Mips16e operand {op.GetType()} not implemented yet."); }
private Expression EffectiveAddress(MemoryOperand mem) { Expression ea; if (mem.Base != null) { ea = binder.EnsureRegister(mem.Base); if (mem.Index != null) { throw new NotImplementedException(); } if (mem.Offset != 0) { ea = m.AddSubSignedInt(ea, mem.Offset); } if (mem.PostDecrement || mem.PostIncrement) { var tmp = binder.CreateTemporary(ea.DataType); m.Assign(tmp, ea); var size = mem.Width.Size; m.Assign(ea, m.AddSubSignedInt(ea, mem.PostIncrement ? size : -size)); ea = tmp; } } else { throw new NotImplementedException(); } return(ea); }
private void RewriteLoadOffset(PrimitiveType dt) { var dst = Reg(0); var baseReg = Reg0(1); var offset = Imm(2); if (baseReg.IsZero) { EmitLoad(dst, m.Mem(dt, Address.Ptr32(offset.ToUInt32()))); } else { EmitLoad(dst, m.Mem(dt, m.AddSubSignedInt(baseReg, offset.ToInt32()))); } }
private void RewriteStm() { var regs = instr.Operands .Skip(1) .Cast <RegisterRange>() .SelectMany(rr => rr.Enumerate()); Identifier sp; bool preDec = false; if (instr.Operands[0] is MemoryOperand pre) { Debug.Assert(pre.PreDecrement); sp = binder.EnsureRegister(pre.Base); preDec = true; } else { sp = binder.EnsureRegister(((RegisterOperand)instr.Operands[0]).Register); } int offset = 0; foreach (var reg in regs) { offset -= reg.DataType.Size; m.Assign(m.Mem(reg.DataType, m.IAddS(sp, offset)), binder.EnsureRegister(reg)); } if (preDec) { m.Assign(sp, m.AddSubSignedInt(sp, offset)); } }
private Expression Rewrite(MachineOperand op) { switch (op) { case RegisterOperand rop: if (rop.Register.Number == 0) { return(Constant.Create(rop.Register.DataType, 0)); } else { return(binder.EnsureRegister(rop.Register)); } case ImmediateOperand imm: return(imm.Value); case MemoryOperand mem: Expression ea; if (mem.Base.Number == 0) { ea = Address.Ptr32((uint)mem.Offset); } else { ea = binder.EnsureRegister(mem.Base); ea = m.AddSubSignedInt(ea, mem.Offset); } return(m.Mem(mem.Width, ea)); case AddressOperand aop: return(aop.Address); } throw new NotImplementedException($"{op.GetType().Name} not implemented."); }
private MemoryAccess Mem(MachineOperand op) { var mop = (MemoryOperand)op; Expression ea = binder.EnsureRegister(mop.Base); ea = m.AddSubSignedInt(ea, mop.Offset); return(m.Mem(op.Width, ea)); }
private void RewriteCmpIncDec(int increment) { var left = Src(0); var right = Src(1); EmitCond(EZVCN, m.ISub(left, right)); m.Assign(left, m.AddSubSignedInt(left, increment)); }
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 Expression EffectiveAddress(MemoryOperand mem) { Expression ea; if (mem.Base != null) { ea = binder.EnsureRegister(mem.Base); if (mem.Offset != 0) { ea = m.AddSubSignedInt(ea, mem.Offset); } } else { ea = Address.Ptr32((uint)mem.Offset); } return(ea); }
private void RewriteOp( Storage rDst, Func <Func <Expression, Expression, Expression>, Expression, Expression, MemoryOperand, Expression> memFn, Func <Expression, Expression, Expression> bin, Action <Expression> genFlags) { Expression dst = rDst != null?binder.EnsureIdentifier(rDst) : null; Expression tmp; switch (instr.Operands[0]) { case RegisterOperand reg: tmp = binder.EnsureRegister(reg.Register); m.Assign(tmp, bin(dst, tmp)); break; case ImmediateOperand imm: m.Assign(dst, bin(dst, imm.Value)); tmp = dst; break; case MemoryOperand mem: Expression ea; Expression idx; switch (mem.AccessMode) { case MemoryOperand.Mode.AccumulatorOffset: ea = binder.EnsureRegister(mem.Base); idx = binder.EnsureRegister(mem.Index); if (idx.DataType.BitSize < ea.DataType.BitSize) { idx = m.Convert(idx, idx.DataType, PrimitiveType.Int16); } ea = m.IAdd(ea, idx); tmp = memFn(bin, dst, ea, mem); break; case MemoryOperand.Mode.ConstantOffset: if (mem.Base == null) { ea = Address.Ptr16((ushort)mem.Offset); } else if (mem.Base == Registers.PCR) { ea = instr.Address + (instr.Length + mem.Offset); } else { ea = binder.EnsureRegister(mem.Base); ea = m.AddSubSignedInt(ea, mem.Offset); } tmp = memFn(bin, dst, ea, mem); break; case MemoryOperand.Mode.Direct: ea = m.IAdd(binder.EnsureRegister(Registers.DP), Constant.Word16((byte)mem.Offset)); tmp = memFn(bin, dst, ea, mem); break; case MemoryOperand.Mode.PostInc1: ea = binder.EnsureRegister(mem.Base); tmp = memFn(bin, dst, ea, mem); m.Assign(ea, m.IAddS(ea, 1)); break; case MemoryOperand.Mode.PostInc2: ea = binder.EnsureRegister(mem.Base); tmp = memFn(bin, dst, ea, mem); m.Assign(ea, m.IAddS(ea, 2)); break; case MemoryOperand.Mode.PreDec1: ea = binder.EnsureRegister(mem.Base); m.Assign(ea, m.ISubS(ea, 1)); tmp = memFn(bin, dst, ea, mem); break; case MemoryOperand.Mode.PreDec2: ea = binder.EnsureRegister(mem.Base); m.Assign(ea, m.ISubS(ea, 2)); tmp = memFn(bin, dst, ea, mem); break; default: throw new NotImplementedException($"Unimplemented access mode {mem.AccessMode.ToString()}"); } break; default: throw new NotImplementedException($"Unimplemented operand type {instr.Operands[0].GetType().Name}"); } genFlags(tmp); }
private void PreDec(int iOp) { var reg = RewriteOp(instr.Operands[iOp]); m.Assign(reg, m.AddSubSignedInt(reg, -4)); }