Esempio n. 1
0
        private bool TryDecodeOperand(PrimitiveType width, out MachineOperand op)
        {
            op = null;
            byte   b;
            byte   bSpecifier;
            ushort w;
            uint   dw;

            if (!rdr.TryReadByte(out bSpecifier))
            {
                return(false);
            }
            var reg = arch.GetRegister(bSpecifier & 0xF);

            switch (bSpecifier >> 4)
            {
            case 0: // Literal mode
            case 1:
            case 2:
            case 3:
                op = LiteralOperand(width, bSpecifier);
                break;

            case 4: // Index mode
                op = IndexOperand(width, reg);
                break;

            case 5: // Register mode
                op = new RegisterOperand(reg);
                break;

            case 6: // Register deferred
                op = new MemoryOperand(width)
                {
                    Base = reg
                };
                break;

            case 7: // Autodecrement mode
                op = new MemoryOperand(width)
                {
                    Base          = reg,
                    AutoDecrement = true,
                };
                break;

            case 8: // Autoincrement mode
                if (reg.Number == 0x0F)
                {
                    op = ImmediateOperand(width);
                }
                else
                {
                    op = new MemoryOperand(width)
                    {
                        Base          = reg,
                        AutoIncrement = true,
                    };
                }
                break;

            case 9: // Deferred Autoincrement mode
                op = new MemoryOperand(width)
                {
                    Base          = reg,
                    AutoIncrement = true,
                    Deferred      = true,
                };
                break;

            case 0xA: // Displacement mode
            case 0xD:
                if (!rdr.TryReadByte(out b))
                {
                    return(false);
                }
                op = DisplacementOperand(width, reg, Constant.SByte((sbyte)b), bSpecifier);
                break;

            case 0xB:
            case 0xE:
                if (!rdr.TryReadUInt16(out w))
                {
                    return(false);
                }
                op = DisplacementOperand(width, reg, Constant.Int16((short)w), bSpecifier);
                break;

            case 0xC:
            case 0xF:
                if (!rdr.TryReadUInt32(out dw))
                {
                    return(false);
                }
                op = DisplacementOperand(width, reg, Constant.Word32(dw), bSpecifier);
                break;

            default:
                throw new InvalidCastException("Impossiburu!");
            }
            return(true);
        }
Esempio n. 2
0
        private bool CompareOp(MachineOperand opA, MachineOperand opB)
        {
            if (opA == null && opB == null)
            {
                return(true);
            }
            if (opA == null || opB == null)
            {
                return(false);
            }
            if (opA.GetType() != opB.GetType())
            {
                return(false);
            }
            var regOpA = opA as RegisterOperand;

            if (regOpA != null)
            {
                if (NormalizeRegisters)
                {
                    return(true);
                }
                var regOpB = (RegisterOperand)opB;
                return(regOpA.Register == regOpB.Register);
            }
            var immOpA = opA as ImmediateOperand;

            if (immOpA != null)
            {
                if (NormalizeConstants)
                {
                    return(true);
                }
                var immOpB = (ImmediateOperand)opB;
                return(CompareValues(immOpA.Value, immOpB.Value));
            }
            var addrOpA = opA as AddressOperand;

            if (addrOpA != null)
            {
                if (NormalizeConstants)
                {
                    return(true);
                }
                var addrOpB = (AddressOperand)opB;
                return(addrOpA.Address.ToLinear() == addrOpB.Address.ToLinear());
            }
            var condOpA = opA as ConditionOperand;

            if (condOpA != null)
            {
                return(condOpA.Code == ((ConditionOperand)opB).Code);
            }
            var memOpA = opA as MemoryOperand;

            if (memOpA != null)
            {
                var memOpB = (MemoryOperand)opB;
                if (NormalizeRegisters && !CompareRegisters(memOpA.Base, memOpB.Base))
                {
                    return(false);
                }
                if (NormalizeConstants && !CompareValues(memOpA.Offset, memOpB.Offset))
                {
                    return(false);
                }
                return(true);
            }
            throw new NotImplementedException();
        }
