示例#1
0
        //Register with 6-bit immediate subtracted from PC
        private static bool ru6_m_pc(uint uInstr, XCore200Disassembler dasm)
        {
            var iReg = (uInstr >> 6) & 0xF;
            var imm  = uInstr & 0x3F;

            if ((imm & 1) != 0)
            {
                return(false);       // Illegal address.
            }
            var addr = dasm.addr - imm;

            dasm.ops.Add(new RegisterOperand(Registers.GpRegs[iReg]));
            dasm.ops.Add(AddressOperand.Create(addr));
            return(true);
        }
示例#2
0
        private static bool disp32(uint uInstr, V850Disassembler dasm)
        {
            if (!dasm.rdr.TryReadUInt16(out ushort dispLo))
            {
                return(false);
            }
            if (!dasm.rdr.TryReadUInt16(out ushort dispHi))
            {
                return(false);
            }
            var disp = (uint)(dispHi << 16) | dispLo;

            dasm.ops.Add(AddressOperand.Create(dasm.addr + (int)disp));
            return(true);
        }
示例#3
0
        private void RewritePush()
        {
            if (instrCur.Operands[0] is RegisterOperand reg && reg.Register == Registers.cs)
            {
                // Is it a 'push cs;call near XXXX' sequence that simulates a far call?
                if (dasm.Peek(1).Mnemonic == Mnemonic.call &&
                    dasm.Peek(1).Operands[0].Width.BitSize == 16)
                {
                    dasm.MoveNext();
                    MachineOperand targetOperand = dasm.Current.Operands[0];

                    if (targetOperand is ImmediateOperand immOperand)
                    {
                        targetOperand = AddressOperand.Create(orw.ImmediateAsAddress(instrCur.Address, immOperand));
                    }
                    else
                    {
                        m.Assign(StackPointer(), m.ISubS(StackPointer(), reg.Register.DataType.Size));
                    }

                    RewriteCall(targetOperand, targetOperand.Width);
                    this.len = (byte)(this.len + dasm.Current.Length);
                    return;
                }

                if (
                    dasm.Peek(1).Mnemonic == Mnemonic.push && (dasm.Peek(1).Operands[0] is ImmediateOperand) &&
                    dasm.Peek(2).Mnemonic == Mnemonic.push && (dasm.Peek(2).Operands[0] is ImmediateOperand) &&
                    dasm.Peek(3).Mnemonic == Mnemonic.jmp && (dasm.Peek(3).Operands[0] is AddressOperand))
                {
                    // That's actually a far call, but the callee thinks its a near call.
                    RewriteCall(dasm.Peek(3).Operands[0], instrCur.Operands[0].Width);
                    dasm.MoveNext();
                    dasm.MoveNext();
                    dasm.MoveNext();
                    return;
                }
            }
            var value = SrcOp(0, instrCur.dataWidth);

            Debug.Assert(
                value.DataType.BitSize == 16 ||
                value.DataType.BitSize == 32 ||
                value.DataType.BitSize == 64,
                $"Unexpected size {dasm.Current.dataWidth}");
            RewritePush(PrimitiveType.CreateWord(value.DataType.BitSize), value);
        }
示例#4
0
            public override AArch32Instruction Decode(uint wInstr, T32Disassembler dasm)
            {
                var s   = SBitfield(wInstr, 10 + 16, 1);
                var i1  = 1 & ~(SBitfield(wInstr, 13, 1) ^ s);
                var i2  = 1 & ~(SBitfield(wInstr, 11, 1) ^ s);
                var off = (int)Bits.SignExtend((uint)s, 1);

                off   = (off << 2) | (i1 << 1) | i2;
                off   = (off << 10) | SBitfield(wInstr, 16, 10);
                off   = (off << 11) | SBitfield(wInstr, 0, 11);
                off <<= 1;
                return(new T32Instruction
                {
                    Mnemonic = Mnemonic.bl,
                    Operands = new MachineOperand[] { AddressOperand.Create(dasm.addr + (off + 4)) }
                });
            }
