예제 #1
0
        private MachineOperand Absolute(int addrBytes, PrimitiveType size)
        {
            uint uAddr = 0;
            int  sh    = 0;

            while (--addrBytes >= 0)
            {
                if (!rdr.TryReadByte(out byte b))
                {
                    return(null);
                }
                uAddr |= (uint)b << sh;
                sh    += 8;
            }
            SetSize(size);
            return(MemoryOperand.Absolute(size, uAddr));
        }
예제 #2
0
 // Predecrement
 private static Mutator <Tlcs900Disassembler> Pre(PrimitiveType size)
 {
     return((b, dasm) =>
     {
         if (!dasm.rdr.TryReadByte(out byte r))
         {
             return false;
         }
         var incCode = r & 3;
         if (incCode >= incDecSize.Length)
         {
             return false;
         }
         dasm.ops.Add(MemoryOperand.PreDecrement(dasm.Size(size), incDecSize[r & 3], dasm.Reg(PrimitiveType.Word32, (r >> 2) & 0x3F)));
         dasm.SetSize(size);
         return true;
     });
 }
예제 #3
0
        /// <summary>
        /// Rewrites the effective address of a memory load.
        /// </summary>
        /// <param name="mem"></param>
        /// <returns></returns>
        private Expression RewriteSrcEa(MemoryOperand mem)
        {
            Expression ea;

            if (mem.Base != null)
            {
                if (mem.Increment < 0)
                {
                    throw new NotImplementedException("predec");
                }
                ea = binder.EnsureRegister(mem.Base);
                if (mem.Offset != null)
                {
                    ea = m.IAdd(ea, mem.Offset);
                }
            }
            else
            {
                ea = arch.MakeAddressFromConstant(mem.Offset, false);
            }

            return(ea);
        }
예제 #4
0
        private MachineOperand DecodeOperand(byte b, string fmt)
        {
            MachineOperand op;
            byte           r;
            Constant       c;
            byte           o8;
            int            incCode;

            switch (fmt[0])
            {
            case '+': // Predecrement
                if (!rdr.TryReadByte(out r))
                {
                    return(null);
                }
                incCode = r & 3;
                if (incCode >= incDecSize.Length)
                {
                    return(null);
                }
                op = MemoryOperand.PostIncrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F));
                SetSize(fmt[1]);
                return(op);

            case '-':
                if (!rdr.TryReadByte(out r))
                {
                    return(null);
                }
                incCode = r & 3;
                if (incCode >= incDecSize.Length)
                {
                    return(null);
                }
                op = MemoryOperand.PreDecrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F));
                SetSize(fmt[1]);
                return(op);

            case '3': // Immediate encoded in low 3 bits
                c = Constant.Create(Size(fmt[1]), b & 7);
                SetSize(fmt[1]);
                return(new ImmediateOperand(c));

            case '#': // Immediate encoded in low 3 bits, with 8 encoded as 0
                c = Constant.Create(Size(fmt[1]), imm3Const[b & 7]);
                SetSize(fmt[1]);
                return(new ImmediateOperand(c));

            case 'A': // A register
                op = new RegisterOperand(Tlcs900Registers.a);
                return(op);

            case 'C': // condition code
                op = new ConditionOperand((CondCode)(b & 0xF));
                return(op);

            case 'I': // immediate
                op = Immediate(fmt[1]);
                return(op);

            case 'j': // Relative jump
                switch (fmt[1])
                {
                case 'b':
                    if (!rdr.TryReadByte(out o8))
                    {
                        return(null);
                    }
                    else
                    {
                        return(AddressOperand.Create(rdr.Address + (sbyte)o8));
                    }

                case 'w':
                    short o16;
                    if (!rdr.TryReadLeInt16(out o16))
                    {
                        return(null);
                    }
                    else
                    {
                        return(AddressOperand.Create(rdr.Address + o16));
                    }
                }
                return(null);

            case 'r': // Register
            case 'R':
                //$TODO: 'r' may encode other registers. manual is dense
                op = new RegisterOperand(Reg(fmt[1], b & 0x7));
                SetSize(fmt[1]);
                return(op);

            case 'M': // Register indirect
                op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', b & 7));
                SetSize(fmt[1]);
                return(op);

            case 'N': // indexed (8-bit offset)
                if (!rdr.TryReadByte(out o8))
                {
                    return(null);
                }
                op = MemoryOperand.Indexed8(Size(fmt[1]), Reg('x', b & 7), (sbyte)o8);
                SetSize(fmt[1]);
                return(op);

            case 'm': // various mem formats
                byte m;
                if (!rdr.TryReadByte(out m))
                {
                    return(null);
                }
                switch (m & 3)
                {
                case 0: // Register indirect
                    op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F));
                    break;

                case 1: // indexed (16-bit offset)
                    short o16;
                    if (!rdr.TryReadLeInt16(out o16))
                    {
                        return(null);
                    }
                    op = MemoryOperand.Indexed16(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F), o16);
                    SetSize(fmt[1]);
                    return(op);

                case 3:
                    if (m != 3 && m != 7)
                    {
                        return(null);
                    }
                    byte rBase;
                    if (!rdr.TryReadByte(out rBase))
                    {
                        return(null);
                    }
                    byte rIdx;
                    if (!rdr.TryReadByte(out rIdx))
                    {
                        return(null);
                    }
                    var regBase = Reg('x', rBase);
                    var regIdx  = Reg(m == 3 ? 'b' : 'w', rIdx);
                    op = MemoryOperand.RegisterIndexed(Size(fmt[1]), regBase, regIdx);
                    SetSize(fmt[1]);
                    return(op);

                default:
                    throw new FormatException(string.Format(
                                                  "Unknown format {0} decoding bytes {1:X2}{2:X2}.",
                                                  fmt[0], (int)b, (int)m));
                }
                SetSize(fmt[1]);
                return(op);

            case 'O': return(Absolute(1, fmt[1]));

            case 'P': return(Absolute(2, fmt[1]));

            case 'Q': return(Absolute(3, fmt[1]));

            default: throw new FormatException(
                          string.Format(
                              "Unknown format {0} decoding byte {1:X2}.", fmt[0], (int)b));
            }
        }