Esempio n. 3
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 = default !;
                    return(false);
                }
                op = MemoryOperand.Indirect(dataWidth, AddressRegister(operandBits, 0), offset);
                return(true);
Esempio n. 4
0
 private Expression SrcOp(MachineOperand opSrc)
 {
     return(orw.Transform(instrCur, opSrc, opSrc.Width, state));
 }
Esempio n. 5
0
        private Expression DstOp(MachineOperand op, Expression src, Func <Expression, Expression> fn)
        {
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                var id = binder.EnsureRegister(regOp.Register);
                m.Assign(id, fn(src));
                return(id);
            }
            var mem = op as MemoryOperand;

            if (mem != null)
            {
                Identifier r0;
                Identifier gbr;
                Identifier reg;
                var        tmp = binder.CreateTemporary(op.Width);
                switch (mem.mode)
                {
                case AddressingMode.Indirect:
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(
                        m.Load(mem.Width, reg),
                        fn(src));
                    return(null);

                case AddressingMode.IndirectDisplacement:
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(
                        m.Load(mem.Width, m.IAdd(reg, Constant.Int32(mem.disp))),
                        fn(src));
                    return(null);

                case AddressingMode.IndirectPreDecr:
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(reg, m.ISub(reg, Constant.Int32(mem.Width.Size)));
                    m.Assign(
                        m.Load(tmp.DataType, reg),
                        fn(src));
                    return(null);

                case AddressingMode.IndexedIndirect:
                    m.Assign(
                        m.Load(mem.Width, m.IAdd(
                                   binder.EnsureRegister(Registers.r0),
                                   binder.EnsureRegister(mem.reg))),
                        fn(src));
                    return(null);

                case AddressingMode.GbrIndexedIndirect:
                    r0  = binder.EnsureRegister(Registers.r0);
                    gbr = binder.EnsureRegister(Registers.gbr);
                    m.Assign(tmp, m.Load(tmp.DataType, m.IAdd(r0, gbr)));
                    m.Assign(
                        m.Load(tmp.DataType, m.IAdd(r0, gbr)),
                        fn(src));
                    return(tmp);

                default: throw new NotImplementedException(mem.mode.ToString());
                }
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Esempio n. 6
0
        private bool Compare(MachineOperand a, MachineOperand b)
        {
            if (a == null && b == null)
            {
                return(true);
            }
            if (a == null || b == null)
            {
                return(false);
            }
            if (a.GetType() != b.GetType())
            {
                return(false);
            }
            var rA = a as RegisterOperand;

            if (rA != null)
            {
                if (NormalizeRegisters)
                {
                    return(true);
                }
                var rB = (RegisterOperand)b;
                return(rA.Register == rB.Register);
            }
            var iA = a as ImmediateOperand;

            if (iA != null)
            {
                if (NormalizeConstants)
                {
                    return(true);
                }
                var iB = (ImmediateOperand)b;
                return(CompareValues(iA.Value, iB.Value));
            }
            var aA = a as AddressOperand;

            if (aA != null)
            {
                if (NormalizeConstants)
                {
                    return(true);
                }
                var aB = (AddressOperand)b;
                return(aA.Address.ToLinear() == aB.Address.ToLinear());
            }
            var mA = a as IndirectOperand;

            if (mA != null)
            {
                var mB = (IndirectOperand)b;
                if (!NormalizeRegisters && mA.Base != mB.Base)
                {
                    return(false);
                }
                if (!NormalizeConstants && mA.Offset != mB.Offset)
                {
                    return(false);
                }
                return(true);
            }
            throw new NotImplementedException();
        }
        private bool Compare(MachineOperand opA, MachineOperand opB)
        {
            if (opA == null && opB == null)
            {
                return(true);
            }
            if (opA == null || opB == null)
            {
                return(false);
            }

            if (opA.GetType() != opB.GetType())
            {
                return(false);
            }
            if (opA is RegisterOperand regA)
            {
                var regB = (RegisterOperand)opB;
                return(NormalizeRegisters || regA.Register == regB.Register);
            }
            if (opA is M68kImmediateOperand immA)
            {
                var immB = (M68kImmediateOperand)opB;
                return(CompareValues(immA.Constant, immB.Constant));
            }
            if (opA is PredecrementMemoryOperand preA)
            {
                var preB = (PredecrementMemoryOperand)opB;
                return(CompareRegisters(preA.Register, preB.Register));
            }
            if (opA is PostIncrementMemoryOperand postA)
            {
                var postB = (PostIncrementMemoryOperand)opB;
                return(CompareRegisters(postA.Register, postB.Register));
            }
            if (opA is RegisterSetOperand regsetA)
            {
                var regsetB = (RegisterSetOperand)opB;
                return(NormalizeRegisters || regsetA.BitSet == regsetB.BitSet);
            }
            if (opA is MemoryOperand memA)
            {
                var memB = (MemoryOperand)opB;
                if (!NormalizeRegisters && !CompareRegisters(memA.Base, memB.Base))
                {
                    return(false);
                }
                return(NormalizeConstants || CompareValues(memA.Offset, memB.Offset));
            }
            if (opA is M68kAddressOperand addrA)
            {
                var addrB = (M68kAddressOperand)opB;
                return(NormalizeConstants || addrA.Address == addrB.Address);
            }
            if (opA is IndirectIndexedOperand idxA)
            {
                var idxB = (IndirectIndexedOperand)opB;
                if (!NormalizeRegisters)
                {
                    if (!CompareRegisters(idxA.ARegister, idxB.ARegister))
                    {
                        return(false);
                    }
                    if (!CompareRegisters(idxA.XRegister, idxB.XRegister))
                    {
                        return(false);
                    }
                }
                if (!NormalizeConstants)
                {
                    if (idxA.Imm8 != idxB.Imm8)
                    {
                        return(false);
                    }
                    if (idxA.Scale != idxB.Scale)
                    {
                        return(false);
                    }
                }
                return(true);
            }
            throw new NotImplementedException(opA.GetType().FullName);
        }
Esempio n. 8
0
 private void Branch(ConditionCode code, MachineOperand op)
 {
     this.iclass = InstrClass.ConditionalTransfer;
     m.Branch(m.Test(code, orw.AluRegister(Registers.FPUF)), OperandAsCodeAddress(op)!, InstrClass.ConditionalTransfer);
 }
Esempio n. 9
0
 private Identifier Reg(MachineOperand op)
 {
     return(binder.EnsureRegister(((RegisterOperand)op).Register));
 }
Esempio n. 10
0
 private int OperandHash(MachineOperand op)
 {
     if (op == null)
     {
         return(0);
     }
     if (op is RegisterOperand rop)
     {
         if (NormalizeRegisters)
         {
             return(0);
         }
         else
         {
             return(rop.Register.GetHashCode());
         }
     }
     if (op is M68kImmediateOperand immop)
     {
         if (NormalizeConstants)
         {
             return(0);
         }
         else
         {
             return(immop.Constant.GetHashCode());
         }
     }
     if (op is M68kAddressOperand addrOp)
     {
         if (NormalizeConstants)
         {
             return(0);
         }
         else
         {
             return(addrOp.Address.GetHashCode());
         }
     }
     if (op is MemoryOperand memOp)
     {
         int h = 0;
         if (!NormalizeConstants && memOp.Offset != null)
         {
             h = memOp.Offset.GetHashCode();
         }
         if (!NormalizeRegisters)
         {
             h = h * 9 ^ memOp.Base.GetHashCode();
         }
         return(h);
     }
     if (op is IndirectIndexedOperand ind)
     {
         int h = 0;
         if (!NormalizeConstants)
         {
             h = ind.Imm8.GetHashCode();
             h = h * 11 ^ ind.Scale.GetHashCode();
             h = h * 13 ^ ind.Imm8.GetHashCode();
         }
         if (!NormalizeRegisters)
         {
             h = h * 5 ^ ind.ARegister.GetHashCode();
             h = h * 17 ^ ind.XRegister.GetHashCode();
         }
         return(h);
     }
     if (op is PredecrementMemoryOperand pre)
     {
         int h = 43;
         if (!NormalizeRegisters)
         {
             h = h * 5 ^ base.GetRegisterHash(pre.Register);
         }
         return(h);
     }
     if (op is PostIncrementMemoryOperand post)
     {
         int h = 47;
         if (!NormalizeRegisters)
         {
             h = h * 7 ^ base.GetRegisterHash(post.Register);
         }
         return(h);
     }
     if (op is RegisterSetOperand regset)
     {
         int h = 29;
         if (!NormalizeRegisters)
         {
             h = h ^ regset.BitSet.GetHashCode();
         }
         return(h);
     }
     if (op is IndexedOperand indexOp)
     {
         int h = 53;
         if (!NormalizeRegisters)
         {
             if (indexOp.Base != null)
             {
                 h = h * 7 ^ GetRegisterHash(indexOp.Base);
             }
             if (indexOp.Index != null)
             {
                 h = h * 11 ^ GetRegisterHash(indexOp.Index);
                 h = h * 13 ^ indexOp.index_reg_width !.GetHashCode();
             }
         }
         if (!NormalizeConstants)
         {
             if (indexOp.BaseDisplacement != null)
             {
                 h = h * 17 ^ indexOp.BaseDisplacement.GetHashCode();
             }
             if (indexOp.IndexScale != 0)
             {
                 h = h * 19 ^ indexOp.IndexScale;
             }
         }
         return(h);
     }
     throw new NotImplementedException();
 }
Esempio n. 11
0
 private Constant Imm(MachineOperand op)
 {
     return(((ImmediateOperand)op).Value);
 }
Esempio n. 12
0
 private Address Addr(MachineOperand op)
 {
     return(((AddressOperand)op).Address);
 }
Esempio n. 13
0
        private RegisterStorage GetRegister(MachineOperand op)
        {
            var rOp = op as RegisterOperand;

            return(rOp?.Register);
        }
Esempio n. 14
0
        // Zero-extend an operand known to be unsigned immediate.
        private Constant RewriteUimm(MachineOperand op)
        {
            var iOp = (ImmediateOperand)op;

            return(Constant.UInt32(iOp.Value.ToUInt32()));
        }
Esempio n. 15
0
 private bool ImplicitWidth(MachineOperand op)
 {
     return(op is RegisterOperand || op is X86AddressOperand);
 }
Esempio n. 16
0
 public DecoratorOperand(DataType width, MachineOperand op) : base(width)
 {
     this.Operand = op;
 }
Esempio n. 17
0
        protected virtual (FSRIndexedMode indMode, Expression memPtr) GetMemFileAccess(MachineOperand opernd)
        {
            switch (opernd)
            {
            case PICOperandBankedMemory bnkmem:
                var offset = bnkmem.Offset;
                if (PICRegisters.TryGetAlwaysAccessibleRegister(offset, out var regsrc))
                {
                    var srciopr = PICRegisters.IndirectOpMode(regsrc, out PICRegisterStorage indsrcreg);
                    if (srciopr != FSRIndexedMode.None)
                    {
                        return(srciopr, binder.EnsureRegister(indsrcreg));
                    }
                    return(FSRIndexedMode.None, binder.EnsureRegister(regsrc));
                }
                return(FSRIndexedMode.None, DataBankMem8(Bsr, Constant.Byte(offset)));

            case PICOperandRegister reg:
                var iopr = PICRegisters.IndirectOpMode(reg.Register, out PICRegisterStorage indreg);
                if (iopr != FSRIndexedMode.None)
                {
                    return(iopr, binder.EnsureRegister(indreg));
                }
                return(iopr, binder.EnsureRegister(reg.Register));

            default:
                throw new InvalidOperationException($"Invalid PIC instruction's memory operand: {opernd}");
            }
        }
Esempio n. 18
0
        private Expression SrcOp(MachineOperand op, Func <int, int> immediateFn = null)
        {
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                var id = binder.EnsureRegister(regOp.Register);
                return(id);
            }
            var immOp = op as ImmediateOperand;

            if (immOp != null)
            {
                return(Constant.Word32(immediateFn(immOp.Value.ToInt32())));
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                return(addrOp.Address);
            }
            var mem = op as MemoryOperand;

            if (mem != null)
            {
                Identifier reg;
                switch (mem.mode)
                {
                default:
                    throw new NotImplementedException(mem.mode.ToString());

                case AddressingMode.Indirect:
                    return(m.Load(mem.Width, binder.EnsureRegister(mem.reg)));

                case AddressingMode.IndirectPreDecr:
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(reg, m.IAdd(reg, Constant.Int32(mem.Width.Size)));
                    return(m.Load(mem.Width, reg));

                case AddressingMode.IndirectPostIncr:
                    var t = binder.CreateTemporary(mem.Width);
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(t, m.Load(mem.Width, reg));
                    m.Assign(reg, m.IAdd(reg, Constant.Int32(t.DataType.Size)));
                    return(t);

                case AddressingMode.IndirectDisplacement:
                    reg = binder.EnsureRegister(mem.reg);
                    return(m.Load(
                               mem.Width,
                               m.IAdd(reg, Constant.Int32(mem.disp))));

                case AddressingMode.IndexedIndirect:
                    return(m.Load(mem.Width, m.IAdd(
                                      binder.EnsureRegister(Registers.r0),
                                      binder.EnsureRegister(mem.reg))));

                case AddressingMode.PcRelativeDisplacement:
                    var addr = instr.Address.ToUInt32();
                    if (mem.Width.Size == 4)
                    {
                        addr &= ~3u;
                    }
                    addr += (uint)(mem.disp + 4);
                    return(m.Load(mem.Width, Address.Ptr32(addr)));
                }
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Esempio n. 19
0
 protected override (FSRIndexedMode indMode, Expression memPtr) GetMemFileAccess(MachineOperand opernd)
 {
     if (opernd is PICOperandBankedMemory bankmemop && bankmemop.IsAccess)
     {
         var bankmem = PICMemoryDescriptor.CreateBankedAddr(bankmemop);
         if (PICMemoryDescriptor.CanBeFSR2IndexAddress(bankmem))
         {
             return(FSRIndexedMode.None, DataMem8(m.IAdd(Fsr2, bankmem.BankOffset)));  // Address is in the form [FSR2]+offset ("à la" Extended Execution mode).
         }
         if (PICMemoryDescriptor.TryGetAbsDataAddress(bankmem, out var absAddr))
         {
             if (PICRegisters.TryGetRegister(absAddr, out var sfr))
             {
                 var iop = PICRegisters.IndirectOpMode(sfr, out PICRegisterStorage fsrreg);
                 if (iop != FSRIndexedMode.None)
                 {
                     return(iop, binder.EnsureRegister(fsrreg));
                 }
                 return(iop, binder.EnsureRegister(sfr));
             }
             return(FSRIndexedMode.None, DataMem8(absAddr));
         }
     }
     return(base.GetMemFileAccess(opernd));
 }
Esempio n. 20
0
        private int GetHashCode(MachineOperand op)
        {
            if (op == null)
            {
                return(0);
            }
            var r = op as RegisterOperand;

            if (r != null)
            {
                if (NormalizeRegisters)
                {
                    return(0);
                }
                else
                {
                    return(GetRegisterHash(r.Register));
                }
            }
            var i = op as ImmediateOperand;

            if (i != null)
            {
                if (NormalizeConstants)
                {
                    return(0);
                }
                else
                {
                    return(GetConstantHash(i.Value));
                }
            }
            var a = op as AddressOperand;

            if (a != null)
            {
                if (NormalizeConstants)
                {
                    return(0);
                }
                else
                {
                    return(a.Address.GetHashCode());
                }
            }
            var m = op as IndirectOperand;

            if (m != null)
            {
                int h = 0;
                if (!NormalizeRegisters)
                {
                    h = GetRegisterHash(m.Base);
                }
                if (!NormalizeConstants)
                {
                    h ^= m.Offset.GetHashCode();
                }
                return(h);
            }
            return(42);
        }
Esempio n. 21
0
        private Expression?RewriteJmpSrc(MachineOperand op)
        {
            if (!(op is MemoryOperand memOp))
            {
                // PDP-11 always has a memory reference
                // for the destination of a transfer instruction.
                return(null);
            }
            var r = memOp.Register != null
                ? binder.EnsureRegister(memOp.Register)
                : null;

            var tmp = binder.CreateTemporary(op.Width);

            switch (memOp.Mode)
            {
            default:
                throw new AddressCorrelatedException(
                          dasm.Current.Address,
                          "Not implemented: addressing mode {0}.",
                          memOp.Mode);

            case AddressMode.RegDef:
                return(r !);

            case AddressMode.Absolute:
                return(Address.Ptr16(memOp.EffectiveAddress));

            case AddressMode.AutoIncr:
                m.Assign(tmp, m.Mem(PrimitiveType.Ptr16, r !));
                m.Assign(r !, m.IAdd(r !, memOp.Width.Size));
                break;

            case AddressMode.AutoIncrDef:
                m.Assign(tmp, m.Mem(op.Width, r !));
                m.Assign(r !, m.IAdd(r !, memOp.Width.Size));
                break;

            case AddressMode.AutoDecr:
                m.Assign(r !, m.ISub(r !, memOp.Width.Size));
                return(m.Mem(op.Width, r !));

            case AddressMode.AutoDecrDef:
                m.Assign(r !, m.ISub(r !, memOp.Width.Size));
                m.Assign(tmp, m.Mem(op.Width, m.Mem(PrimitiveType.Ptr16, r !)));
                return(tmp);

            case AddressMode.Indexed:
                if (memOp.Register == Registers.pc)
                {
                    var offset   = (short)memOp.EffectiveAddress;
                    var addrBase = (long)instr.Address.ToLinear();
                    var addr     = Address.Ptr16((ushort)(instr.Length + addrBase + offset));
                    return(addr);
                }
                else
                {
                    return(m.Mem(
                               this.dasm.Current.DataWidth !,
                               m.IAdd(r !, Constant.Word16(memOp.EffectiveAddress))));
                }

            case AddressMode.IndexedDef:
                if (memOp.Register == Registers.pc)
                {
                    var offset   = (short)memOp.EffectiveAddress;
                    var addrBase = (long)instr.Address.ToLinear() + instr.Length;
                    var addr     = m.Ptr16((ushort)(addrBase + offset));
                    return(m.Mem(
                               PrimitiveType.Word16,
                               addr));
                }
                else
                {
                    return(m.Mem(
                               PrimitiveType.Ptr16,
                               m.IAdd(r !, Constant.Word16(memOp.EffectiveAddress))));
                }
            }
            return(tmp);

            /*
             *  var immOp = op as ImmediateOperand;
             *  if (immOp != null)
             *  {
             *      return immOp.Value;
             *  }
             *  var addrOp = op as AddressOperand;
             *  if (addrOp != null)
             *  {
             *      return addrOp.Address;
             *  }
             *  throw new NotImplementedException();
             */
        }
Esempio n. 22
0
        public bool TryParseOperand(ushort opcode, int bitOffset, PrimitiveType dataWidth, EndianImageReader rdr, out MachineOperand op)
        {
            opcode >>= bitOffset;
            byte operandBits = (byte)(opcode & 7);
            byte addressMode = (byte)((opcode >> 3) & 7);

            return(TryParseOperandInner(opcode, addressMode, operandBits, dataWidth, rdr, out op));
        }
Esempio n. 23
0
        private Expression OpSrc(MachineOperand op)
        {
            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
                    {
                        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();
                }
                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}.");
            }
        }