示例#5
0
        private static Mutator <C166Disassembler> QQrrqFn()
        {
            var qqField = new Bitfield(8, 8);
            var qField  = new Bitfield(28, 4);
            var rrField = new Bitfield(16, 8);

            return((u, d) =>
            {
                if (!d.rdr.TryReadLeUInt16(out ushort hiword))
                {
                    return false;
                }
                u |= ((uint)hiword) << 16;
                var qq = Decode8bitReg(PrimitiveType.Word16, Registers.GpRegs, (int)qqField.Read(u));
                var q = (int)qField.Read(u);
                d.ops.Add(new BitOfOperand(q, qq));
                var offset = rrField.ReadSigned(u) << 1;
                var addr = d.rdr.Address + offset;
                d.ops.Add(AddressOperand.Create(addr));
                return true;
            });
        }
示例#6
0
        public AvrInstruction Decode(ushort wInstr, Opcode opcode, InstrClass iclass, string fmt)
        {
            var    ops = new List <MachineOperand>();
            int    offset;
            ushort w2;

            for (int i = 0; i < fmt.Length; ++i)
            {
                MachineOperand op;
                switch (fmt[i++])
                {
                case ',':
                    continue;

                case '+':
                    op = IncDec(true, fmt[i++]);
                    break;

                case '-':
                    op = IncDec(false, fmt[i++]);
                    break;

                case 'A': // I/O location
                    op = ImmediateOperand.Byte((byte)(((wInstr >> 5) & 0x30) | (wInstr & 0xF)));
                    break;

                case 'B': // 8-bit immediate at bits 8..11 and 0..3
                    op = ImmediateOperand.Byte((byte)(((wInstr >> 4) & 0xF0) | (wInstr & 0x0F)));
                    break;

                case 'g': // 4-bit field in sgis
                    op = ImmediateOperand.Byte((byte)((wInstr >> 3) & 0x0F));
                    break;

                case 'h': // 3-bit field in sgis, indicating bit nr.
                    op = ImmediateOperand.Byte((byte)(wInstr & 7));
                    break;

                case 'I': // 4-bit immediate at bit 0
                    op = ImmediateOperand.Byte((byte)(wInstr & 0x0F));
                    break;

                case 'i': // 4-bit immediate at bit 4
                    op = ImmediateOperand.Byte((byte)((wInstr >> 4) & 0x0F));
                    break;

                case 'J': // Relative jump
                    offset = (short)((wInstr & 0xFFF) << 4);
                    offset = offset >> 3;
                    op     = AddressOperand.Create(this.addr + 2 + offset);
                    break;

                case 'D': // Destination register
                    op = Register((wInstr >> 4) & 0x1F);
                    break;

                case 'd': // Destination register (r16-r31)
                    op = Register(0x10 | (wInstr >> 4) & 0x0F);
                    break;

                case 'R': // source register (5 bits)
                    op = Register((wInstr >> 5) & 0x10 | (wInstr) & 0x0F);
                    break;

                case 'r':
                    if (i < fmt.Length && fmt[i] == '4')
                    {
                        ++i;
                        // source register (r16-r31)
                        op = Register(0x10 | wInstr & 0x0F);
                    }
                    else
                    {
                        // source register (5 bits)
                        op = Register((wInstr >> 4) & 0x10 | (wInstr >> 4) & 0x0F);
                    }
                    break;

                case 'K':
                    op = ImmediateOperand.Byte((byte)(((wInstr >> 4) & 0xF0) | (wInstr & 0xF)));
                    break;

                case 'P': // register pair source
                    op = Register((wInstr << 1) & ~1);
                    break;

                case 'p': // register pair destination
                    op = Register((wInstr >> 3) & ~1);
                    break;

                case 'Q':   // absolute address used by jump and call.
                    if (!rdr.TryReadLeUInt16(out w2))
                    {
                        return(null);
                    }
                    op = AddressOperand.Ptr32(
                        (uint)(((wInstr >> 4) & 0x1F) << 18) |
                        (uint)((wInstr & 1) << 17) |
                        (uint)(w2 << 1));
                    break;

                case 'q':   // register pair used by adiw
                    op = Register(24 + ((wInstr >> 3) & 6));
                    break;

                case 's':   // immediate used by adiw/sbiw
                    op = ImmediateOperand.Byte((byte)(((wInstr >> 2) & 0x30) | (wInstr & 0xF)));
                    break;

                case 'w': // Trailing 16-bit absolute address
                    if (!rdr.TryReadLeUInt16(out w2))
                    {
                        return(null);
                    }
                    op = AddressOperand.Ptr16(w2);
                    break;

                case 'o':   // Branch offset
                    offset = (short)wInstr;
                    offset = (short)(offset << 6);
                    offset = (short)(offset >> 8);
                    offset = (short)(offset & ~1);
                    op     = AddressOperand.Create(this.addr + offset + 2);
                    break;

                case 'X':
                    op = MemD(arch.x, 0);
                    break;

                case 'Y':
                    op = MemD(arch.y, 0);
                    break;

                case 'y':
                    op = MemD(arch.y, Displacement(wInstr));
                    break;

                case 'Z':
                    op = MemD(arch.z, 0);
                    break;

                case 'z':
                    op = MemD(arch.z, Displacement(wInstr));
                    break;

                default:
                    throw new NotImplementedException(string.Format("Unimplemented AVR8 format symbol '{0}'.'", fmt[i - 1]));
                }
                ops.Add(op);
            }
            return(new AvrInstruction
            {
                opcode = opcode,
                iclass = iclass,
                operands = ops.ToArray(),
            });
        }
