// various mem formats private static Mutator <Tlcs900Disassembler> m(PrimitiveType size) { return((b, dasm) => { if (!dasm.rdr.TryReadByte(out byte m)) { return false; } switch (m & 3) { case 0: // Register indirect dasm.ops.Add(MemoryOperand.Indirect(dasm.Size(size), dasm.Reg(PrimitiveType.Word32, (m >> 2) & 0x3F))); dasm.SetSize(size); return true; case 1: // indexed (16-bit offset) if (!dasm.rdr.TryReadLeInt16(out short o16)) { return false; } dasm.ops.Add(MemoryOperand.Indexed16(dasm.Size(size), dasm.Reg(PrimitiveType.Word32, (m >> 2) & 0x3F), o16)); dasm.SetSize(size); return true; case 3: if (m != 3 && m != 7) { return false; } if (!dasm.rdr.TryReadByte(out byte rBase)) { return false; } if (!dasm.rdr.TryReadByte(out byte rIdx)) { return false; } var regBase = dasm.Reg(PrimitiveType.Word32, rBase); var regIdx = dasm.Reg(m == 3 ? PrimitiveType.Byte : PrimitiveType.Word16, rIdx); dasm.ops.Add(MemoryOperand.RegisterIndexed(dasm.Size(size), regBase, regIdx)); dasm.SetSize(size); return true; default: return false; } }); }
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)); } }