private Expression OpSrc(MachineOperand op, RegisterStorage?dataMemory) { switch (op) { case RegisterOperand reg: return(binder.EnsureRegister(reg.Register)); case FlagGroupOperand flg: return(binder.EnsureFlagGroup(flg.FlagGroup)); case ImmediateOperand imm: return(imm.Value); case AddressOperand addr: return(addr.Address); case MemoryOperand mem: Expression ea; if (mem.DirectAddress != null) { if (mem.Index != null) { ea = m.IAdd(mem.DirectAddress, binder.EnsureRegister(mem.Index)); } else if (mem.DirectAddress is Constant c) { var alias = AliasedSpecialFunctionRegister(c.ToUInt16()); if (alias != null) { return(alias); } ea = c; } else { ea = mem.DirectAddress; } } else if (mem.Register != null) { if (mem.Index != null) { var idx = binder.EnsureRegister(mem.Index); if (mem.Register == Registers.PC) { ea = m.IAdd( instr.Address + instr.Length, idx); } else { ea = binder.EnsureIdentifier(mem.Register); ea = m.IAdd(ea, idx); } } else { ea = binder.EnsureIdentifier(mem.Register); } } else { throw new NotImplementedException(); } if (dataMemory != null) { return(m.SegMem(mem.Width, binder.EnsureRegister(dataMemory), ea)); } else { return(m.Mem(mem.Width, ea)); } case BitOperand bit: Expression e = binder.EnsureRegister(bit.Register); if (bit.Bit > 0) { e = m.Shr(e, (byte)bit.Bit); } e = m.And(e, 1); if (bit.Negated) { e = m.Not(e); } return(e); case SequenceOperand seq: return(binder.EnsureSequence(seq.Sequence.DataType, seq.Sequence.Name, seq.Sequence.Elements)); default: throw new NotImplementedException($"Not implemented {op.GetType().Name}."); } }
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); }