示例#7
0
 private static bool j(uint uInstr, SuperHDisassembler dasm)
 {
     dasm.state.ops.Add(AddressOperand.Create(dasm.rdr.Address + (2 + 2 * (sbyte)uInstr)));
     return(true);
 }
示例#8
0
        private Tms7000Instruction Decode(Opcode opcode, string format)
        {
            int iOp   = 0;
            var instr = new Tms7000Instruction
            {
                Opcode = opcode,
            };

            for (int i = 0; i < format.Length; ++i)
            {
                MachineOperand op;
                byte           b;
                ushort         w;
                switch (format[i])
                {
                case ',': continue;

                case 'A':
                    op = new RegisterOperand(arch.a);
                    break;

                case 'B':
                    op = new RegisterOperand(arch.b);
                    break;

                case 'R':
                    if (!rdr.TryReadByte(out b))
                    {
                        return(Invalid());
                    }
                    op = new RegisterOperand(arch.GpRegs[b]);
                    break;

                case 'P':
                    if (!rdr.TryReadByte(out b))
                    {
                        return(Invalid());
                    }
                    op = new RegisterOperand(arch.Ports[b]);
                    break;

                case 'S':
                    ;                   op = new RegisterOperand(arch.st);
                    break;

                case 'i':
                    if (!rdr.TryReadByte(out b))
                    {
                        return(Invalid());
                    }
                    op = ImmediateOperand.Byte(b);
                    break;

                case 'I':
                    if (!rdr.TryReadBeUInt16(out w))
                    {
                        return(Invalid());
                    }
                    op = ImmediateOperand.Word16(w);
                    break;

                case 'j':   // short PC-relative jump
                    if (!rdr.TryReadByte(out b))
                    {
                        return(Invalid());
                    }
                    op = AddressOperand.Create(rdr.Address + (sbyte)b);
                    break;

                case 'D':  // direct, absolute address
                    if (!rdr.TryReadBeUInt16(out w))
                    {
                        return(Invalid());
                    }
                    if (i < format.Length - 1 && format[i + 1] == 'B')
                    {
                        ++i;
                        op = MemoryOperand.Indexed(Address.Ptr16(w), arch.b);
                    }
                    else
                    {
                        op = MemoryOperand.Direct(Address.Ptr16(w));
                    }
                    break;

                case '*': // indirect
                    if (!rdr.TryReadByte(out b))
                    {
                        return(Invalid());
                    }
                    op = MemoryOperand.Indirect(arch.GpRegs[b]);
                    break;

                default: throw new NotImplementedException($"Addressing mode {format[i]}");
                }
                switch (iOp++)
                {
                case 0: instr.op1 = op; break;

                case 1: instr.op2 = op; break;

                case 2: instr.op3 = op; break;
                }
            }
            return(instr);
        }