Esempio n. 24
0
 private void RewriteConditionalGoto(ConditionCode cc, MachineOperand op1)
 {
     iclass = InstrClass.ConditionalTransfer;
     m.Branch(CreateTestCondition(cc, instrCur.Mnemonic), OperandAsCodeAddress(op1) !, InstrClass.ConditionalTransfer);
 }
Esempio n. 25
0
        private void WriteDst(MachineOperand op, Expression src)
        {
            switch (op)
            {
            case RegisterOperand reg:
                m.Assign(binder.EnsureRegister(reg.Register), src);
                break;

            case FlagGroupOperand flg:
                m.Assign(binder.EnsureFlagGroup(flg.FlagGroup), src);
                break;

            case MemoryOperand mem:
                Expression ea;
                if (mem.DirectAddress != null)
                {
                    if (mem.Index != null)
                    {
                        ea = m.IAdd(mem.DirectAddress, binder.EnsureRegister(mem.Index));
                    }
                    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();
                }
                m.Assign(m.Mem(mem.Width, ea), src);
                break;

            case BitOperand bit:
                if (bit.Bit > 0)
                {
                    src = m.Shl(src, (byte)bit.Bit);
                }
                var mask = (byte)~(1 << bit.Bit);
                var e    = binder.EnsureRegister(bit.Register);
                m.Assign(e, m.Or(m.And(e, mask), src));
                break;

            default:
                throw new NotImplementedException($"Not implemented {op.GetType().Name}.");
            }
        }
