private void RewriteCom(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op1, src, m.Comp); SetFlags(dst, FlagM.NF | FlagM.ZF, FlagM.VF, FlagM.CF); }
private void RewriteAsr(Pdp11Instruction instr) { var src = Constant.Int16(1); var dst = RewriteDst(instr.op1, src, m.Sar); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteBit(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op2, src, m.And); SetFlags(dst, FlagM.NF | FlagM.ZF, FlagM.VF, 0); }
private void RewriteNeg(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op1, src, m.Neg); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF, 0, 0); }
private void RewriteShift(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var immSrc = src as Constant; Func <Expression, Expression, Expression> fn = null; if (immSrc != null) { int sh = immSrc.ToInt32(); if (sh < 0) { fn = m.Sar; src = Constant.Int16((short)-sh); } else { fn = m.Shl; src = Constant.Int16((short)sh); } } else { fn = (a, b) => host.PseudoProcedure("__shift", instr.DataWidth, a, b); } var dst = RewriteDst(instr.op2, src, fn); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteIncDec(Pdp11Instruction instr, Func <Expression, int, Expression> fn) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op1, src, s => fn(s, 1)); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF, 0, 0); }
private void RewriteBic(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op2, src, (a, b) => m.And(a, m.Comp(b))); SetFlags(dst, FlagM.NF | FlagM.ZF, FlagM.VF, 0); }
private void RewriteEmt(Pdp11Instruction instr) { this.rtlCluster.Class = RtlClass.Transfer; var imm = ((ImmediateOperand)instr.op1).Value.ToByte(); var svc = m.Word16((ushort)(0x8800 | imm)); m.SideEffect(host.PseudoProcedure(PseudoProcedure.Syscall, VoidType.Instance, svc)); }
public override Pdp11Instruction Decode(ushort opcode, Pdp11Disassembler dasm) { foreach (var m in mutators) { if (!m(opcode, dasm)) { return new Pdp11Instruction { Opcode = Opcode.illegal, IClass = InstrClass.Invalid, } } ; } var instr = new Pdp11Instruction { Opcode = this.opcode, IClass = iclass, DataWidth = dasm.dataWidth, op1 = dasm.ops.Count > 0 ? dasm.ops[0] : null, op2 = dasm.ops.Count > 1 ? dasm.ops[1] : null, }; return(instr); } }
private void RewriteAdc(Pdp11Instruction instr) { var src = frame.EnsureFlagGroup(this.arch.GetFlagGroup((uint)FlagM.CF)); var dst = RewriteDst(instr.op1, src, m.IAdd); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteAdd(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op2, src, m.IAdd); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteJmp(Pdp11Instruction instr) { this.rtlCluster.Class = RtlClass.Transfer; var jmpDst = RewriteJmpSrc(instr.op1); m.Goto(jmpDst); }
private void RewriteStcdi(Pdp11Instruction instr) { var src = m.Cast(PrimitiveType.Int32, RewriteSrc(instr.op1)); var dst = RewriteDst(instr.op2, src, s => s); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.CF, FlagM.VF, 0); }
private void RewriteCmp(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteSrc(instr.op2); var tmp = frame.CreateTemporary(src.DataType); emitter.Assign(tmp, emitter.ISub(dst, src)); SetFlags(tmp, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteBxx(Pdp11Instruction instr, ConditionCode cc, FlagM flags) { this.rtlCluster.Class = RtlClass.Transfer; m.Branch( m.Test(cc, frame.EnsureFlagGroup(arch.GetFlagGroup((uint)flags))), ((AddressOperand)instr.op1).Address, RtlClass.ConditionalTransfer); }
private void RewriteRol(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op1, src, (a, b) => host.PseudoProcedure(PseudoProcedure.Rol, instr.DataWidth, a, b)); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteCmp(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteSrc(instr.op2); var tmp = frame.CreateTemporary(src.DataType); m.Assign(tmp, m.ISub(dst, src)); SetFlags(tmp, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteClr(Pdp11Instruction instr, Expression src) { var dst = RewriteDst(instr.Operands[0], src, s => s); SetFalse(Registers.C); SetFalse(Registers.V); SetFalse(Registers.N); SetTrue(Registers.Z); }
private void RewriteTst(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var tmp = frame.CreateTemporary(src.DataType); m.Assign(tmp, src); m.Assign(tmp, m.And(tmp, tmp)); SetFlags(tmp, FlagM.NF | FlagM.ZF, FlagM.VF | FlagM.CF, 0); }
private void RewriteSxt(Pdp11Instruction instr) { var n = frame.EnsureFlagGroup(this.arch.GetFlagGroup((uint)FlagM.NF)); var src = m.ISub(Constant.Int16(0), n); var dst = RewriteDst(instr.op1, src, s => s); SetFlags(dst, FlagM.ZF, 0, 0); }
private void RewriteJsr(Pdp11Instruction instr) { this.rtlCluster.Class = RtlClass.Transfer; var regLink = (RegisterOperand)instr.op1; //$TODO: do something with regLink. var callDst = RewriteJmpSrc(instr.op2); m.Call(callDst, 2); return; }
private void RewriteRts(Pdp11Instruction instr) { this.rtlCluster.Class = RtlClass.Transfer; var regLink = (RegisterOperand)instr.op1; if (regLink.Register == Registers.pc) { emitter.Return(2, 0); return; } throw new NotImplementedException(regLink.Register.Name); }
public Pdp11Rewriter( Pdp11Architecture arch, IEnumerable <Pdp11Instruction> instrs, IStorageBinder binder, IRewriterHost host) { this.arch = arch; this.dasm = instrs.GetEnumerator(); this.binder = binder; this.host = host; this.instr = null !; this.m = null !; this.rtlInstructions = null !; }
private void RewriteDiv(Pdp11Instruction instr) { var reg = ((RegisterOperand)instr.op2).Register; var reg1 = arch.GetRegister(reg.Number | 1); var reg_reg = frame.EnsureSequence(reg, reg1, PrimitiveType.Int32); var dividend = frame.CreateTemporary(PrimitiveType.Int32); var divisor = RewriteSrc(instr.op1); var quotient = frame.EnsureRegister(reg); var remainder = frame.EnsureRegister(reg1); m.Assign(dividend, reg_reg); m.Assign(quotient, m.SDiv(dividend, divisor)); m.Assign(remainder, m.Mod(dividend, divisor)); SetFlags(quotient, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteMov(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); Expression dst; if (instr.op2 is RegisterOperand && instr.DataWidth.Size == 1) { dst = RewriteDst(instr.op2, src, s => m.Cast(PrimitiveType.Int16, s)); } else { dst = RewriteDst(instr.op2, src, s => s); } SetFlags(dst, FlagM.ZF | FlagM.NF, FlagM.VF, 0); }
public override Pdp11Instruction Decode(uint uInstr, Pdp11Disassembler dasm) { foreach (var m in mutators) { if (!m(uInstr, dasm)) { return(dasm.CreateInvalidInstruction()); } } var instr = new Pdp11Instruction { Mnemonic = this.opcode, InstructionClass = iclass, DataWidth = dasm.dataWidth, Operands = dasm.ops.ToArray() }; return(instr); }
private void RewriteRts(Pdp11Instruction instr) { this.rtlCluster.Class = RtlClass.Transfer; var regLink = (RegisterOperand)instr.op1; if (regLink.Register == Registers.pc) { m.Return(2, 0); return; } else { var tmp = frame.CreateTemporary(regLink.Width); var sp = frame.EnsureRegister(Registers.sp); var reg = frame.EnsureRegister(regLink.Register); m.Assign(tmp, reg); m.Assign(reg, m.Load(regLink.Width, sp)); m.Assign(sp, m.IAdd(sp, reg.DataType.Size)); m.Call(tmp, 0); m.Return(0, 0); } }
private void RewriteClr(Pdp11Instruction instr, Expression src) { var dst = RewriteDst(instr.op1, src, s => s); SetFlags(dst, 0, FlagM.NF | FlagM.CF | FlagM.VF, FlagM.ZF); }
private void RewriteBic(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op2, src, (a, b) => emitter.And(a, emitter.Comp(b))); SetFlags(dst, FlagM.NF | FlagM.ZF, FlagM.VF, 0); }
private void RewriteBit(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op2, src, emitter.And); SetFlags(dst, FlagM.NF | FlagM.ZF, FlagM.VF, 0); }
private void RewriteAdc(Pdp11Instruction instr) { var src = frame.EnsureFlagGroup(this.arch.GetFlagGroup((uint)FlagM.CF)); var dst = RewriteDst(instr.op1, src, emitter.IAdd); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteAsl(Pdp11Instruction instr) { var src = Constant.Int16(1); var dst = RewriteDst(instr.op1, src, emitter.Shl); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteBr(Pdp11Instruction instr) { this.rtlCluster.Class = RtlClass.Transfer; m.Goto(((AddressOperand)instr.op1).Address); }
private void RewriteXor(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op2, src, m.Xor); SetFlags(dst, FlagM.ZF | FlagM.NF, FlagM.CF | FlagM.VF, 0); }
private void RewriteMov(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); Expression dst; if (instr.op2 is RegisterOperand && instr.DataWidth.Size == 1) { dst = RewriteDst(instr.op2, src, s => emitter.Cast(PrimitiveType.Int16, s)); } else { dst = RewriteDst(instr.op2, src, s => s); } SetFlags(dst, FlagM.ZF | FlagM.NF, FlagM.VF, 0); }
private void RewriteNeg(Pdp11Instruction instr) { var dst = RewriteDst(instr.op1, null, emitter.Neg); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF, 0, 0); }
private void RewriteIncDec(Pdp11Instruction instr, Func<Expression, int, Expression> fn) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op1, src, s => fn(s, 1)); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF, 0, 0); }
private void RewriteSxt(Pdp11Instruction instr) { var n = frame.EnsureFlagGroup(this.arch.GetFlagGroup((uint)FlagM.NF)); var src = emitter.ISub(Constant.Int16(0), n); var dst = RewriteDst(instr.op1, src, s => s); SetFlags(dst, FlagM.ZF, 0, 0); }
private void RewriteDiv(Pdp11Instruction instr) { var reg = ((RegisterOperand)instr.op2).Register; var reg1 = arch.GetRegister(reg.Number | 1); var reg_reg = frame.EnsureSequence(reg, reg1, PrimitiveType.Int32); var dividend = frame.CreateTemporary(PrimitiveType.Int32); var divisor = RewriteSrc(instr.op1); var quotient = frame.EnsureRegister(reg); var remainder = frame.EnsureRegister(reg1); emitter.Assign(dividend, reg_reg); emitter.Assign(quotient, emitter.SDiv(dividend, divisor)); emitter.Assign(remainder, emitter.Mod(dividend, divisor)); SetFlags(quotient, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
private void RewriteTst(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var tmp = frame.CreateTemporary(src.DataType); emitter.Assign(tmp, src); emitter.Assign(tmp, emitter.And(tmp, tmp)); SetFlags(tmp, FlagM.NF | FlagM.ZF, FlagM.VF | FlagM.CF, 0); }
private void RewriteShift(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var immSrc = src as Constant; Func<Expression, Expression, Expression> fn = null; if (immSrc != null) { int sh = immSrc.ToInt32(); if (sh < 0) { fn = emitter.Sar; src = Constant.Int16((short)-sh); } else { fn = emitter.Shl; src = Constant.Int16((short)sh); } } else { fn = (a, b) => host.PseudoProcedure("__shift", instr.DataWidth, a, b); } var dst = RewriteDst(instr.op2, src, fn); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; this.rtlInstructions = new List <RtlInstruction>(); this.iclass = instr.InstructionClass; m = new RtlEmitter(this.rtlInstructions); switch (instr.Mnemonic) { default: host.Warn( instr.Address, "PDP-11 instruction {0} is not supported yet.", instr.Mnemonic); iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.illegal: iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.adc: RewriteAdcSbc(m.IAdd); break; case Mnemonic.add: RewriteAdd(); break; case Mnemonic.addb: RewriteAdd(); break; case Mnemonic.ash: RewriteShift(); break; case Mnemonic.ashc: RewriteAshc(); break; case Mnemonic.asl: RewriteAsl(); break; case Mnemonic.aslb: RewriteAsl(); break; case Mnemonic.asr: RewriteAsr(); break; case Mnemonic.asrb: RewriteAsr(); break; case Mnemonic.bcc: RewriteBxx(ConditionCode.UGE, FlagM.CF); break; case Mnemonic.bcs: RewriteBxx(ConditionCode.ULT, FlagM.CF); break; case Mnemonic.beq: RewriteBxx(ConditionCode.EQ, FlagM.ZF); break; case Mnemonic.bge: RewriteBxx(ConditionCode.GE, FlagM.VF | FlagM.NF); break; case Mnemonic.bgt: RewriteBxx(ConditionCode.GT, FlagM.ZF | FlagM.NF | FlagM.VF); break; case Mnemonic.bhi: RewriteBxx(ConditionCode.UGT, FlagM.ZF | FlagM.CF); break; case Mnemonic.bvs: RewriteBxx(ConditionCode.OV, FlagM.VF); break; case Mnemonic.bic: RewriteBic(); break; case Mnemonic.bicb: RewriteBic(); break; case Mnemonic.bis: RewriteBis(); break; case Mnemonic.bisb: RewriteBis(); break; case Mnemonic.bit: RewriteBit(); break; case Mnemonic.bitb: RewriteBit(); break; case Mnemonic.ble: RewriteBxx(ConditionCode.LE, FlagM.ZF | FlagM.NF | FlagM.VF); break; case Mnemonic.blos: RewriteBxx(ConditionCode.ULE, FlagM.ZF | FlagM.CF); break; case Mnemonic.blt: RewriteBxx(ConditionCode.LT, FlagM.NF | FlagM.VF); break; case Mnemonic.bmi: RewriteBxx(ConditionCode.LT, FlagM.NF); break; case Mnemonic.bne: RewriteBxx(ConditionCode.NE, FlagM.ZF); break; case Mnemonic.bpl: RewriteBxx(ConditionCode.GT, FlagM.NF); break; case Mnemonic.bpt: RewriteBpt(); break; case Mnemonic.br: RewriteBr(); break; case Mnemonic.clr: RewriteClr(instr, m.Word16(0)); break; case Mnemonic.clrb: RewriteClr(instr, m.Byte(0)); break; case Mnemonic.clrflags: RewriteClrSetFlags(Constant.False); break; case Mnemonic.cmp: RewriteCmp(); break; case Mnemonic.cmpb: RewriteCmp(); break; case Mnemonic.com: RewriteCom(); break; case Mnemonic.comb: RewriteCom(); break; case Mnemonic.dec: RewriteIncDec(m.ISub); break; case Mnemonic.decb: RewriteIncDec(m.ISub); break; case Mnemonic.div: RewriteDiv(); break; case Mnemonic.emt: RewriteEmt(); break; case Mnemonic.halt: RewriteHalt(); break; case Mnemonic.iot: RewriteIot(); break; case Mnemonic.inc: RewriteIncDec(m.IAdd); break; case Mnemonic.incb: RewriteIncDec(m.IAdd); break; case Mnemonic.jmp: RewriteJmp(); break; case Mnemonic.jsr: RewriteJsr(); break; case Mnemonic.mark: RewriteMark(); break; case Mnemonic.mfpd: RewriteMfpd(); break; case Mnemonic.mfpi: RewriteMfpi(); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.movb: RewriteMov(); break; case Mnemonic.mtpi: RewriteMtpi(); break; case Mnemonic.mul: RewriteMul(); break; case Mnemonic.neg: RewriteNeg(); break; case Mnemonic.negb: RewriteNeg(); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.reset: RewriteReset(); break; case Mnemonic.rol: RewriteRotate(PseudoProcedure.Rol); break; case Mnemonic.rolb: RewriteRotate(PseudoProcedure.Rol); break; case Mnemonic.ror: RewriteRotate(PseudoProcedure.Ror); break; case Mnemonic.rorb: RewriteRotate(PseudoProcedure.Ror); break; case Mnemonic.rti: RewriteRti(); break; case Mnemonic.rts: RewriteRts(); break; case Mnemonic.rtt: RewriteRtt(); break; case Mnemonic.sbc: RewriteAdcSbc(m.ISub); break; case Mnemonic.sbcb: RewriteAdcSbc(m.ISub); break; case Mnemonic.setflags: RewriteClrSetFlags(Constant.True); break; case Mnemonic.stcdi: RewriteStcdi(); break; case Mnemonic.sob: RewriteSob(); break; case Mnemonic.stexp: RewriteStexp(); break; case Mnemonic.sub: RewriteSub(); break; case Mnemonic.swab: RewriteSwab(); break; case Mnemonic.sxt: RewriteSxt(); break; case Mnemonic.trap: RewriteTrap(); break; case Mnemonic.tst: RewriteTst(); break; case Mnemonic.tstb: RewriteTst(); break; case Mnemonic.wait: RewriteWait(); break; case Mnemonic.xor: RewriteXor(); break; } yield return(m.MakeCluster(instr.Address, instr.Length, iclass)); } }
private void RewriteSub(Pdp11Instruction instr) { var src = RewriteSrc(instr.op1); var dst = RewriteDst(instr.op2, src, emitter.ISub); SetFlags(dst, FlagM.NF | FlagM.ZF | FlagM.VF | FlagM.CF, 0, 0); }