示例#9
0
 private SuperHInstruction Decode(ushort uInstr, Opcode opcode, string format)
 {
     var ops = new MachineOperand[2];
     int iop = 0;
     RegisterStorage reg;
     PrimitiveType width;
     for (int i = 0; i < format.Length; ++i)
     {
         switch (format[i])
         {
         case ',':
             continue;
         case '-': // predecrement
             reg = Register(format[++i], uInstr);
             ops[iop] = MemoryOperand.IndirectPreDecr(GetWidth(format[++i]), reg);
             break;
         case '+': // postdecrement
             reg = Register(format[++i], uInstr);
             ops[iop] = MemoryOperand.IndirectPostIncr(GetWidth(format[++i]), reg);
             break;
         case 'd':
             ops[iop] = DfpRegister(format[++i], uInstr);
             break;
         case 'f':
             ops[iop] = FpRegister(format[++i], uInstr);
             break;
         case 'r':
             ops[iop] = new RegisterOperand(Register(format[++i], uInstr));
             break;
         case 'v':
             ops[iop] = VfpRegister(format[++i], uInstr);
             break;
         case 'I':
             ops[iop] = ImmediateOperand.Byte((byte)uInstr);
             break;
         case 'F':
             if (format[++i] == 'U')
             {
                 ops[iop] = new RegisterOperand(Registers.fpul);
                 break;
             }
             goto default;
         case 'G':
             ops[iop] = MemoryOperand.GbrIndexedIndirect(GetWidth(format[++i]));
             break;
         case '@':
             reg = Register(format[++i], uInstr);
             ops[iop] = MemoryOperand.Indirect(GetWidth(format[++i]), reg);
             break;
         case 'D':   // indirect with displacement
             reg = Register(format[++i], uInstr);
             width = GetWidth(format[++i]);
             ops[iop] = MemoryOperand.IndirectDisplacement(width, reg, (uInstr & 0xF) * width.Size);
             break;
         case 'X':   // indirect indexed
             reg = Register(format[++i], uInstr);
             ops[iop] = MemoryOperand.IndexedIndirect(GetWidth(format[++i]), reg);
             break;
         case 'P':   // PC-relative with displacement
             width = GetWidth(format[++i]);
             ops[iop] = MemoryOperand.PcRelativeDisplacement(width, width.Size * (byte)uInstr);
             break;
         case 'R':
             ++i;
             if (format[i] == 'P')
                 ops[iop] = new RegisterOperand(Registers.pr);
             else
                 ops[iop] = new RegisterOperand(Registers.gpregs[HexDigit(format[i]).Value]);
             break;
         case 'j':
             ops[iop] = AddressOperand.Create(rdr.Address + (2 + 2 * (sbyte)uInstr));
             break;
         case 'J':
             int offset = ((int)uInstr << 20) >> 19;
             ops[iop] = AddressOperand.Create(rdr.Address + (2 + offset));
             break;
         case 'm':   // Macl.
             if (i < format.Length-1)
             {
                 ++i;
                 if (format[i] == 'l')
                 {
                     ops[iop] = new RegisterOperand(Registers.macl);
                 }
                 else if (format[i] == 'h')
                 {
                     ops[iop] = new RegisterOperand(Registers.mach);
                 }
                 else
                 {
                     throw new NotImplementedException(string.Format("m{0}", format[i]));
                 }
             }
             else
             {
                 throw new NotImplementedException(string.Format("m{0}", format[i]));
             }
             break;
         default: throw new NotImplementedException(string.Format("SuperHDisassembler.Decode({0})", format[i]));
         }
         ++iop;
     }
     return new SuperHInstruction
     {
         Opcode = opcode,
         op1 = ops[0],
         op2 = ops[1],
     };
 }
