Ejemplo n.º 1
0
        private MemoryAccess RewriteMemoryAccess(MemoryOperand mem, PrimitiveType dataWidth, Address addrInstr)
        {
            Expression ea;

            if (mem.Base == Registers.pc)
            {
                ea = addrInstr + mem.Offset.ToInt32();
            }
            else
            {
                var bReg = binder.EnsureRegister(mem.Base);
                ea = bReg;
                if (mem.Offset != null)
                {
                    ea = m.IAdd(bReg, Constant.Int32(mem.Offset.ToInt32()));
                }
            }
            return(m.Mem(dataWidth, ea));
        }
Ejemplo n.º 2
0
        private bool TryParseOperandInner(ushort uInstr, byte addressMode, byte operandBits, PrimitiveType dataWidth, EndianImageReader rdr, out MachineOperand op)
        {
            Constant offset;

            switch (addressMode)
            {
            case 0: // Data register direct.
                op = DataRegisterOperand(operandBits, 0);
                return(true);

            case 1: // Address register direct
                op = new RegisterOperand(AddressRegister(operandBits, 0));
                return(true);

            case 2:  // Address register indirect
                op = MemoryOperand.Indirect(dataWidth, AddressRegister(operandBits, 0));
                return(true);

            case 3:  // Address register indirect with postincrement.
                op = MemoryOperand.PostIncrement(dataWidth, AddressRegister(operandBits, 0));
                return(true);

            case 4:  // Address register indirect with predecrement.
                op = MemoryOperand.PreDecrement(dataWidth, AddressRegister(operandBits, 0));
                return(true);

            case 5: // Address register indirect with displacement.
                if (!rdr.TryReadBe(PrimitiveType.Int16, out offset))
                {
                    op = null;
                    return(false);
                }
                op = MemoryOperand.Indirect(dataWidth, AddressRegister(operandBits, 0), offset);
                return(true);

            case 6: // Address register indirect with index
                return(TryAddressRegisterIndirectWithIndex(uInstr, dataWidth, rdr, out op));

            case 7:
                switch (operandBits)
                {
                case 0: // Absolute short address
                    ushort usAddr;
                    if (!rdr.TryReadBeUInt16(out usAddr))
                    {
                        op = null; return(false);
                    }
                    op = new M68kAddressOperand(usAddr);
                    return(true);

                case 1: // Absolute long address
                    uint uAddr;
                    if (!rdr.TryReadBeUInt32(out uAddr))
                    {
                        op = null; return(false);
                    }
                    op = new M68kAddressOperand(uAddr);
                    return(true);

                case 2: // Program counter with displacement
                    var   off = rdr.Address - dasm.instr.Address;
                    short sOffset;
                    if (!rdr.TryReadBeInt16(out sOffset))
                    {
                        op = null; return(false);
                    }
                    off += sOffset;
                    op   = new MemoryOperand(dataWidth, Registers.pc, Constant.Int16((short)off));
                    return(true);

                case 3:
                    // Program counter with index
                    var    addrExt = rdr.Address;
                    ushort extension;
                    if (!rdr.TryReadBeUInt16(out extension))
                    {
                        op = null; return(false);
                    }

                    if (EXT_FULL(extension))
                    {
                        if (EXT_EFFECTIVE_ZERO(extension))
                        {
                            op = new M68kImmediateOperand(Constant.Word32(0));
                            return(true);
                        }
                        Constant @base = null;
                        Constant outer = null;
                        if (EXT_BASE_DISPLACEMENT_PRESENT(extension))
                        {
                            @base = EXT_BASE_DISPLACEMENT_LONG(extension)
                                ? rdr.ReadBe(PrimitiveType.Word32)
                                : rdr.ReadBe(PrimitiveType.Int16);
                        }
                        if (EXT_OUTER_DISPLACEMENT_PRESENT(extension))
                        {
                            outer = EXT_OUTER_DISPLACEMENT_LONG(extension)
                                ? rdr.ReadBe(PrimitiveType.Word32)
                                : rdr.ReadBe(PrimitiveType.Int16);
                        }
                        RegisterStorage base_reg = EXT_BASE_REGISTER_PRESENT(extension)
                            ? Registers.pc
                            : null;
                        RegisterStorage index_reg   = null;
                        PrimitiveType   index_width = null;
                        int             index_scale = 0;
                        if (EXT_INDEX_REGISTER_PRESENT(extension))
                        {
                            index_reg = EXT_INDEX_AR(extension)
                                ? Registers.AddressRegister((int)EXT_INDEX_REGISTER(extension))
                                : Registers.DataRegister((int)EXT_INDEX_REGISTER(extension));
                            index_width = EXT_INDEX_LONG(extension) ? PrimitiveType.Word32 : PrimitiveType.Int16;
                            index_scale = (EXT_INDEX_SCALE(extension) != 0)
                                ? 1 << EXT_INDEX_SCALE(extension)
                                : 0;
                        }
                        op = new IndexedOperand(dataWidth, @base, outer, base_reg, index_reg, index_width, index_scale,
                                                (extension & 7) > 0 && (extension & 7) < 4,
                                                (extension & 7) > 4);
                        return(true);
                    }
                    op = new IndirectIndexedOperand(
                        dataWidth,
                        EXT_8BIT_DISPLACEMENT(extension),
                        Registers.pc,
                        EXT_INDEX_AR(extension)
                            ? Registers.AddressRegister((int)EXT_INDEX_REGISTER(extension))
                            : Registers.DataRegister((int)EXT_INDEX_REGISTER(extension)),
                        EXT_INDEX_LONG(extension)
                            ? PrimitiveType.Word32
                            : PrimitiveType.Int16,
                        1 << EXT_INDEX_SCALE(extension));
                    return(true);

                case 4:
                    //  Immediate
                    if (dataWidth.Size == 1)        // don't want the instruction stream to get misaligned!
                    {
                        rdr.Offset += 1;
                    }
                    Constant coff;
                    if (!rdr.TryReadBe(dataWidth, out coff))
                    {
                        op = null; return(false);
                    }
                    op = new M68kImmediateOperand(coff);
                    return(true);

                default:
                    op = null;
                    return(false);
                }

            default:
                throw new NotImplementedException(string.Format("Address mode {0:X1} not implemented.", addressMode));
            }
        }