private void RewriteDacDsb(string intrinsicName) { var opLeft = Operand(instr.Operands[0]); var opRight = Operand(instr.Operands[0]); var c = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.st, (uint)FlagM.CF)); m.Assign(c, host.PseudoProcedure( intrinsicName, PrimitiveType.Bool, opLeft, opRight, c, m.Out(opLeft.DataType, opLeft))); CNZ(opLeft); }
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.PseudoProcedure( "__bit", 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 OperandDst(MachineOperand op, Action <Expression, Expression> write, Expression src) { switch (op) { case RegisterOperand rop: write(binder.EnsureRegister(rop.Register), src); return; case MemoryOperand mem: write(RewriteMemoryOperand(mem), src); MaybeEmitIncrement(mem); return; case RegisterPairOperand pair: write(binder.EnsureSequence(PrimitiveType.Word64, pair.HighRegister, pair.LowRegister), src); return; case DecoratorOperand dec: if (dec.Width.BitSize < dec.Operand.Width.BitSize) { var dst = binder.EnsureRegister(((RegisterOperand)dec.Operand).Register); var dt = PrimitiveType.CreateWord(32 - dec.Width.BitSize); if (dec.BitOffset == 0) { var hi = m.Slice(dt, dst, dec.Width.BitSize); write(dst, m.Seq(hi, src)); } else { var lo = m.Slice(dt, dst, 0); write(dst, m.Seq(src, lo)); } return; } break; case ApplicationOperand app: var appOps = app.Operands.Select(OperandSrc).Concat(new[] { src }).ToArray(); m.SideEffect(host.PseudoProcedure(app.Mnemonic.ToString(), VoidType.Instance, appOps)); return; } throw new NotImplementedException($"Hexagon rewriter for {op.GetType().Name} not implemented yet."); }
private void RewriteFninit() { var ppp = host.PseudoProcedure("__fninit", VoidType.Instance); m.SideEffect(ppp); }
private void RewriteBrk() { m.SideEffect(host.PseudoProcedure("__brk", VoidType.Instance)); }
private Expression Rol(Expression a, Expression b) { var intrinsic = host.PseudoProcedure(PseudoProcedure.RolC, a.DataType, a, b); return(intrinsic); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { rtlc = new RtlInstructionCluster(dasm.Current.Address, dasm.Current.Length); rtlc.Class = RtlClass.Linear; emitter = new RtlEmitter(rtlc.Instructions); switch (dasm.Current.Code) { default: throw new AddressCorrelatedException( dasm.Current.Address, "Rewriting of Z80 instruction '{0}' not implemented yet.", dasm.Current.Code); case Opcode.adc: RewriteAdc(); break; case Opcode.add: RewriteAdd(); break; case Opcode.and: RewriteAnd(); break; case Opcode.bit: RewriteBit(); break; case Opcode.call: RewriteCall(dasm.Current); break; case Opcode.ccf: RewriteCcf(); break; case Opcode.cp: RewriteCp(); break; case Opcode.cpd: RewriteCp(emitter.ISub, false); break; case Opcode.cpdr: RewriteCp(emitter.ISub, true); break; case Opcode.cpi: RewriteCp(emitter.IAdd, false); break; case Opcode.cpir: RewriteCp(emitter.IAdd, true); break; case Opcode.cpl: RewriteCpl(); break; case Opcode.di: RewriteDi(); break; case Opcode.daa: RewriteDaa(); break; case Opcode.dec: RewriteDec(); break; case Opcode.djnz: RewriteDjnz(dasm.Current.Op1); break; case Opcode.ei: RewriteEi(); break; case Opcode.ex: RewriteEx(); break; case Opcode.exx: RewriteExx(); break; case Opcode.hlt: emitter.SideEffect(host.PseudoProcedure("__hlt", VoidType.Instance)); break; case Opcode.@in: RewriteIn(); break; case Opcode.ind: RewriteIn(emitter.ISub, false); break; case Opcode.indr: RewriteIn(emitter.ISub, true); break; case Opcode.ini: RewriteIn(emitter.IAdd, false); break; case Opcode.inir: RewriteIn(emitter.IAdd, true); break; case Opcode.im: emitter.SideEffect(host.PseudoProcedure("__im", VoidType.Instance, RewriteOp(dasm.Current.Op1))); break; case Opcode.inc: RewriteInc(); break; case Opcode.jp: RewriteJp(dasm.Current); break; case Opcode.jr: RewriteJr(); break; case Opcode.ld: emitter.Assign( RewriteOp(dasm.Current.Op1), RewriteOp(dasm.Current.Op2)); break; case Opcode.rl: RewriteRotation(PseudoProcedure.RolC, true); break; case Opcode.rla: RewriteRotation(PseudoProcedure.Rol, false); break; case Opcode.rlc: RewriteRotation(PseudoProcedure.RolC, false); break; case Opcode.rlca: RewriteRotation(PseudoProcedure.RolC, false); break; case Opcode.rr: RewriteRotation(PseudoProcedure.RorC, true); break; case Opcode.rra: RewriteRotation(PseudoProcedure.Ror, true); break; case Opcode.rrc: RewriteRotation(PseudoProcedure.RorC, true); break; case Opcode.rrca: RewriteRotation(PseudoProcedure.RorC, true); break; case Opcode.ldd: RewriteBlockInstruction(emitter.ISub, false); break; case Opcode.lddr: RewriteBlockInstruction(emitter.ISub, true); break; case Opcode.ldi: RewriteBlockInstruction(emitter.IAdd, false); break; case Opcode.ldir: RewriteBlockInstruction(emitter.IAdd, true); break; case Opcode.neg: RewriteNeg(); break; case Opcode.nop: emitter.Nop(); break; case Opcode.or: RewriteOr(); break; case Opcode.@out: RewriteOut(); break; case Opcode.pop: RewritePop(); break; case Opcode.push: RewritePush(dasm.Current); break; case Opcode.res: RewriteResSet("__res"); break; case Opcode.ret: RewriteRet(); break; case Opcode.rst: RewriteRst(); break; case Opcode.sbc: RewriteSbc(); break; case Opcode.scf: RewriteScf(); break; case Opcode.set: RewriteResSet("__set"); break; case Opcode.sla: RewriteShift(dasm.Current, emitter.Shl); break; case Opcode.sra: RewriteShift(dasm.Current, emitter.Sar); break; case Opcode.srl: RewriteShift(dasm.Current, emitter.Shr); break; case Opcode.sub: RewriteSub(); break; case Opcode.xor: RewriteXor(); break; //$TODO: Not implemented yet; feel free to implement these! case Opcode.ex_af: goto default; case Opcode.otdr: goto default; case Opcode.otir: goto default; case Opcode.outd: goto default; case Opcode.outi: goto default; case Opcode.outr: goto default; case Opcode.reti: goto default; case Opcode.retn: goto default; case Opcode.rld: goto default; case Opcode.rrd: goto default; case Opcode.swap: goto default; } yield return(rtlc); } }
private Expression Dadd(Expression a, Expression b) { return(host.PseudoProcedure("__dadd", a.DataType, a, b)); }
private void RewriteRotate(string rot) { var dst = OpSrc(instr.Operand1); m.Assign(dst, host.PseudoProcedure(rot, dst.DataType, dst, m.Byte(1))); }
private Expression Rol1(Expression e) { return(host.PseudoProcedure(PseudoProcedure.Rol, e.DataType, e, Constant.Byte(1))); }
private void ParseStatement() { if (!EatSpaces()) { return; } byte b = line[i++]; switch ((Token)b) { case Token.END: var c = new ProcedureCharacteristics { Terminates = true }; var ppp = host.PseudoProcedure("__End", c, VoidType.Instance); m.SideEffect(ppp); i = line.Length; // We never return from end. return; case Token.CLOSE: RewriteClose(); break; case Token.CLR: RewriteClr(); break; case Token.FOR: RewriteFor(); break; case Token.GET: RewriteGet(); break; case Token.GOSUB: RewriteGosub(); break; case Token.GOTO: RewriteGoto(); break; case Token.IF: RewriteIf(); break; case Token.INPUT: RewriteInput(); break; case Token.INPUT_hash: RewriteInput_hash(); break; case Token.NEXT: RewriteNext(); break; case Token.OPEN: RewriteOpen(); break; case Token.POKE: RewritePoke(); break; case Token.PRINT: RewritePrint(); break; case Token.PRINT_hash: RewritePrint_hash(); break; case Token.REM: //$TODO: annotation i = line.Length; return; case Token.RETURN: RewriteReturn(); break; case Token.SYS: RewriteSys(); break; case Token.COLON: // Statement separator. break; default: if (0x41 <= b && b <= 0x5A) { --i; RewriteLet(); break; } throw new NotImplementedException(string.Format( "Unimplemented BASIC token {0:X2} [{1}].", (int)line[i - 1], C64BasicInstruction.TokenToString(b))); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { var addr = dasm.Current.Address; var len = dasm.Current.Length; this.rtlc = dasm.Current.InstructionClass; var rtlInstructions = new List <RtlInstruction>(); m = new RtlEmitter(rtlInstructions); switch (dasm.Current.Mnemonic) { default: throw new AddressCorrelatedException( dasm.Current.Address, "Z80 instruction '{0}' is not supported yet.", dasm.Current.Mnemonic); case Mnemonic.illegal: m.Invalid(); break; case Mnemonic.adc: RewriteAdc(); break; case Mnemonic.add: RewriteAdd(); break; case Mnemonic.and: RewriteAnd(); break; case Mnemonic.bit: RewriteBit(); break; case Mnemonic.call: RewriteCall(dasm.Current); break; case Mnemonic.ccf: RewriteCcf(); break; case Mnemonic.cp: RewriteCp(); break; case Mnemonic.cpd: RewriteCp(m.ISub, false); break; case Mnemonic.cpdr: RewriteCp(m.ISub, true); break; case Mnemonic.cpi: RewriteCp(m.IAdd, false); break; case Mnemonic.cpir: RewriteCp(m.IAdd, true); break; case Mnemonic.cpl: RewriteCpl(); break; case Mnemonic.di: RewriteDi(); break; case Mnemonic.daa: RewriteDaa(); break; case Mnemonic.dec: RewriteDec(); break; case Mnemonic.djnz: RewriteDjnz(dasm.Current.Operands[0]); break; case Mnemonic.ei: RewriteEi(); break; case Mnemonic.ex: RewriteEx(); break; case Mnemonic.ex_af: RewriteExAf(); break; case Mnemonic.exx: RewriteExx(); break; case Mnemonic.hlt: RewriteHlt(); break; case Mnemonic.@in: RewriteIn(); break; case Mnemonic.ind: RewriteIn(m.ISub, false); break; case Mnemonic.indr: RewriteIn(m.ISub, true); break; case Mnemonic.ini: RewriteIn(m.IAdd, false); break; case Mnemonic.inir: RewriteIn(m.IAdd, true); break; case Mnemonic.im: m.SideEffect(host.PseudoProcedure("__im", VoidType.Instance, RewriteOp(dasm.Current.Operands[0]))); break; case Mnemonic.inc: RewriteInc(); break; case Mnemonic.jp: RewriteJp(dasm.Current); break; case Mnemonic.jr: RewriteJr(); break; case Mnemonic.ld: RewriteLd(); break; case Mnemonic.rl: RewriteRotation(PseudoProcedure.RolC, true); break; case Mnemonic.rla: RewriteRotation(PseudoProcedure.RolC, true); break; case Mnemonic.rlc: RewriteRotation(PseudoProcedure.Rol, false); break; case Mnemonic.rlca: RewriteRotation(PseudoProcedure.Rol, false); break; case Mnemonic.rr: RewriteRotation(PseudoProcedure.RorC, true); break; case Mnemonic.rra: RewriteRotation(PseudoProcedure.RorC, true); break; case Mnemonic.rrc: RewriteRotation(PseudoProcedure.Ror, true); break; case Mnemonic.rrca: RewriteRotation(PseudoProcedure.Ror, true); break; case Mnemonic.ldd: RewriteBlockInstruction(m.ISub, false); break; case Mnemonic.lddr: RewriteBlockInstruction(m.ISub, true); break; case Mnemonic.ldi: RewriteBlockInstruction(m.IAdd, false); break; case Mnemonic.ldir: RewriteBlockInstruction(m.IAdd, true); break; case Mnemonic.neg: RewriteNeg(); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.or: RewriteOr(); break; case Mnemonic.@out: RewriteOut(); break; case Mnemonic.pop: RewritePop(); break; case Mnemonic.push: RewritePush(dasm.Current); break; case Mnemonic.res: RewriteResSet("__res"); break; case Mnemonic.ret: RewriteRet(); break; case Mnemonic.rst: RewriteRst(); break; case Mnemonic.sbc: RewriteSbc(); break; case Mnemonic.scf: RewriteScf(); break; case Mnemonic.set: RewriteResSet("__set"); break; case Mnemonic.sla: RewriteShift(dasm.Current, m.Shl); break; case Mnemonic.sra: RewriteShift(dasm.Current, m.Sar); break; case Mnemonic.srl: RewriteShift(dasm.Current, m.Shr); break; case Mnemonic.sub: RewriteSub(); break; case Mnemonic.xor: RewriteXor(); break; //$TODO: Not implemented yet; feel free to implement these! case Mnemonic.otdr: goto default; case Mnemonic.otir: goto default; case Mnemonic.outd: goto default; case Mnemonic.outi: goto default; case Mnemonic.outr: goto default; case Mnemonic.reti: goto default; case Mnemonic.retn: goto default; case Mnemonic.rld: goto default; case Mnemonic.rrd: goto default; case Mnemonic.swap: goto default; } yield return(new RtlInstructionCluster(addr, len, rtlInstructions.ToArray()) { Class = rtlc }); } }
private void RewriteCsync() { m.SideEffect(host.PseudoProcedure("__csync", VoidType.Instance)); }
private Expression Operand(MachineOperand op) { var rop = op as RegisterOperand; if (rop != null) { return(frame.EnsureRegister(rop.Register)); } var immOp = op as ImmediateOperand; if (immOp != null) { return(immOp.Value); } var shOp = op as ShiftOperand; if (shOp != null) { var r = Operand(shOp.Operand); var sh = Operand(shOp.Shift); switch (shOp.Opcode) { case Opcode.lsl: return(emitter.Shl(r, sh)); case Opcode.lsr: return(emitter.Shr(r, sh)); case Opcode.asr: return(emitter.Sar(r, sh)); case Opcode.ror: return(host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, r, sh)); default: throw new NotSupportedException(string.Format("Unsupported shift operation {0}.", shOp.Opcode)); } } var memOp = op as ArmMemoryOperand; if (memOp != null) { Expression baseReg = frame.EnsureRegister(memOp.Base); Expression ea = baseReg; if (memOp.Base.Number == 0x0F) // PC-relative address { var imm = memOp.Offset as ArmImmediateOperand; if (imm != null) { if (memOp.Writeback) { throw new NotImplementedException(); } var dst = (uint)((int)instr.Address.ToUInt32() + imm.Value.ToInt32()) + 8u; return(emitter.Load(memOp.Width, Address.Ptr32(dst))); } } if (memOp.Offset != null && memOp.Preindexed) { var offset = Operand(memOp.Offset); ea = memOp.Subtract ? emitter.ISub(ea, offset) : emitter.IAdd(ea, offset); } if (memOp.Preindexed && memOp.Writeback) { emitter.Assign(baseReg, ea); ea = baseReg; } return(emitter.Load(memOp.Width, ea)); } throw new NotSupportedException(string.Format("Unsupported operand {0}.", op)); }
private void RewriteBrk() { rtlc = RtlClass.Linear; m.SideEffect(host.PseudoProcedure("__brk", VoidType.Instance)); }