示例#10
0
        private i8051Instruction Decode(Mnemonic opcode, byte uInstr, string fmt)
        {
            byte b;
            var  ops = new List <MachineOperand>();

            foreach (var ch in fmt)
            {
                switch (ch)
                {
                case ',':
                    continue;

                case 'j': // An 11-bit address destination. This argument is used by ACALL and AJMP instructions. The target of the CALL or JMP must lie within the same 2K page as the first byte of the following instruction.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(AddressOperand.Ptr16(
                                (ushort)(
                                    (rdr.Address.ToLinear() & ~0x7Ful) |
                                    (uInstr & 0xE0u) << 3 |
                                        b)));
                    break;

                case 'J':                                    // A 16-bit address destination. This argument is used by LCALL and LJMP instructions.
                    if (!rdr.TryReadBeUInt16(out var uAddr)) // Yes, big endian!
                    {
                        return(null);
                    }
                    ops.Add(AddressOperand.Ptr16(uAddr));
                    break;

                case 'o': // A signed (two's complement) 8-bit offset (-128 to 127) relative to the first byte of the following instruction.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(AddressOperand.Create(rdr.Address + (sbyte)b));
                    break;

                case 'A': // The accumulator.
                    ops.Add(new RegisterOperand(Registers.A));
                    break;

                case 'd': // An internal data RAM location (0-127) or SFR (128-255).
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(MemoryOperand.Direct(Address.Ptr16(b)));
                    break;

                case 'r': // Register r0-r7
                    ops.Add(Reg(uInstr & 7));
                    break;

                case 'b': // A direct addressed bit in internal data RAM or SFR memory.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(BitReg(b, false));
                    break;

                case 'B': // A direct addressed bit in internal data RAM or SFR memory.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(BitReg(b, true));
                    break;

                case 'C':   // C flag of PSW
                    ops.Add(new FlagGroupOperand(arch.GetFlagGroup(Registers.PSW, (uint)FlagM.C)));
                    break;

                case 'D':   // @DPTR
                    ops.Add(MemoryOperand.Indirect(Registers.DPTR));
                    break;

                case 'p':   // DPTR register pair
                    ops.Add(new SequenceOperand(Registers.DPTR));
                    break;

                case 'i': // A constant included in the instruction encoding.
                    if (!rdr.TryReadByte(out b))
                    {
                        return(null);
                    }
                    ops.Add(ImmediateOperand.Byte(b));
                    break;

                case 'I': // A constant included in the instruction encoding.
                    if (!rdr.TryReadUInt16(out var w))
                    {
                        return(null);
                    }
                    ops.Add(ImmediateOperand.Word16(w));
                    break;

                case '@': // @Ri	An internal data RAM location (0-255) addressed indirectly through R0 or R1.
                    ops.Add(MemoryOperand.Indirect(Registers.GetRegister(uInstr & 1)));
                    break;

                case '+': // @A + DPTR:
                    ops.Add(MemoryOperand.Indexed(Registers.DPTR, Registers.A));
                    break;

                case 'P': // @A + PC:
                    ops.Add(MemoryOperand.Indexed(Registers.PC, Registers.A));
                    break;

                case '*': // AB register pair
                    ops.Add(new SequenceOperand(Registers.AB));
                    break;

                default:
                    EmitUnitTest(opcode, uInstr);
                    break;
                }
            }

            return(new i8051Instruction
            {
                Mnemonic = opcode,
                Address = this.addr,
                Length = (int)(rdr.Address - this.addr),
                Operands = ops.ToArray()
            });
        }
