private Expression Mem(MemoryOperand mem) { Expression ea; if (mem.Base != null) { var baseReg = binder.EnsureRegister(mem.Base); ea = baseReg; if (mem.Predecrement) { m.Assign(baseReg, m.ISubS(baseReg, mem.Width.Size)); } if (mem.Offset != 0) { ea = m.IAdd(ea, mem.Offset); } if (mem.Postincrement) { m.Assign(baseReg, m.IAddS(baseReg, mem.Width.Size)); } } else { ea = Address.Ptr16((ushort)mem.Offset); } return(m.Mem(mem.Width, ea)); }
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.ISubS(baseReg, 1)); } else if (mop.Displacement != 0) { ea = m.IAddS(ea, 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.IAddS(baseReg, 1)); } }
private Expression SrcOp(MachineOperand op, Func <int, int>?immediateFn = null) { switch (op) { case RegisterOperand regOp: var id = binder.EnsureRegister(regOp.Register); return(id); case ImmediateOperand immOp: return(Constant.Word32(immediateFn !(immOp.Value.ToInt32()))); case AddressOperand addrOp: return(addrOp.Address); case MemoryOperand mem: 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); }
private void RewriteAllocFrame(MachineOperand opImm) { var ea = binder.CreateTemporary(PrimitiveType.Ptr32); m.Assign(ea, m.ISubS(binder.EnsureRegister(Registers.sp), 8)); m.Assign(m.Mem32(ea), binder.EnsureRegister(Registers.fp)); m.Assign(m.Mem32(m.IAddS(ea, 4)), binder.EnsureRegister(Registers.lr)); m.Assign(binder.EnsureRegister(Registers.fp), ea); m.Assign(binder.EnsureRegister(Registers.sp), m.ISubS(ea, ((ImmediateOperand)opImm).Value.ToInt32())); }
private void Pull(RegisterStorage reg) { var id = binder.EnsureRegister(reg); var s = binder.EnsureRegister(arch.StackRegister); var c = FlagGroupStorage(FlagM.NF | FlagM.ZF); m.Assign(id, m.Mem8(s)); m.Assign(s, m.IAddS(s, 1)); m.Assign(c, m.Cond(id)); }
private MemoryAccess RewriteMemoryOperand(MemoryOperand memop) { if (memop.Base != null) { Expression baseReg; if (memop.Base == Registers.pc) { baseReg = instr.Address + instr.Length; } else { baseReg = binder.EnsureRegister(memop.Base); } Expression ea = baseReg; if (memop.Index != null) { Expression idx = binder.EnsureRegister(memop.Index); if (idx.DataType.BitSize < ea.DataType.BitSize) { idx = m.Cast(PrimitiveType.UInt16, idx); } ea = m.IAdd(baseReg, idx); } else if (memop.PreIncrement) { m.Assign(ea, m.IAddS(ea, memop.Offset.Value)); } else if (memop.PostIncrement) { var tmp = binder.CreateTemporary(baseReg.DataType); m.Assign(tmp, ea); m.Assign(baseReg, m.IAddS(baseReg, memop.Offset.Value)); ea = tmp; } else { ea = m.IAdd(baseReg, (ushort)memop.Offset.Value); } if (memop.Indirect) { ea = m.Mem(PrimitiveType.Ptr16, ea); } return(m.Mem(memop.Width, ea)); } else { Debug.Assert(memop.Offset != null); return(m.Mem(memop.Width, Address.Ptr16((ushort)memop.Offset.Value))); } }
private Expression RewriteMemoryOperand(MemoryOperand mem) { var baseReg = binder.EnsureRegister(mem.Base); if (mem.PostIncrement) { var tmp = binder.CreateTemporary(mem.Width); m.Assign(tmp, m.Mem(mem.Width, baseReg)); m.Assign(baseReg, m.IAddS(baseReg, mem.Width.Size)); return(tmp); } if (mem.PreDecrement) { m.Assign(baseReg, m.ISubS(baseReg, mem.Width.Size)); var tmp = binder.CreateTemporary(mem.Width); m.Assign(tmp, m.Mem(mem.Width, baseReg)); return(tmp); } Expression ea = baseReg; if (mem.Index != null) { Expression idx = binder.EnsureRegister(mem.Index); if (mem.Shift > 0) { idx = m.IMul(idx, m.Word32(1 << mem.Shift)); } ea = m.IAdd(ea, idx); } if (mem.Offset != 0) { ea = m.IAddS(ea, mem.Offset); } return(m.Mem(mem.Width, ea)); }
private Expression RewriteSrc(MachineOperand op) { switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case ImmediateOperand iop: return(iop.Value); case AddressOperand aop: return(aop.Address); case MemoryOperand mop: Expression ea; if (mop.Base != null) { ea = binder.EnsureRegister(mop.Base); if (mop.Offset != 0) { ea = m.IAddS(ea, mop.Offset); } } else { ea = m.Ptr32((uint)mop.Offset); } if (mop.Index != null) { var idx = binder.EnsureRegister(mop.Index); ea = m.IAdd(ea, idx); } return(m.Mem(op.Width, ea)); case BitOperand bit: var bitSrc = RewriteSrc(bit.Operand); return(host.Intrinsic( "__bit", false, PrimitiveType.Bool, bitSrc, Constant.Byte((byte)bit.BitPosition))); case FlagGroupOperand fop: return(binder.EnsureFlagGroup(fop.FlagGroup)); default: throw new NotImplementedException($"Rl87Rewriter: operand type {op.GetType().Name} not implemented yet."); } }
private void Pull(RegisterStorage stackptr, RegisterStorage reg) { var sp = binder.EnsureRegister(stackptr); var r = binder.EnsureRegister(reg); if (reg == Registers.PCR) { m.Return(2, 0); } else { m.Assign(r, m.Mem(r.DataType, sp)); m.Assign(sp, m.IAddS(sp, r.DataType.Size)); } }
private Expression EffectiveAddress(MachineOperand operand, RtlEmitter emitter) { var mop = (MemoryOperand)operand; var reg = binder.EnsureRegister(mop.BaseRegister); var offset = mop.Offset; return(emitter.IAddS(reg, offset)); }
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 Expression OpDst(MachineOperand op, Expression src, Func <Expression, Expression, Expression> fn) { Expression dst; switch (op) { case RegisterOperand reg: dst = binder.EnsureRegister(reg.Register); m.Assign(dst, fn(dst, src)); return(dst); case MemoryOperand mem: Expression ea; if (mem.Base != null) { var regBase = binder.EnsureRegister(mem.Base); if (mem.PreDecrement) { ea = binder.EnsureRegister(mem.Base !); m.Assign(ea, m.ISubS(ea, mem.Width.Size)); } else if (mem.PostIncrement) { throw new NotImplementedException(); } else { ea = m.AddSubSignedInt(regBase, mem.Offset); } } else { ea = Address.Ptr16((ushort)mem.Offset); } dst = fn(m.Mem(mem.Width, ea), src); if (dst is Identifier || dst is Constant) { m.Assign(m.Mem(mem.Width, ea), dst); } else { var tmp = binder.CreateTemporary(mem.Width); m.Assign(tmp, dst); dst = tmp; } if (mem.PostIncrement) { m.Assign(ea, m.IAddS(ea, mem.Width.Size)); } return(dst); } throw new NotImplementedException(); }
private Expression EffectiveAddress_r0(MachineOperand operand, RtlEmitter emitter) { var mop = (MemoryOperand)operand; if (mop.BaseRegister.Number == 0) { return(Constant.Word32(mop.Offset)); } else { var reg = binder.EnsureRegister(mop.BaseRegister); var offset = mop.Offset; if (offset != 0) { return(emitter.IAddS(reg, offset)); } else { return(reg); } } }
private Expression Inc(Expression e) { return(m.IAddS(e, 1)); }
} // 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.ISubS(ea, 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.IAddS(r, 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); }
} // 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> public Expression RewriteSrc(MachineOperand operand, Address addrInstr, bool addressAsAddress = false) { Expression ea; Expression r; switch (operand) { case RegisterOperand reg: r = binder.EnsureRegister(reg.Register); if (DataWidth != null && DataWidth.Size != reg.Width.Size) { if (DataWidth.Domain == Domain.Real) { r = m.Convert(r, r.DataType, DataWidth); } else { r = m.Slice(DataWidth, r, 0); } } return(r); case M68kImmediateOperand imm: if (imm.Width.IsReal) { 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())); } case MemoryOperand mem: return(RewriteMemoryAccess(mem, DataWidth, addrInstr)); case M68kAddressOperand addr: if (addressAsAddress) { return(addr.Address); } else { return(m.Mem(DataWidth, addr.Address)); } case PredecrementMemoryOperand pre: ea = binder.EnsureRegister(pre.Register); m.Assign(ea, m.ISubS(ea, DataWidth.Size)); return(m.Mem(DataWidth, ea)); case PostIncrementMemoryOperand post: r = binder.EnsureRegister(post.Register); var tmp = binder.CreateTemporary(DataWidth); m.Assign(tmp, m.Mem(DataWidth, r)); m.Assign(r, m.IAddS(r, DataWidth.Size)); return(tmp); case IndirectIndexedOperand indidx: ea = RewriteIndirectBaseRegister(indidx, addrInstr); Expression ix = binder.EnsureRegister(indidx.XRegister); if (indidx.XWidth.Size != 4) { ix = m.Slice(PrimitiveType.Int16, ix, 0); ix = m.Convert(ix, PrimitiveType.Int16, PrimitiveType.Int32); } if (indidx.Scale > 1) { ix = m.IMul(ix, Constant.Int32(indidx.Scale)); } return(m.Mem(DataWidth, m.IAdd(ea, ix))); case IndexedOperand indop: 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.Convert(m.Slice(PrimitiveType.Int16, idx, 0), PrimitiveType.Int16, PrimitiveType.Int32); } if (indop.IndexScale > 1) { idx = m.IMul(idx, indop.IndexScale); } ea = Combine(ea, idx); } if (indop.preindex) { ea = m.Mem32(ea); } ea = Combine(ea, indop.OuterDisplacement); return(m.Mem(DataWidth, ea)); } throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; var instrs = new List <RtlInstruction>(); this.m = new RtlEmitter(instrs); this.iclass = dasm.Current.InstructionClass; switch (instr.Mnemonic) { case Mnemonic.invalid: m.Invalid(); break; case Mnemonic.brk: case Mnemonic.cmps: case Mnemonic.movs: case Mnemonic.retb: case Mnemonic.stop: default: EmitUnitTest(); this.iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.add: RewriteAdd(); break; case Mnemonic.addc: RewriteAddcSubc(m.IAdd); break; case Mnemonic.addw: RewriteAddw(); break; case Mnemonic.and: RewriteLogical(m.And); break; case Mnemonic.and1: RewriteLogical1(m.And); break; case Mnemonic.bc: RewriteBranch(ConditionCode.ULT, C()); break; case Mnemonic.bf: RewriteBf(); break; case Mnemonic.bh: RewriteBranch(ConditionCode.UGT, CZ()); break; case Mnemonic.bnc: RewriteBranch(ConditionCode.UGE, C()); break; case Mnemonic.bnh: RewriteBranch(ConditionCode.ULE, CZ()); break; case Mnemonic.bnz: RewriteBranch(ConditionCode.NE, Z()); break; case Mnemonic.br: RewriteBr(); break; case Mnemonic.bt: RewriteBt(); break; case Mnemonic.btclr: RewriteBtclr(); break; case Mnemonic.bz: RewriteBranch(ConditionCode.EQ, Z()); break; case Mnemonic.call: RewriteCall(); break; case Mnemonic.callt: RewriteCall(); break; case Mnemonic.clr1: RewriteClr1(); break; case Mnemonic.clrb: RewriteClr(PrimitiveType.Byte); break; case Mnemonic.clrw: RewriteClr(PrimitiveType.Word16); break; case Mnemonic.cmp: RewriteCmp(); break; case Mnemonic.cmp0: RewriteCmp0(); break; case Mnemonic.cmpw: RewriteCmp(); break; case Mnemonic.dec: RewriteIncDec((a, b) => m.ISubS(a, 1)); break; case Mnemonic.decw: RewriteIncwDecw((a, b) => m.ISubS(a, 1)); break; case Mnemonic.halt: RewriteHalt(); break; case Mnemonic.inc: RewriteIncDec((a, b) => m.IAddS(a, 1)); break; case Mnemonic.incw: RewriteIncwDecw((a, b) => m.IAddS(a, 1)); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.mov1: RewriteMov1(); break; case Mnemonic.movw: RewriteMov(); break; case Mnemonic.mulu: RewriteMulu(); break; case Mnemonic.oneb: RewriteOne(PrimitiveType.Byte); break; case Mnemonic.onew: RewriteOne(PrimitiveType.Word16); break; case Mnemonic.or: RewriteLogical(m.Or); break; case Mnemonic.or1: RewriteLogical1(m.Or); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.not1: RewriteNot1(); break; case Mnemonic.pop: RewritePop(); break; case Mnemonic.push: RewritePush(); break; case Mnemonic.ret: RewriteRet(); break; case Mnemonic.reti: RewriteRet(); break; case Mnemonic.rol: RewriteRotate(PseudoProcedure.Rol); break; case Mnemonic.rolc: RewriteRotateC(PseudoProcedure.RolC); break; case Mnemonic.rolwc: RewriteRotateC(PseudoProcedure.RolC); break; case Mnemonic.ror: RewriteRotate(PseudoProcedure.Ror); break; case Mnemonic.rorc: RewriteRotate(PseudoProcedure.RorC); break; case Mnemonic.sar: RewriteShift(m.Sar); break; case Mnemonic.sarw: RewriteShiftw(m.Sar); break; case Mnemonic.sel: RewriteSel(); break; case Mnemonic.set1: RewriteSet1(); break; case Mnemonic.shl: RewriteShift(m.Shl); break; case Mnemonic.shlw: RewriteShiftw(m.Shl); break; case Mnemonic.shr: RewriteShift(m.Shr); break; case Mnemonic.shrw: RewriteShiftw(m.Shr); break; case Mnemonic.skc: RewriteSkip(ConditionCode.ULT, C()); break; case Mnemonic.skh: RewriteSkip(ConditionCode.UGT, CZ()); break; case Mnemonic.sknc: RewriteSkip(ConditionCode.UGE, C()); break; case Mnemonic.sknh: RewriteSkip(ConditionCode.ULE, CZ()); break; case Mnemonic.sknz: RewriteSkip(ConditionCode.NE, Z()); break; case Mnemonic.skz: RewriteSkip(ConditionCode.EQ, Z()); break; case Mnemonic.sub: RewriteSub(); break; case Mnemonic.subc: RewriteAddcSubc(m.ISub); break; case Mnemonic.subw: RewriteSubw(); break; case Mnemonic.xch: RewriteXch(); break; case Mnemonic.xchw: RewriteXch(); break; case Mnemonic.xor: RewriteLogical(m.Xor); break; case Mnemonic.xor1: RewriteLogical1(m.Xor); break; } yield return(m.MakeCluster(instr.Address, instr.Length, iclass)); } }
private Expression RewriteSrcOp(int iOp, PrimitiveType width) { var op = this.instr.Operands[iOp]; switch (op) { case RegisterOperand regOp: var reg = binder.EnsureRegister(regOp.Register); if (reg == null) { return(null); } if (width.Size == 4) { return(reg); } else if (width.Size == 8) { var rHi = arch.GetRegister(1 + (int)reg.Storage.Domain); if (rHi == null) { return(null); } var regHi = binder.EnsureRegister(rHi); return(binder.EnsureSequence(width, regHi.Storage, reg.Storage)); } else if (width.Size == 16) { var regHi1 = binder.EnsureRegister(arch.GetRegister(1 + (int)reg.Storage.Domain)); var regHi2 = binder.EnsureRegister(arch.GetRegister(2 + (int)reg.Storage.Domain)); var regHi3 = binder.EnsureRegister(arch.GetRegister(3 + (int)reg.Storage.Domain)); var regLo = binder.EnsureSequence(PrimitiveType.Word64, regHi1.Storage, reg.Storage); var regHi = binder.EnsureSequence(PrimitiveType.Word64, regHi3.Storage, regHi2.Storage); return(binder.EnsureSequence(width, regHi.Storage, regLo.Storage)); } else { return(m.Slice(width, reg, 0)); } case ImmediateOperand immOp: return(immOp.Value); case MemoryOperand memOp: Expression ea; if (memOp.Base != null) { reg = binder.EnsureRegister(memOp.Base); if (memOp.AutoDecrement) { m.Assign(reg, m.ISub(reg, width.Size)); } else if (memOp.AutoIncrement) { var tmp = binder.CreateTemporary(reg.DataType); m.Assign(tmp, reg); reg = tmp; } ea = reg; if (memOp.Offset != null) { if (memOp.Offset.DataType.BitSize < ea.DataType.BitSize) { ea = m.IAddS(ea, memOp.Offset.ToInt32()); } else { ea = m.IAdd(ea, memOp.Offset); } } if (memOp.Index != null) { Expression idx = binder.EnsureRegister(memOp.Index); if (width.Size != 1) { idx = m.IMul(idx, Constant.Int32(width.Size)); } ea = m.IAdd(ea, idx); } Expression load; if (memOp.Deferred) { load = m.Mem(width, m.Mem32(ea)); } else { load = m.Mem(width, ea); } if (memOp.AutoIncrement) { reg = binder.EnsureRegister(memOp.Base); int inc = (memOp.Deferred) ? 4 : width.Size; m.Assign(reg, m.IAdd(reg, inc)); } return(load); } else { ea = arch.MakeAddressFromConstant(memOp.Offset, false); Expression load; if (memOp.Deferred) { load = m.Mem(width, m.Mem32(ea)); } else { load = m.Mem(width, ea); } return(load); } case AddressOperand addrOp: //$BUG: enabling the commented code causes huge regressions in the // unzip subject. /*if (addrOp.Width.BitSize > width.BitSize) * { * var c = addrOp.Address.ToUInt32(); * return Constant.Create(width, c); * } * else*/ { return(addrOp.Address); } } throw new NotImplementedException(op.GetType().Name); }