private void RewriteMovx() { var src = SrcOperand(1); var from = PrimitiveType.Create(Domain.SignedInt, src.DataType.BitSize); m.Assign(Reg(0), m.Convert(src, from, PrimitiveType.Int32)); }
private void RewriteLoad(PrimitiveType dtDst) { var dst = Reg(instrCur.Operands[0]); Expression mem = Mem(instrCur.Operands[1]); if (mem.DataType.BitSize < dtDst.BitSize) { mem = m.Convert(mem, mem.DataType, dtDst); } m.Assign(dst, mem); }
private void RewriteLoad(PrimitiveType dt) { var src = Rewrite(instr.Operands[1]); var dst = Rewrite(instr.Operands[0]); if (src.DataType.BitSize < dst.DataType.BitSize) { src = m.Convert(src, src.DataType, dt); } m.Assign(dst, src); }
private void RewriteCast(PrimitiveType dtFrom, PrimitiveType dtTo) { var src = RewriteOp(0); if (src.DataType.BitSize > dtFrom.BitSize) { src = m.Slice(dtFrom, src, 0); } var dst = RewriteOpDst(0, m.Convert(src, dtFrom, dtTo)); EmitCc(NZC, dst); }
private void EmitLoad(Identifier dst, MemoryAccess src) { if (src.DataType.BitSize < dst.DataType.BitSize) { var tmp = binder.CreateTemporary(src.DataType); m.Assign(tmp, src); m.Assign(dst, m.Convert(tmp, tmp.DataType, dst.DataType)); } else { m.Assign(dst, src); } }
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.Convert(idx, idx.DataType, PrimitiveType.UInt16); } 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 void RewriteMovz() { var src = Op(1); var dst = Op(0); m.Assign(dst, m.Convert(src, src.DataType, dst.DataType)); }
private void RewriteSxt(string flags) { var src = RewriteOp(instr.Operands[0]); var tmp = binder.CreateTemporary(PrimitiveType.Byte); m.Assign(tmp, m.Slice(PrimitiveType.Byte, src, 0)); var dst = RewriteDst(instr.Operands[0], tmp, (a, b) => m.Convert(b, b.DataType, PrimitiveType.Int16)); EmitCc(dst, flags); }
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 RewriteSxt() { var src = RewriteOp(instr.Operands[0]); var tmp = binder.CreateTemporary(PrimitiveType.Byte); m.Assign(tmp, m.Slice(PrimitiveType.Byte, src, 0)); var dst = RewriteDst(instr.Operands[0], tmp, (a, b) => m.Convert(b, b.DataType, PrimitiveType.Int16)); EmitCc(dst, Registers.NZC); Assign(Registers.V, Constant.False()); }
private void RewriteLoad(MipsInstruction instr, PrimitiveType dt) { var src = Rewrite(instr.Operands[1]); var dst = Rewrite(instr.Operands[0]); src.DataType = dt; if (dst.DataType.Size != src.DataType.Size) { // If the source is smaller than the destination register, // perform a sign/zero extension/conversion. src = m.Convert(src, src.DataType, arch.WordWidth); } m.Assign(dst, src); }
private void RewriteExt(H8Instruction instr, Domain domain) { var dstRange = new BitRange(0, instr.Size !.BitSize); var srcRange = new BitRange(0, instr.Size !.BitSize / 2); var dt = PrimitiveType.Create(domain, dstRange.Extent); var dst = (Identifier)OpSrc(instr.Operands[0]); var src = binder.EnsureRegister(arch.GetRegister( dst.Storage.Domain, srcRange) !); m.Assign(dst, m.Convert(src, src.DataType, dt)); EmitCond(Z, dst); m.Assign(binder.EnsureFlagGroup(N), Constant.False()); m.Assign(binder.EnsureFlagGroup(V), Constant.False()); }
private void RewriteAddw() { var src = RewriteSrc(instr.Operands[1]); Func <Expression, Expression, Expression> fn; if (src.DataType.Size < instr.Operands[0].Width.Size) { if (src is Constant c) { fn = (a, b) => m.IAddS(a, c.ToInt32()); } else { fn = (a, b) => m.IAdd(a, m.Convert(b, b.DataType, PrimitiveType.UInt16)); } } else { fn = m.IAdd; } var dst = RewriteDst(instr.Operands[0], src, fn); EmitCond(dst, CZ()); }
private void RewriteExt(PrimitiveType dtSrc, PrimitiveType dtDst) { var src = SrcOp(instr.Operands[0], null); var dst = DstOp(instr.Operands[1], src, (a, b) => { if (b.DataType.BitSize > dtSrc.BitSize) { b = m.Slice(dtSrc, b, 0); } return(m.Convert(b, dtSrc, dtDst)); }); }
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.Convert(binder.EnsureRegister(mem.Register), mem.Register.DataType, PrimitiveType.UInt16)); } 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 Expression?RewriteApplication(ApplicationOperand app) { var ops = app.Operands.Select(o => OperandSrc(o) !).ToArray(); var dt = app.Width; switch (app.Mnemonic) { case Mnemonic.add: return(m.IAdd(ops[0], ops[1])); case Mnemonic.addasl: return(RewriteAddAsl(ops[0], ops[1], ops[2])); case Mnemonic.allocframe: RewriteAllocFrame(app.Operands[0]); return(null); case Mnemonic.and: return(m.And(ops[0], ops[1])); case Mnemonic.asl: return(m.Shl(ops[0], ops[1])); case Mnemonic.aslh: return(m.Shl(ops[0], 16)); case Mnemonic.asr: return(m.Sar(ops[0], ops[1])); case Mnemonic.asrh: return(m.Sar(ops[0], 16)); case Mnemonic.cmp__eq: return(m.Eq(ops[0], ops[1])); case Mnemonic.cmp__gt: return(m.Gt(ops[0], ops[1])); case Mnemonic.cmp__gtu: return(m.Ugt(ops[0], ops[1])); case Mnemonic.cmpb__eq: return(RewriteCmp(PrimitiveType.Byte, m.Eq, ops[0], ops[1])); case Mnemonic.cmpb__gt: return(RewriteCmp(PrimitiveType.Byte, m.Gt, ops[0], ops[1])); case Mnemonic.cmpb__gtu: return(RewriteCmp(PrimitiveType.Byte, m.Ugt, ops[0], ops[1])); case Mnemonic.cmph__eq: return(RewriteCmp(PrimitiveType.Word16, m.Eq, ops[0], ops[1])); case Mnemonic.cmph__gt: return(RewriteCmp(PrimitiveType.Word16, m.Gt, ops[0], ops[1])); case Mnemonic.cmph__gtu: return(RewriteCmp(PrimitiveType.Word16, m.Ugt, ops[0], ops[1])); case Mnemonic.dfcmp__eq: return(m.FEq(ops[0], ops[1])); case Mnemonic.dfcmp__ge: return(m.FGe(ops[0], ops[1])); case Mnemonic.dfcmp__uo: return(host.Intrinsic("isunordered", false, PrimitiveType.Bool, ops[0], ops[1])); case Mnemonic.combine: return(RewriteCombine(ops[0], ops[1])); case Mnemonic.convert_d2df: return(m.Convert(ops[0], PrimitiveType.Int64, PrimitiveType.Real64)); case Mnemonic.convert_df2sf: return(m.Convert(ops[0], PrimitiveType.Real64, PrimitiveType.Real32)); case Mnemonic.convert_sf2df: return(m.Convert(ops[0], PrimitiveType.Real32, PrimitiveType.Real64)); case Mnemonic.EQ: return(m.Eq(ops[0], ops[1])); case Mnemonic.extract: return(RewriteExtract(Domain.SignedInt, ops[0], app.Operands)); case Mnemonic.extractu: return(RewriteExtract(Domain.UnsignedInt, ops[0], app.Operands)); case Mnemonic.loop0: RewriteLoop(0, ops); return(null); case Mnemonic.loop1: RewriteLoop(1, ops); return(null); case Mnemonic.lsl: return(m.Shl(ops[0], ops[1])); case Mnemonic.lsr: return(m.Shr(ops[0], ops[1])); case Mnemonic.mpy: return(RewriteMpy(ops[0], ops[1])); case Mnemonic.mpyi: return(RewriteMpyi(ops[0], ops[1])); case Mnemonic.mpyu: return(RewriteMpyu(app.Width, ops[0], ops[1])); case Mnemonic.mux: return(m.Conditional(ops[1].DataType, ops[0], ops[1], ops[2])); case Mnemonic.NE: return(m.Ne(ops[0], ops[1])); case Mnemonic.neg: return(m.Neg(ops[0])); case Mnemonic.not: return(m.Not(ops[0])); case Mnemonic.or: return(m.Or(ops[0], ops[1])); case Mnemonic.sub: return(m.ISub(ops[0], ops[1])); case Mnemonic.sxtb: return(RewriteExt(ops[0], PrimitiveType.SByte, PrimitiveType.Int32)); case Mnemonic.sxth: return(RewriteExt(ops[0], PrimitiveType.Int16, PrimitiveType.Int32)); case Mnemonic.xor: return(m.Xor(ops[0], ops[1])); case Mnemonic.zxtb: return(RewriteExt(ops[0], PrimitiveType.Byte, PrimitiveType.UInt32)); case Mnemonic.zxth: return(RewriteExt(ops[0], PrimitiveType.UInt16, PrimitiveType.UInt32)); case Mnemonic.abs: dt = PrimitiveType.Int32; goto intrinsicFunc; case Mnemonic.max: dt = PrimitiveType.Int32; goto intrinsicFunc; case Mnemonic.maxu: dt = PrimitiveType.UInt32; goto intrinsicFunc; case Mnemonic.min: dt = PrimitiveType.Int32; goto intrinsicFunc; case Mnemonic.minu: dt = PrimitiveType.UInt32; goto intrinsicFunc; case Mnemonic.all8: case Mnemonic.any8: case Mnemonic.bitsclr: case Mnemonic.bitsplit: case Mnemonic.bitsset: case Mnemonic.ciad: case Mnemonic.cl0: case Mnemonic.cl1: case Mnemonic.clb: case Mnemonic.clrbit: case Mnemonic.crswap: case Mnemonic.cswi: case Mnemonic.ct0: case Mnemonic.dfclass: case Mnemonic.fastcorner9: case Mnemonic.insert: //$BUG: like DPB? case Mnemonic.memw_locked: case Mnemonic.setbit: case Mnemonic.start: case Mnemonic.stop: case Mnemonic.tlbw: case Mnemonic.tlbp: case Mnemonic.trap0: case Mnemonic.trap1: case Mnemonic.togglebit: case Mnemonic.tstbit: intrinsicFunc: return(RewriteIntrinsic(app.Mnemonic.ToString(), true, dt, ops)); case Mnemonic.dccleana: case Mnemonic.dccleaninva: case Mnemonic.dcfetch: case Mnemonic.dcinva: case Mnemonic.dczeroa: return(RewriteIntrinsic(app.Mnemonic.ToString(), true, VoidType.Instance, ops)); case Mnemonic.vavgh: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Word16, ops)); case Mnemonic.vcmpb__eq: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Byte, ops)); case Mnemonic.vmux: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Byte, ops)); case Mnemonic.vsplatb: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Byte, ops)); case Mnemonic.vsubh: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Int16, ops)); } throw new ArgumentException($"Hexagon rewriter for {app.Mnemonic} not implemented yet.", app.Mnemonic.ToString()); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; this.iclass = this.instr.InstructionClass; var instrs = new List <RtlInstruction>(); this.m = new RtlEmitter(instrs); switch (instr.Mnemonic) { default: host.Error( dasm.Current.Address, string.Format( "SuperH instruction {0} not supported yet.", dasm.Current.Mnemonic)); EmitUnitTest(); goto case Mnemonic.invalid; case Mnemonic.invalid: Invalid(); break; case Mnemonic.add: RewriteBinOp(m.IAdd, n => (sbyte)n); break; case Mnemonic.addc: RewriteAddcSubc(m.IAdd); break; case Mnemonic.addv: RewriteAddv(m.IAdd); break; case Mnemonic.and: RewriteBinOp(m.And, n => (byte)n); break; case Mnemonic.and_b: RewriteBinOp(m.And, n => (byte)n); break; case Mnemonic.bf: RewriteBranch(false, false); break; case Mnemonic.bf_s: RewriteBranch(false, true); break; case Mnemonic.bra: RewriteGoto(); break; case Mnemonic.braf: RewriteBraf(); break; case Mnemonic.brk: RewriteBrk(); break; case Mnemonic.bsr: RewriteBsr(); break; case Mnemonic.bsrf: RewriteBsrf(); break; case Mnemonic.bt: RewriteBranch(true, false); break; case Mnemonic.bt_s: RewriteBranch(true, true); break; case Mnemonic.clrmac: RewriteClr(Registers.mac); break; case Mnemonic.clrs: RewriteClrtSet(Registers.S, Constant.False()); break; case Mnemonic.clrt: RewriteClrtSet(Registers.T, Constant.False()); break; case Mnemonic.cmp_eq: RewriteCmp(m.Eq); break; case Mnemonic.cmp_ge: RewriteCmp(m.Ge); break; case Mnemonic.cmp_gt: RewriteCmp(m.Gt); break; case Mnemonic.cmp_hs: RewriteCmp(m.Uge); break; case Mnemonic.cmp_hi: RewriteCmp(m.Ugt); break; case Mnemonic.cmp_pl: RewriteCmp0(m.Gt0); break; case Mnemonic.cmp_pz: RewriteCmp0(m.Ge0); break; case Mnemonic.cmp_str: RewriteCmpStr(); break; case Mnemonic.div0s: RewriteDiv0s(); break; case Mnemonic.div0u: RewriteDiv0u(); break; case Mnemonic.div1: RewriteDiv1(); break; case Mnemonic.dmuls_l: RewriteDmul(m.SMul); break; case Mnemonic.dmulu_l: RewriteDmul(m.UMul); break; case Mnemonic.dt: RewriteDt(); break; case Mnemonic.exts_b: RewriteExt(PrimitiveType.SByte, PrimitiveType.Int32); break; case Mnemonic.exts_w: RewriteExt(PrimitiveType.Int16, PrimitiveType.Int32); break; case Mnemonic.extu_b: RewriteExt(PrimitiveType.Byte, PrimitiveType.UInt32); break; case Mnemonic.extu_w: RewriteExt(PrimitiveType.UInt16, PrimitiveType.UInt32); break; case Mnemonic.fabs: RewriteFabs(); break; case Mnemonic.fadd: RewriteBinOp(m.FAdd, null); break; case Mnemonic.fcmp_eq: RewriteCmp(m.FEq); break; case Mnemonic.fcmp_gt: RewriteCmp(m.FGt); break; case Mnemonic.fcnvds: RewriteUnary(d => m.Convert(d, PrimitiveType.Real64, PrimitiveType.Real32)); break; case Mnemonic.fcnvsd: RewriteUnary(d => m.Convert(d, PrimitiveType.Real32, PrimitiveType.Real64)); break; case Mnemonic.fdiv: RewriteBinOp(m.FDiv, null); break; case Mnemonic.fldi0: RewriteFldi(0.0F); break; case Mnemonic.fldi1: RewriteFldi(1.0F); break; case Mnemonic.flds: RewriteMov(); break; case Mnemonic.@float: RewriteFloat(); break; case Mnemonic.fmac: RewriteFmac(); break; case Mnemonic.fmov: RewriteMov(); break; case Mnemonic.fmov_d: RewriteMov(); break; case Mnemonic.fmov_s: RewriteMov(); break; case Mnemonic.fmul: RewriteBinOp(m.FMul, n => n); break; case Mnemonic.fsts: RewriteMov(); break; case Mnemonic.ftrc: RewriteFtrc(); break; case Mnemonic.jmp: RewriteJmp(); break; case Mnemonic.jsr: RewriteJsr(); break; case Mnemonic.lds: RewriteMov(); break; case Mnemonic.lds_l: RewriteMov(); break; case Mnemonic.mac_l: RewriteMac(PrimitiveType.Int64); break; case Mnemonic.mac_w: RewriteMac(PrimitiveType.Int32); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.mova: RewriteMova(); break; case Mnemonic.mov_b: RewriteMov(); break; case Mnemonic.mov_w: RewriteMov(); break; case Mnemonic.mov_l: RewriteMov(); break; case Mnemonic.movt: RewriteMovt(); break; case Mnemonic.mul_l: RewriteMul_l(); break; case Mnemonic.muls_w: RewriteMul_w(PrimitiveType.Int16, m.SMul); break; case Mnemonic.mulu_w: RewriteMul_w(PrimitiveType.UInt16, m.UMul); break; case Mnemonic.neg: RewriteUnary(m.Neg); break; case Mnemonic.negc: RewriteNegc(); break; case Mnemonic.not: RewriteUnary(m.Comp); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.ocbi: RewriteOcbi(); break; case Mnemonic.or: RewriteBinOp(m.Or, u => (byte)u); break; case Mnemonic.rotcl: RewriteRotc(IntrinsicProcedure.RolC); break; case Mnemonic.rotcr: RewriteRotc(IntrinsicProcedure.RorC); break; case Mnemonic.rotl: RewriteRot(IntrinsicProcedure.Rol); break; case Mnemonic.rotr: RewriteRot(IntrinsicProcedure.Ror); break; case Mnemonic.rts: RewriteRts(); break; case Mnemonic.sett: RewriteClrtSet(Registers.T, Constant.True()); break; case Mnemonic.shad: RewriteShd(m.Shl, m.Sar); break; case Mnemonic.shar: RewriteShift(m.Sar, 1); break; case Mnemonic.shld: RewriteShd(m.Shl, m.Shr); break; case Mnemonic.shll: RewriteShift(m.Shl, 1); break; case Mnemonic.shll2: RewriteShift(m.Shl, 2); break; case Mnemonic.shll8: RewriteShift(m.Shl, 8); break; case Mnemonic.shll16: RewriteShift(m.Shl, 16); break; case Mnemonic.shlr: RewriteShift(m.Shr, 1); break; case Mnemonic.shlr2: RewriteShift(m.Shr, 2); break; case Mnemonic.shlr8: RewriteShift(m.Shr, 8); break; case Mnemonic.shlr16: RewriteShift(m.Shr, 16); break; case Mnemonic.stc: RewriteMov(); break; case Mnemonic.sts: RewriteMov(); break; case Mnemonic.sts_l: RewriteMov(); break; case Mnemonic.sub: RewriteBinOp(m.ISub, null); break; case Mnemonic.subc: RewriteAddcSubc(m.ISub); break; case Mnemonic.swap_w: RewriteSwapW(); break; case Mnemonic.tst: RewriteTst(); break; case Mnemonic.xor: RewriteBinOp(m.Xor, n => (byte)n); break; case Mnemonic.xtrct: RewriteXtrct(); break; } yield return(m.MakeCluster(instr.Address, instr.Length, this.iclass)); } }
public HExpr Cast(BaseType type, HExpr a) { var src = GetExpression(a); return(MapToHandle(m.Convert(src, src.DataType, Interop.DataTypes[type]))); }
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); }
} // 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); }
private void RewriteMovx() { var src = Operand(1); m.Assign(Reg(0), m.Convert(src, src.DataType, PrimitiveType.Word32)); }