示例#11
0
        private Tlcs90Instruction DecodeOperands(byte b, Opcode opcode, string format)
        {
            int           op  = 0;
            var           ops = new MachineOperand[2];
            Constant      c;
            PrimitiveType size;

            for (int i = 0; i < format.Length; ++i)
            {
                switch (format[i])
                {
                case ',':
                    continue;

                case 'a':
                    this.dataWidth = PrimitiveType.Byte;
                    ops[op]        = new RegisterOperand(Registers.a);
                    break;

                case '@':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.af_);
                    break;

                case 'A':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.af);
                    break;

                case 'B':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.bc);
                    break;

                case 'c':
                    ops[op] = new ConditionOperand((CondCode)(b & 0xF));
                    break;

                case 'D':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.de);
                    break;

                case 'I':
                    // Immediate value
                    this.dataWidth = GetSize(format[++i]);
                    if (!rdr.TryReadLe(this.dataWidth, out c))
                    {
                        return(null);
                    }
                    ops[op] = new ImmediateOperand(c);
                    break;

                case 'i': // immediate value from opcode bits
                    ops[op] = ImmediateOperand.Byte((byte)(b & 0x7));
                    break;

                case 'g':
                    Debug.Assert(byteReg != null);
                    ops[op] = this.byteReg;
                    break;

                case 'G':
                    Debug.Assert(wordReg != null);
                    ops[op] = this.wordReg;
                    break;

                case 'H':
                    ops[op] = new RegisterOperand(Registers.hl);
                    break;

                case 'J':
                    // Absolute jump.
                    size = GetSize(format[++i]);
                    if (!rdr.TryReadLe(size, out c))
                    {
                        return(null);
                    }
                    ops[op] = AddressOperand.Ptr16(c.ToUInt16());
                    break;

                case 'j':
                    // relative jump
                    size = GetSize(format[++i]);
                    Address dest;
                    if (size.Size == 1)
                    {
                        if (!rdr.TryReadByte(out b))
                        {
                            return(null);
                        }
                        dest = rdr.Address + (sbyte)b;
                    }
                    else
                    {
                        if (!rdr.TryReadLeInt16(out short off))
                        {
                            return(null);
                        }
                        dest = rdr.Address + off;
                    }
                    ops[op] = AddressOperand.Create(dest);
                    break;

                case 'M':
                    this.dataWidth = GetSize(format[++i]);
                    ushort absAddr;
                    if (!rdr.TryReadLeUInt16(out absAddr))
                    {
                        return(null);
                    }
                    ops[op] = MemoryOperand.Absolute(this.dataWidth, absAddr);
                    break;

                case 'm':
                    size = GetSize(format[++i]);
                    byte pageAddr;
                    if (!rdr.TryReadByte(out pageAddr))
                    {
                        return(null);
                    }
                    ops[op] = MemoryOperand.Absolute(size, (ushort)(0xFF00 | pageAddr));
                    break;

                case 'S':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.sp);
                    break;

                case 'X':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.ix);
                    break;

                case 'Y':
                    this.dataWidth = PrimitiveType.Word16;
                    ops[op]        = new RegisterOperand(Registers.iy);
                    break;

                case 'r':
                    // Register encoded in low 3 bits of b.
                    ops[op]   = new RegisterOperand(Registers.byteRegs[b & 7]);
                    dataWidth = PrimitiveType.Byte;
                    break;

                case 'x':
                    this.backPatchOp = op;
                    break;

                default: throw new NotImplementedException(string.Format("Encoding '{0}' not implemented yet.", format[i]));
                }
                ++op;
            }
            return(new Tlcs90Instruction
            {
                Opcode = opcode,
                op1 = op > 0 ? ops[0] : null,
                op2 = op > 1 ? ops[1] : null,
            });
        }
