private Expression Rol(Expression a, Expression b) { var C = binder.EnsureFlagGroup(Registers.C); var intrinsic = m.Fn(CommonOps.RolC, a, b, C); return(intrinsic); }
public Identifier FlagGroup(FlagM flags) { return(frame.EnsureFlagGroup(Registers.eflags, (uint)flags, arch.GrfToString((uint)flags), PrimitiveType.Byte)); }
private void RewriteAddcSubc(Func <Expression, Expression, Expression> fn) { var t = binder.EnsureFlagGroup(Registers.T); var src = SrcOp(instr.Operands[0], null); var dst = DstOp(instr.Operands[1], src, (a, b) => fn(fn(a, b), t)); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { di = dasm.Current; var addr = di.Address; var len = di.Length; rtlInstructions = new List <RtlInstruction>(); rtlc = RtlClass.Linear; m = new RtlEmitter(rtlInstructions); orw = new OperandRewriter(arch, this.m, this.binder, di.dataWidth); switch (di.code) { default: host.Warn( di.Address, "Rewriting M68k opcode '{0}' is not supported yet.", di.code); m.Invalid(); break; case Opcode.illegal: RewriteIllegal(); break; case Opcode.add: RewriteBinOp((s, d) => m.IAdd(d, s), FlagM.CVZNX); break; case Opcode.adda: RewriteBinOp((s, d) => m.IAdd(d, s)); break; case Opcode.addi: RewriteArithmetic((s, d) => m.IAdd(d, s)); break; case Opcode.addq: RewriteAddSubq((s, d) => m.IAdd(d, s)); break; case Opcode.addx: RewriteAddSubx(m.IAdd); break; case Opcode.and: RewriteLogical((s, d) => m.And(d, s)); break; case Opcode.andi: RewriteLogical((s, d) => m.And(d, s)); break; case Opcode.asl: RewriteArithmetic((s, d) => m.Shl(d, s)); break; case Opcode.asr: RewriteShift((s, d) => m.Sar(d, s)); break; /* * * Mnemonic Condition Encoding Test * T* True 0000 1 * F* False 0001 0 * HI High 0010 C L Z * LS Low or Same 0011 C V Z * VC Overflow Clear 1000 V * VS Overflow Set 1001 V */ case Opcode.bclr: RewriteBclrBset("__bclr"); break; case Opcode.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); break; case Opcode.bcs: RewriteBcc(ConditionCode.ULT, FlagM.CF); break; case Opcode.beq: RewriteBcc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.bge: RewriteBcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Opcode.bgt: RewriteBcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.bhi: RewriteBcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Opcode.ble: RewriteBcc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.blt: RewriteBcc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break; case Opcode.bls: RewriteBcc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break; case Opcode.bmi: RewriteBcc(ConditionCode.LT, FlagM.NF); break; case Opcode.bne: RewriteBcc(ConditionCode.NE, FlagM.ZF); break; case Opcode.bpl: RewriteBcc(ConditionCode.GT, FlagM.NF); break; case Opcode.bvs: RewriteBcc(ConditionCode.OV, FlagM.VF); break; case Opcode.bchg: RewriteBchg(); break; case Opcode.bra: RewriteBra(); break; case Opcode.bset: RewriteBclrBset("__bset"); break; case Opcode.bsr: RewriteBsr(); break; case Opcode.btst: RewriteBtst(); break; case Opcode.cas: RewriteCas(); break; case Opcode.clr: RewriteClr(); break; case Opcode.chk: RewriteChk(); break; case Opcode.chk2: RewriteChk2(); break; case Opcode.cmp: RewriteCmp(); break; case Opcode.cmp2: RewriteCmp2(); break; case Opcode.cmpa: RewriteCmp(); break; case Opcode.cmpi: RewriteCmp(); break; case Opcode.cmpm: RewriteCmp(); break; case Opcode.dbeq: RewriteDbcc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.dble: RewriteDbcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.dbhi: RewriteDbcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break; case Opcode.dbne: RewriteDbcc(ConditionCode.NE, FlagM.ZF); break; case Opcode.dbra: RewriteDbcc(ConditionCode.None, 0); break; case Opcode.divs: RewriteDiv(m.SDiv, PrimitiveType.Int16); break; case Opcode.divsl: RewriteDiv(m.SDiv, PrimitiveType.Int32); break; case Opcode.divu: RewriteDiv(m.UDiv, PrimitiveType.UInt16); break; case Opcode.eor: RewriteLogical((s, d) => m.Xor(d, s)); break; case Opcode.eori: RewriteLogical((s, d) => m.Xor(d, s)); break; case Opcode.exg: RewriteExg(); break; case Opcode.ext: RewriteExt(); break; case Opcode.extb: RewriteExtb(); break; case Opcode.fadd: RewriteFBinOp((s, d) => m.FAdd(d, s)); break; //$REVIEW: the following don't respect NaN, but NaN typically doesn't exist in HLLs. case Opcode.fbf: m.Nop(); break; case Opcode.fbnge: RewriteFbcc(ConditionCode.LT); break; case Opcode.fbnlt: RewriteFbcc(ConditionCode.GE); break; case Opcode.fbnle: RewriteFbcc(ConditionCode.GT); break; case Opcode.fbogl: RewriteFbcc(ConditionCode.NE); break; case Opcode.fbult: RewriteFbcc(ConditionCode.LT); break; case Opcode.fbun: RewriteFbcc(ConditionCode.IS_NAN); break; case Opcode.fcmp: RewriteFcmp(); break; case Opcode.fdiv: RewriteFBinOp((s, d) => m.FDiv(d, s)); break; case Opcode.fmove: RewriteFmove(); break; case Opcode.fmovecr: RewriteFmovecr(); break; case Opcode.fmovem: RewriteMovem(i => arch.GetRegister(i + Registers.fp0.Number)); break; case Opcode.fmul: RewriteFBinOp((s, d) => m.FMul(d, s)); break; case Opcode.fneg: RewriteFUnaryOp(m.Neg); break; case Opcode.fsub: RewriteFBinOp((s, d) => m.FSub(d, s)); break; case Opcode.jmp: RewriteJmp(); break; case Opcode.jsr: RewriteJsr(); break; case Opcode.lea: RewriteLea(); break; case Opcode.link: RewriteLink(); break; case Opcode.lsl: RewriteShift((s, d) => m.Shl(d, s)); break; case Opcode.lsr: RewriteShift((s, d) => m.Shr(d, s)); break; case Opcode.move: RewriteMove(true); break; case Opcode.movea: RewriteMove(false); break; case Opcode.movep: RewriteMovep(); break; case Opcode.moveq: RewriteMoveq(); break; case Opcode.movem: RewriteMovem(arch.GetRegister); break; case Opcode.muls: RewriteMul((s, d) => m.SMul(d, s)); break; case Opcode.mulu: RewriteMul((s, d) => m.UMul(d, s)); break; case Opcode.neg: RewriteUnary(s => m.Neg(s), AllConditions); break; case Opcode.negx: RewriteUnary(RewriteNegx, AllConditions); break; case Opcode.nop: m.Nop(); break; case Opcode.not: RewriteUnary(s => m.Comp(s), LogicalConditions); break; case Opcode.or: RewriteLogical((s, d) => m.Or(d, s)); break; case Opcode.ori: RewriteLogical((s, d) => m.Or(d, s)); break; case Opcode.pea: RewritePea(); break; case Opcode.rol: RewriteRotation(PseudoProcedure.Rol); break; case Opcode.ror: RewriteRotation(PseudoProcedure.Ror); break; case Opcode.roxl: RewriteRotationX(PseudoProcedure.RolC); break; case Opcode.roxr: RewriteRotationX(PseudoProcedure.RorC); break; case Opcode.rts: RewriteRts(); break; case Opcode.scc: RewriteScc(ConditionCode.UGE, FlagM.CF); break; case Opcode.scs: RewriteScc(ConditionCode.ULT, FlagM.CF); break; case Opcode.seq: RewriteScc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.sge: RewriteScc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Opcode.sgt: RewriteScc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.shi: RewriteScc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Opcode.sle: RewriteScc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.slt: RewriteScc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break; case Opcode.sls: RewriteScc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break; case Opcode.smi: RewriteScc(ConditionCode.LT, FlagM.NF); break; case Opcode.sne: RewriteScc(ConditionCode.NE, FlagM.ZF); break; case Opcode.spl: RewriteScc(ConditionCode.GT, FlagM.NF); break; case Opcode.st: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.True()); break; case Opcode.sf: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.False()); break; case Opcode.stop: RewriteStop(); break; case Opcode.sub: RewriteArithmetic((s, d) => m.ISub(d, s)); break; case Opcode.suba: RewriteArithmetic((s, d) => m.ISub(d, s)); break; case Opcode.subi: RewriteArithmetic((s, d) => m.ISub(d, s)); break; case Opcode.subq: RewriteAddSubq((s, d) => m.ISub(d, s)); break; case Opcode.subx: RewriteArithmetic((s, d) => m.ISub(m.ISub(d, s), binder.EnsureFlagGroup(Registers.ccr, (uint)FlagM.XF, "X", PrimitiveType.Bool))); break; case Opcode.swap: RewriteSwap(); break; case Opcode.trap: RewriteTrap(); break; case Opcode.tst: RewriteTst(); break; case Opcode.unlk: RewriteUnlk(); break; } yield return(new RtlInstructionCluster( addr, len, rtlInstructions.ToArray()) { Class = rtlc }); } yield break; }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { var instr = dasm.Current; this.iclass = instr.InstructionClass; switch (instr.Mnemonic) { default: EmitUnitTest(instr); goto case Mnemonic.Invalid; case Mnemonic.Invalid: m.Invalid(); iclass = InstrClass.Invalid; break; case Mnemonic.add: RewriteAdd(instr); break; case Mnemonic.adds: RewriteAdds(instr); break; case Mnemonic.addx: RewriteAddxSubx(instr, m.IAdd); break; case Mnemonic.and: RewriteLogical(instr, m.And); break; case Mnemonic.bld: RewriteBtst(instr, C); break; case Mnemonic.bset: RewriteBset(instr, Constant.True()); break; case Mnemonic.bst: RewriteBset(instr, binder.EnsureFlagGroup(C)); break; case Mnemonic.btst: RewriteBtst(instr, Z); break; case Mnemonic.bra: RewriteBranch(instr); break; case Mnemonic.brn: RewriteNop(); break; case Mnemonic.bhi: RewriteBranch(instr, ConditionCode.UGT, ZC); break; case Mnemonic.bls: RewriteBranch(instr, ConditionCode.ULE, ZC); break; case Mnemonic.bcc: RewriteBranch(instr, ConditionCode.UGE, C); break; case Mnemonic.bcs: RewriteBranch(instr, ConditionCode.ULT, C); break; case Mnemonic.bne: RewriteBranch(instr, ConditionCode.NE, Z); break; case Mnemonic.beq: RewriteBranch(instr, ConditionCode.EQ, Z); break; case Mnemonic.bvc: RewriteBranch(instr, ConditionCode.NO, V); break; case Mnemonic.bvs: RewriteBranch(instr, ConditionCode.OV, V); break; case Mnemonic.bpl: RewriteBranch(instr, ConditionCode.GE, N); break; case Mnemonic.bmi: RewriteBranch(instr, ConditionCode.LT, N); break; case Mnemonic.bge: RewriteBranch(instr, ConditionCode.GE, NV); break; case Mnemonic.blt: RewriteBranch(instr, ConditionCode.LT, NV); break; case Mnemonic.bgt: RewriteBranch(instr, ConditionCode.GT, NZV); break; case Mnemonic.ble: RewriteBranch(instr, ConditionCode.LE, NZV); break; case Mnemonic.cmp: RewriteCmp(instr); break; case Mnemonic.extu: RewriteExt(instr, Domain.UnsignedInt); break; case Mnemonic.jmp: RewriteJmp(instr); break; case Mnemonic.jsr: RewriteJsr(instr); break; case Mnemonic.ldc: RewriteLdc(instr); break; case Mnemonic.mov: RewriteMov(instr); break; case Mnemonic.mulxu: RewriteMulxu(instr); break; case Mnemonic.nop: RewriteNop(); break; case Mnemonic.not: RewriteUnaryLogical(instr, m.Comp); break; case Mnemonic.or: RewriteLogical(instr, m.Or); break; case Mnemonic.rotxl: RewriteRotationX(instr, PseudoProcedure.RolC); break; case Mnemonic.rotxr: RewriteRotationX(instr, PseudoProcedure.RorC); break; case Mnemonic.rts: RewriteRts(); break; case Mnemonic.shal: RewriteShift(instr, m.Shl); break; case Mnemonic.shar: RewriteShift(instr, m.Sar); break; case Mnemonic.shll: RewriteShift(instr, m.Shl); break; case Mnemonic.shlr: RewriteShift(instr, m.Shr); break; case Mnemonic.sub: RewriteSub(instr); break; case Mnemonic.subs: RewriteSubs(instr); break; case Mnemonic.subx: RewriteAddxSubx(instr, m.ISub); break; case Mnemonic.xor: RewriteLogical(instr, m.Xor); break; } yield return(m.MakeCluster(instr.Address, instr.Length, iclass)); this.m = new RtlEmitter(new List <RtlInstruction>()); } }
private void SetCc(Expression e) { var cc = binder.EnsureFlagGroup(Registers.CC); m.Assign(cc, e); }
private Identifier FlagGroup(FlagM flags) { return(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.psw, (uint)flags))); }
public void EmitCc(Expression exp, string szhvnc) { // SZIH XVNC var mask = 1u << 7; uint grf = 0; foreach (var c in szhvnc) { switch (c) { case '*': case 'S': case 'Z': case 'I': case 'H': case 'X': case 'V': case 'N': case 'C': grf |= mask; break; case '0': m.Assign( binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, mask)), Constant.False()); break; case '1': m.Assign( binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, mask)), Constant.True()); break; } mask >>= 1; } if (grf != 0) { m.Assign( binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, grf)), m.Cond(exp)); } }
private void EmitFlags(Expression e, FlagM mod = 0, FlagM clr = 0, FlagM set = 0) { if (mod != 0) { var grf = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.sreg, (uint)mod)); m.Assign(grf, m.Cond(e)); } if (clr != 0) { uint grfMask = 1; while (grfMask <= (uint)clr) { if ((grfMask & (uint)clr) != 0) { var grf = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.sreg, grfMask)); m.Assign(grf, 0); } grfMask <<= 1; } } if (set != 0) { uint grfMask = 1; while (grfMask <= (uint)set) { if ((grfMask & (uint)set) != 0) { var grf = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.sreg, grfMask)); m.Assign(grf, 1); } grfMask <<= 1; } } }
private void CV(Identifier dst) { var cv = binder.EnsureFlagGroup(arch.GetFlagGroup((uint)(FlagM.CY | FlagM.OV))); m.Assign(cv, m.Cond(dst)); }
private void NZV_(Expression e) { var grf = arch.GetFlagGroup(Registers.ccr, (uint)(FlagM.NF | FlagM.ZF | FlagM.VF)); m.Assign(binder.EnsureFlagGroup(grf), m.Cond(e)); }
private void RewriteBinop(Func <Expression, Expression, BinaryExpression> fn, FlagGroupStorage grf = null) { var dst = OpSrc(instr.Operands[0], arch.DataMemory); var src = OpSrc(instr.Operands[1], arch.DataMemory); m.Assign(dst, fn(dst, src)); if (grf != null) { m.Assign(binder.EnsureFlagGroup(grf), m.Cond(dst)); } }
public Expression VisitFlagGroupStorage(FlagGroupStorage grf) { return(binder.EnsureFlagGroup(grf.FlagRegister, grf.FlagGroupBits, grf.Name, grf.DataType)); }
public void AddFlagGroupReturnValue(KeyValuePair <RegisterStorage, uint> bits, IStorageBinder binder) { var grf = arch.GetFlagGroup(bits.Key, bits.Value) !; ret = binder.EnsureFlagGroup(grf); }
private void Assign(FlagGroupStorage grf, Expression e) { m.Assign(binder.EnsureFlagGroup(grf), e); }
private Identifier NZCV() { return(binder.EnsureFlagGroup(Registers.NZCV)); }
private void C(Expression e) { var carry = binder.EnsureFlagGroup(Registers.C); m.Assign(carry, m.Cond(e)); }
private void EmitCc(FlagGroupStorage grf, Expression exp) { m.Assign(binder.EnsureFlagGroup(grf), m.Cond(exp)); }
private Identifier FlagGroup(FlagGroupStorage flags) { return(binder.EnsureFlagGroup(flags)); }
public Identifier FlagGroup(FlagGroupStorage flags) => binder.EnsureFlagGroup(flags);
private void ClrCc(Expression e) { m.Assign(binder.EnsureFlagGroup(Registers.N), Constant.False()); m.Assign(binder.EnsureFlagGroup(Registers.Z), Constant.True()); m.Assign(binder.EnsureFlagGroup(Registers.V), Constant.False()); m.Assign(binder.EnsureFlagGroup(Registers.C), Constant.False()); }
protected Identifier FlagGroup(FlagM flags) => binder.EnsureFlagGroup(PICRegisters.STATUS, (uint)flags, arch.GrfToString((uint)flags), PrimitiveType.Byte);
private void CNZ(Expression e) { var cnz = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.st, (uint)FlagM.CNZ)); m.Assign(cnz, m.Cond(e)); }
private void RewriteBinop(Func <Expression, Expression, BinaryExpression> fn, FlagM grf) { var dst = OpSrc(instr.Operands[0]); var src = OpSrc(instr.Operands[1]); m.Assign(dst, fn(dst, src)); if (grf != 0) { var flg = arch.GetFlagGroup(Registers.PSW, (uint)grf); m.Assign(binder.EnsureFlagGroup(flg), m.Cond(dst)); } }
private Identifier C() { return(binder.EnsureFlagGroup(Registers.C)); }
private Identifier NZCV() { var nzcv = arch.GetFlagGroup((uint)(FlagM.NF | FlagM.ZF | FlagM.CF | FlagM.VF)); return(binder.EnsureFlagGroup(nzcv)); }
private Expression Rol(Expression a, Expression b) { var C = binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.ccr, (uint)FlagM.CF)); var intrinsic = host.Intrinsic(IntrinsicProcedure.RolC, true, a.DataType, a, b, C); return(intrinsic); }
public Identifier FlagGroup(FlagM flags) { return(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, (uint)flags))); }
public Identifier FlagGroup(FlagM flags) { return(binder.EnsureFlagGroup(arch.GetFlagGroup((uint)flags)));; }
private void ClrCc(Expression e) { m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.CC, (uint)FlagM.N)), Constant.False()); m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.CC, (uint)FlagM.Z)), Constant.True()); m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.CC, (uint)FlagM.V)), Constant.False()); m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.CC, (uint)FlagM.C)), Constant.False()); }