Exemplo n.º 1
0
        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}.");
            }
        }
Exemplo n.º 2
0
        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);
        }