示例#12
0
        private Tlcs900Instruction Decode(byte b, Opcode opcode, string fmt)
        {
            var instr = new Tlcs900Instruction
            {
                Opcode  = opcode,
                Address = this.addr,
            };
            var            ops = new List <MachineOperand>();
            MachineOperand op  = null;

            for (int i = 0; i < fmt.Length; ++i)
            {
                switch (fmt[i++])
                {
                case ',': continue;

                case 'C': // condition code
                    var cc = (CondCode)(b & 0xF);
                    if (cc == CondCode.T)
                    {
                        continue;
                    }
                    op = new ConditionOperand(cc);
                    break;

                case 'A':
                    op = new RegisterOperand(Tlcs900Registers.a);
                    break;

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

                case 'I': // immediate
                    op = Immediate(fmt[i++]);
                    break;

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

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

                case 'J': // Absolute jump
                    switch (fmt[i++])
                    {
                    case 'w': op = AbsoluteDestination(2); break;

                    case 'l': op = AbsoluteDestination(3); break;

                    default: op = null; break;
                    }
                    break;

                case 'R':   // 16 bit register encoded in lsb
                    op = new RegisterOperand(Reg(fmt[i++], b & 0x7));
                    break;

                case 'S': // status/flag register
                    op = StatusRegister(fmt[i++]);
                    break;
                }
                if (op == null)
                {
                    return(Decode(b, Opcode.invalid, ""));
                }
                ops.Add(op);
            }
            if (ops.Count > 0)
            {
                instr.op1 = ops[0];
                if (ops.Count > 1)
                {
                    instr.op2 = ops[1];
                    if (ops.Count > 2)
                    {
                        instr.op3 = ops[2];
                    }
                }
            }
            return(instr);
        }
示例#13
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));
            }
        }
示例#14
0
 public static bool RILc(ulong uInstr, zSeriesDisassembler dasm)
 {
     var offset = 2 * (int)Bits.SignExtend(uInstr, 32);
     dasm.ops.Add(AddressOperand.Create(dasm.addr + offset));
     return true;
 }
示例#15
0
 public static bool RIc(ulong uInstr, zSeriesDisassembler dasm)
 {
     var addr = dasm.addr + 2*(int)Bits.SignExtend(uInstr, 16);
     dasm.ops.Add(AddressOperand.Create(addr));
     return true;
 }