Esempio n. 26
0
 private Expression SrcOp(MachineOperand opSrc, PrimitiveType dstWidth)
 {
     return(orw.Transform(instrCur, opSrc, dstWidth, state));
 }
Esempio n. 27
0
 private bool HasImplicitWidth(MachineOperand op)
 {
     return(op is RegisterOperand || op is AddressOperand || op is FpuOperand);
 }
Esempio n. 28
0
 private Expression RewriteOp(MachineOperand op)
 {
     return(RewriteOp(op, false));
 }
Esempio n. 29
0
        private int HashOp(MachineOperand op)
        {
            if (op == null)
            {
                return(0);
            }
            int h     = op.GetType().GetHashCode();
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                if (NormalizeRegisters)
                {
                    return(h);
                }
                else
                {
                    return(h * 29 ^ regOp.Register.GetHashCode());
                }
            }
            var immOp = op as ImmediateOperand;

            if (immOp != null)
            {
                if (NormalizeConstants)
                {
                    return(h);
                }
                else
                {
                    return(h * 13 ^ GetConstantHash(immOp.Value));
                }
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                if (NormalizeConstants)
                {
                    return(h);
                }
                else
                {
                    return(h * 29 ^ addrOp.Address.GetHashCode());
                }
            }
            var condOp = op as ConditionOperand;

            if (condOp != null)
            {
                return(h * 19 ^ condOp.Code.GetHashCode());
            }
            var memOp = op as MemoryOperand;

            if (memOp != null)
            {
                if (!NormalizeRegisters && memOp.Base != null)
                {
                    h = h * 23 ^ memOp.Base.GetHashCode();
                }
                if (!NormalizeConstants && memOp.Offset != null)
                {
                    h = h * 17 ^ GetConstantHash(memOp.Offset);
                }
                return(h);
            }
            throw new NotImplementedException(string.Format("{0} ({1})", op, op.GetType().Name));
        }