//$REFACTOR: this probably should live in X86FrameApplicationBuilder public override Expression CreateFpuStackAccess(IStorageBinder binder, int offset, DataType dataType) { Expression e = binder.EnsureRegister(Registers.Top); if (offset != 0) { BinaryOperator op; if (offset < 0) { offset = -offset; op = Operator.ISub; } else { op = Operator.IAdd; } e = new BinaryExpression(op, e.DataType, e, Constant.Create(e.DataType, offset)); } return(new MemoryAccess(Registers.ST, e, dataType)); }
private Expression RewriteOp(MachineOperand op) { switch (op) { case RegisterOperand rop: if (rop.Register.Number == 0) { //$TODO: 32-bit! return(Constant.Word64(0)); } return(binder.EnsureRegister(rop.Register)); case ImmediateOperand immop: return(immop.Value); case AddressOperand addrop: return(addrop.Address); } throw new NotImplementedException($"Rewriting RiscV addressing mode {op.GetType().Name} is not implemented yet."); }
private Expression RewriteOp(MachineOperand op) { var rOp = op as RegisterOperand; if (rOp != null) { return(binder.EnsureRegister(rOp.Register)); } var aOp = op as AddressOperand; if (aOp != null) { return(aOp.Address); } var iOp = op as ImmediateOperand; if (iOp != null) { return(iOp.Value); } throw new NotImplementedException(op.GetType().FullName); }
private Expression EffectiveAddress(MemoryOperand mem) { if (mem.Base == null || mem.Base.Number == 0) { // Must be abs address. return(Address.Create(arch.PointerType, (uint)mem.Offset)); } Expression ea = binder.EnsureRegister(mem.Base); if (mem.Index != null && mem.Index.Number > 0) { var idx = binder.EnsureRegister(mem.Index); ea = m.IAdd(ea, idx); } if (mem.Offset != 0) { var off = Constant.Int(mem.Base.DataType, mem.Offset); ea = m.IAdd(ea, off); } return(ea); }
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 void RewriteJz(Func <Expression, Expression> cmp) { iclass = InstrClass.ConditionalTransfer; var src = binder.EnsureRegister(Registers.A); var addr = ((AddressOperand)instr.Operands[0]).Address; m.Branch(cmp(src), addr, InstrClass.ConditionalTransfer); }
private Expression RewriteOp(MachineOperand op) { switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case ImmediateOperand immop: return(immop.Value); case MemoryOperand memop: return(RewriteMemoryOperand(memop)); } throw new NotImplementedException(); }
} // 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 void AddRegisterArgument(RegisterStorage reg) { AddInParam(binder.EnsureRegister(reg)); }
protected Identifier Fsr2; // cached FSR2 register identifier protected PIC18RewriterBase(PICArchitecture arch, PICDisassemblerBase disasm, PICProcessorState state, IStorageBinder binder, IRewriterHost host) : base(arch, disasm, state, binder, host) { Fsr2 = binder.EnsureRegister(PIC18Registers.FSR2); }
private Expression RewriteJmpSrc(MachineOperand op) { var memOp = op as MemoryOperand; if (memOp == null) { // PDP-11 always has a memory reference // for the destination of a transfer instruction. return(null); } var r = memOp.Register != null ? binder.EnsureRegister(memOp.Register) : null; var tmp = binder.CreateTemporary(op.Width); switch (memOp.Mode) { default: throw new AddressCorrelatedException( dasm.Current.Address, "Not implemented: addressing mode {0}.", memOp.Mode); case AddressMode.RegDef: return(r); case AddressMode.Absolute: return(Address.Ptr16(memOp.EffectiveAddress)); case AddressMode.AutoIncr: m.Assign(tmp, m.Mem(PrimitiveType.Ptr16, r)); m.Assign(r, m.IAdd(r, memOp.Width.Size)); break; case AddressMode.AutoIncrDef: m.Assign(tmp, m.Mem(op.Width, r)); m.Assign(r, m.IAdd(r, memOp.Width.Size)); break; case AddressMode.AutoDecr: m.Assign(r, m.ISub(r, memOp.Width.Size)); return(m.Mem(op.Width, r)); case AddressMode.AutoDecrDef: m.Assign(r, m.ISub(r, memOp.Width.Size)); m.Assign(tmp, m.Mem(op.Width, m.Mem(PrimitiveType.Ptr16, r))); return(tmp); case AddressMode.Indexed: if (memOp.Register == Registers.pc) { var offset = (short)memOp.EffectiveAddress; var addrBase = (long)instr.Address.ToLinear(); var addr = Address.Ptr16((ushort)(instr.Length + addrBase + offset)); return(addr); } else { return(m.Mem( this.dasm.Current.DataWidth, m.IAdd(r, Constant.Word16(memOp.EffectiveAddress)))); } case AddressMode.IndexedDef: if (memOp.Register == Registers.pc) { var offset = (short)memOp.EffectiveAddress; var addrBase = (long)instr.Address.ToLinear() + instr.Length; var addr = Constant.Word16((ushort)(addrBase + offset)); return(m.Mem( PrimitiveType.Word16, addr)); } else { return(m.Mem( PrimitiveType.Ptr16, m.IAdd(r, Constant.Word16(memOp.EffectiveAddress)))); } } return(tmp); /* * var immOp = op as ImmediateOperand; * if (immOp != null) * { * return immOp.Value; * } * var addrOp = op as AddressOperand; * if (addrOp != null) * { * return addrOp.Address; * } * throw new NotImplementedException(); */ }
public Identifier AluRegister(RegisterOperand reg) { return(binder.EnsureRegister(reg.Register)); }
public override Expression CreateStackAccess(IStorageBinder binder, int cbOffset, DataType dataType) { var sp = binder.EnsureRegister(this.StackRegister); return(MemoryAccess.Create(sp, cbOffset, dataType)); }
private Expression RewriteSrcOp(int iOp, PrimitiveType width) { var op = dasm.Current.Operands[iOp]; var regOp = op as RegisterOperand; if (regOp != null) { 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(regHi.Storage, reg.Storage, width)); } 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(regHi1.Storage, reg.Storage, PrimitiveType.Word64); var regHi = binder.EnsureSequence(regHi3.Storage, regHi2.Storage, PrimitiveType.Word64); return(binder.EnsureSequence(regHi.Storage, regLo.Storage, width)); } else { return(m.Cast(width, reg)); } } var immOp = op as ImmediateOperand; if (immOp != null) { return(immOp.Value); } var memOp = op as MemoryOperand; if (memOp != null) { Expression ea; if (memOp.Base != null) { var 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) { 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) { 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 { } } var addrOp = op as AddressOperand; if (addrOp != null) { return(addrOp.Address); } throw new NotImplementedException(op.GetType().Name); }
private Expression Operand(MachineOperand op) { switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case ImmediateOperand imm: return(imm.Value); case MemoryOperand mem: Expression ea; if (mem.Address != null) { if (mem.Register != null) { ea = m.IAdd( mem.Address, m.Cast(PrimitiveType.UInt16, binder.EnsureRegister(mem.Register))); } else { ea = mem.Address; } } else { ea = RegisterPair(mem.Register); } return(m.Mem(mem.Width, ea)); case AddressOperand addr: return(addr.Address); default: throw new NotImplementedException(op.GetType().Name); } }
private void Copy(RegisterStorage regDst, RegisterStorage regSrc) { var dst = binder.EnsureRegister(regDst); var src = binder.EnsureRegister(regSrc); m.Assign(dst, src); m.Assign( binder.EnsureFlagGroup( Registers.p, (uint)(FlagM.NF | FlagM.ZF), "NZ", PrimitiveType.Byte), m.Cond(dst)); }
private void RewriteBlockInstruction(Func <Expression, Expression, Expression> incdec, bool repeat) { var bc = binder.EnsureRegister(Registers.bc); var de = binder.EnsureRegister(Registers.de); var hl = binder.EnsureRegister(Registers.hl); var V = FlagGroup(FlagM.PF); m.Assign(m.Mem8(de), m.Mem8(hl)); m.Assign(hl, incdec(hl, Constant.Int16(1))); m.Assign(de, incdec(de, Constant.Int16(1))); m.Assign(bc, m.ISub(bc, 1)); if (repeat) { m.BranchInMiddleOfInstruction(m.Ne0(bc), dasm.Current.Address, InstrClass.Transfer); } m.Assign(V, m.Const(PrimitiveType.Bool, 0)); }
} // 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); }
private void Push(RegisterStorage stackRegister, RegisterStorage reg) { var sp = binder.EnsureRegister(stackRegister); m.Assign(sp, m.ISubS(sp, reg.DataType.Size)); m.Assign(m.Mem(reg.DataType, sp), binder.EnsureRegister(reg)); }
private Expression?OperandSrc(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 ApplicationOperand app: return(RewriteApplication(app)); case MemoryOperand mem: var src = RewriteMemoryOperand(mem); MaybeEmitIncrement(mem); return(src); case RegisterPairOperand pair: return(binder.EnsureSequence(PrimitiveType.Word64, pair.HighRegister, pair.LowRegister)); case DecoratorOperand dec: return(RewriteDecorator(dec)); } throw new NotImplementedException($"Hexagon rewriter for {op.GetType().Name} not implemented yet."); }
/// <summary> /// Make a function signature based on the procedure flow <paramref name="flow"/>. /// </summary> /// <returns>A valid function signature.</returns> public FunctionType MakeSignature(SsaState ssa, IStorageBinder frame, ProcedureFlow flow) { var allLiveOut = flow.BitsLiveOut; var sb = new SignatureBuilder(frame, platform.Architecture); var implicitRegs = platform.CreateImplicitArgumentRegisters(); var liveOutFlagGroups = flow.grfLiveOut.Select(de => platform.Architecture.GetFlagGroup(de.Key, de.Value) !); AddModifiedFlags(frame, liveOutFlagGroups, sb); var mayUseSeqs = flow.BitsUsed.Keys.OfType <SequenceStorage>().ToHashSet(); var seqRegs = mayUseSeqs.SelectMany(s => s.Elements).Distinct().ToHashSet(); //$BUG: should be sorted by ABI register order. foreach (var seq in mayUseSeqs.OrderBy(r => r.Name)) { sb.AddSequenceArgument(seq); } var mayUseRegs = flow.BitsUsed .Select(de => (Key: de.Key as RegisterStorage, de.Value)) .Where(b => { return(b.Key is RegisterStorage reg && !implicitRegs.Contains(reg)); }) .Select(MakeRegisterParameter) .ToDictionary(de => de.Item1, de => de.Item2); //$BUG: should be sorted by ABI register order. Need a new method // IPlatform.CreateAbiRegisterCollator(). foreach (var reg in mayUseRegs.OrderBy(r => r.Key.Number)) { if (!IsSubRegisterOfRegisters(reg.Key, mayUseRegs) && !seqRegs.Contains(reg.Key)) { sb.AddRegisterArgument(reg.Key); } } foreach (var id in GetSortedStackArguments((Frame)frame, flow.BitsUsed)) { sb.AddInParam(id.Item2); } foreach (var oFpu in flow.BitsUsed .Where(f => f.Key is FpuStackStorage) .OrderBy(r => ((FpuStackStorage)r.Key).FpuStackOffset)) { var fpu = (FpuStackStorage)oFpu.Key; var id = frame.EnsureFpuStackVariable(fpu.FpuStackOffset, fpu.DataType); sb.AddFpuStackArgument(fpu.FpuStackOffset, id); } var liveOut = allLiveOut .Select(de => (Key: de.Key as RegisterStorage, de.Value)) .Where(de => { return(de.Key != null && !implicitRegs.Contains(de.Key)); }) .Select(MakeRegisterParameter) .ToDictionary(de => de.Item1, de => de.Item2); // Sort the names in a stable way to avoid regression tests failing. foreach (var r in liveOut.OrderBy(r => r.Key.Number).ThenBy(r => r.Key.BitAddress)) { if (!IsSubRegisterOfRegisters(r.Key, liveOut)) { var regOut = sb.AddOutParam(frame.EnsureRegister(r.Key)); if (regOut.Storage is OutArgumentStorage && !ssa.Identifiers.TryGetValue(regOut, out var sidOut)) { // Ensure there are SSA identifiers for 'out' registers. ssa.Identifiers.Add(regOut, null, null, false); } } } foreach (var fpu in allLiveOut.Keys.OfType <FpuStackStorage>().OrderBy(r => r.FpuStackOffset)) { sb.AddOutParam(frame.EnsureFpuStackVariable(fpu.FpuStackOffset, fpu.DataType)); } var sig = sb.BuildSignature(); return(sig); }
private Identifier Reg(int iOp) { var op = instrCur.Operands[iOp]; var id = binder.EnsureRegister(((RegisterOperand)op).Register); return(id); }
public Expression VisitRegisterStorage(RegisterStorage reg) { return(binder.EnsureRegister(reg)); }
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 SrcOp(MachineOperand op, Func <int, int> immediateFn = null) { var regOp = op as RegisterOperand; if (regOp != null) { var id = binder.EnsureRegister(regOp.Register); return(id); } var immOp = op as ImmediateOperand; if (immOp != null) { return(Constant.Word32(immediateFn(immOp.Value.ToInt32()))); } var addrOp = op as AddressOperand; if (addrOp != null) { return(addrOp.Address); } var mem = op as MemoryOperand; if (mem != null) { 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); }
public override Expression CreateStackAccess(IStorageBinder binder, int offset, DataType dataType) { var rsp = binder.EnsureRegister(Registers.rsp); return(MemoryAccess.Create(rsp, offset, dataType)); }
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); }
private void RewriteJxx(RegisterStorage reg, Func <Expression, BinaryExpression> test) { m.Branch(test(binder.EnsureRegister(reg)), (Address)Op(0)); }
public Identifier Register(int iReg) { return(binder.EnsureRegister(arch.GetRegister(iReg))); }
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)); } }