示例#16
0
        private Msp430Instruction Decode(ushort uInstr, Opcode opcode, string fmt)
        {
            PrimitiveType dataWidth = null;
            int           i         = 0;

            if (i < fmt.Length)
            {
                switch (fmt[i++])
                {
                case 'w': // use width bit
                    dataWidth = (uInstr & 0x40) != 0 ? PrimitiveType.Byte : PrimitiveType.Word16;
                    break;

                case 'a':   // a/w bit 4.
                    dataWidth = (uInstr & 0x04) != 0 ? PrimitiveType.Word16 : Msp430Architecture.Word20;
                    break;

                case 'x':
                    dataWidth = (uExtension != 0) && (uExtension & 0x40) == 0 ? Msp430Architecture.Word20 : PrimitiveType.Word16;
                    break;

                case 'p':
                    dataWidth = Msp430Architecture.Word20;
                    break;

                case 'W': // b/w/a combined from the op and the extension
                    var w = ((this.uExtension & 0x40) >> 5) | (uInstr & 0x040) >> 6;
                    switch (w)
                    {
                    case 0: return(Invalid());

                    case 1: dataWidth = Msp430Architecture.Word20; break;

                    case 2: dataWidth = PrimitiveType.Word16;      break;

                    case 3: dataWidth = PrimitiveType.Byte;        break;
                    }
                    break;

                default:
                    --i;
                    break;
                }
            }
            MachineOperand op1 = null;
            MachineOperand op2 = null;
            int            aS;
            int            iReg;

            if (i < fmt.Length)
            {
                switch (fmt[i++])
                {
                case 'J':
                    int offset = (short)(uInstr << 6) >> 5;
                    op1 = AddressOperand.Create(rdr.Address + offset);
                    break;

                case 'r':
                    op1 = SourceOperand(0, uInstr & 0x0F, dataWidth);
                    break;

                case 'S':
                    aS   = (uInstr >> 4) & 0x03;
                    iReg = (uInstr >> 8) & 0x0F;
                    op1  = SourceOperand(aS, iReg, dataWidth);
                    if (op1 == null)
                    {
                        return(null);
                    }
                    break;

                case 's':
                    aS   = (uInstr >> 4) & 0x03;
                    iReg = uInstr & 0x0F;
                    op1  = SourceOperand(aS, iReg, dataWidth);
                    if (op1 == null)
                    {
                        return(null);
                    }
                    break;

                case 'n':
                    int n = 1 + ((uInstr >> 4) & 0x0F);
                    op1 = ImmediateOperand.Byte((byte)n);
                    break;

                case 'N':
                    n   = 1 + ((uInstr >> 10) & 3);
                    op1 = ImmediateOperand.Byte((byte)n);
                    break;

                case '@':
                    iReg = (uInstr >> 8) & 0x0F;
                    var reg = Registers.GpRegisters[iReg];
                    op1 = new MemoryOperand(Msp430Architecture.Word20)
                    {
                        Base = reg,
                    };
                    break;

                case '+':
                    iReg = (uInstr >> 8) & 0x0F;
                    reg  = Registers.GpRegisters[iReg];
                    op1  = PostInc(reg, Msp430Architecture.Word20);
                    break;

                case '&':
                    if (!rdr.TryReadLeUInt16(out var lo16))
                    {
                        return(Invalid());
                    }
                    var hi4 = (uint)(uInstr >> 8) & 0x0F;
                    //$TODO: 20-bit address?
                    op1 = AddressOperand.Ptr32((hi4 << 16) | lo16);
                    break;

                case 'x':
                    if (!rdr.TryReadLeInt16(out var idxOffset))
                    {
                        return(Invalid());
                    }
                    iReg = (uInstr >> 8) & 0x0F;
                    reg  = Registers.GpRegisters[iReg];
                    op1  = new MemoryOperand(Msp430Architecture.Word20)
                    {
                        Base   = reg,
                        Offset = idxOffset
                    };
                    break;

                default:
                    --i;
                    break;
                }
            }
            if (i < fmt.Length)
            {
                switch (fmt[i])
                {
                case 'D':
                    var aD = (uInstr >> 7) & 0x01;
                    iReg = uInstr & 0x0F;
                    if (iReg == 3)
                    {
                        return(Invalid());
                    }
                    var reg = Registers.GpRegisters[iReg];
                    if (aD == 0)
                    {
                        if (iReg == 3)
                        {
                            return(Invalid());
                        }
                        op2 = new RegisterOperand(reg);
                    }
                    else
                    {
                        op2 = Indexed(reg, dataWidth);
                        if (op2 == null)
                        {
                            return(null);
                        }
                    }
                    break;

                case 'r':
                    op2 = SourceOperand(0, uInstr & 0x0F, dataWidth);
                    break;
                }
            }
            int rep   = (uExtension & 0x0F);
            var instr = new Msp430Instruction
            {
                opcode    = opcode,
                dataWidth = dataWidth,
                op1       = op1,
                op2       = op2,
                repeatImm = (uExtension & 0x80) != 0 ? 0 : rep + 1,
                repeatReg = (uExtension & 0x80) != 0 ? Registers.GpRegisters[rep] : null,
            };

            instr = SpecialCase(instr);
            return(instr);
        }