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); }
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 5: // Register mode op = new RegisterOperand(reg); break; case 7: // Autodecrement mode op = new MemoryOperand(width) { Base = reg, AutoDecrement = true, }; break; case 8: // Autoincrement mode 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 10: // Displacement mode case 11: if (!rdr.TryReadByte(out b)) { return(false); } op = DisplacementOperand(width, reg, Constant.SByte((sbyte)b), bSpecifier); break; case 12: case 13: if (!rdr.TryReadUInt16(out w)) { return(false); } op = DisplacementOperand(width, reg, Constant.Int16((short)w), bSpecifier); break; case 14: case 15: if (!rdr.TryReadUInt32(out dw)) { return(false); } op = DisplacementOperand(width, reg, Constant.Word32(dw), bSpecifier); break; default: throw new NotImplementedException( string.Format( "Unimplemented addressing mode {0:X2}", (bSpecifier >> 4))); } return(true); }