public BinaryOperationArgument(Operation type, ushort destinationAddress, NumberSpec argument1, NumberSpec argument2) { Type = type; DestinationAddress = destinationAddress; Argument1 = argument1; Argument2 = argument2; }
private string FormatBinaryOperation(Instruction instruction) { Opcode65 opcode65 = instruction.Data[0]; if (opcode65.Type == Argument2) { return($"mov {FormatNumber(NumberSpec.FromAddress(opcode65.DestinationAddress))}, {FormatNumber(opcode65.Argument2)}"); } if (opcode65.Type == Zero) { return($"mov {FormatNumber(NumberSpec.FromAddress(opcode65.DestinationAddress))}, 0"); } return(opcode65.Type switch { Add => "add", Subtract => "sub", Multiply => "mul", Divide => "div", Remainder => "rem", BitwiseAnd => "and", BitwiseOr => "or", BitwiseXor => "xor", LeftShift => "lsh", RightShift => "rsh", _ => throw new ArgumentOutOfRangeException(), } +$" {FormatNumber(NumberSpec.FromAddress(opcode65.DestinationAddress))}, " + FormatNumber(opcode65.Argument1) + ", " + FormatNumber(opcode65.Argument2)); }
public Opcode65(Operation type, ushort destinationAddress, NumberSpec argument2) { Type = type; DestinationAddress = destinationAddress; Argument1 = NumberSpec.FromAddress(destinationAddress); Argument2 = argument2; }
private string FormatNumber(NumberSpec number) { if (number.IsConstant) { return($"{number.Value}n"); } Trace.Assert(number.Address.HasValue); return($"@0x{number.Address ?? 0x0:x4}"); }
public BinaryOperationArgument(byte type, ushort destinationAddress, NumberSpec argument2) { type = (byte)(type & 0x7f); Trace.Assert(type <= 11); Type = (Operation)type; DestinationAddress = destinationAddress; Argument1 = NumberSpec.FromAddress(destinationAddress); Argument2 = argument2; }
public Opcode65(byte type, ushort destinationAddress, NumberSpec argument1, NumberSpec argument2) { type = (byte)(type & 0x7f); Trace.Assert(type <= 11); Type = (Operation)type; DestinationAddress = destinationAddress; Argument1 = argument1; Argument2 = argument2; }
private static void EncodeNumber(BinaryWriter bw, NumberSpec value) { if (value.IsConstant) { Debug.Assert(value.Value != null, "value.Value != null"); var val = value.Value.Value; if (val <= 63 && val >= -64) // [-2**6; 2**6 - 1] { bw.Write((byte)(val & 0x7f)); } else if (val <= 2047 && val >= -2048) // [-2**11; 2**11 - 1] { // ReSharper disable once ShiftExpressionZeroLeftOperand bw.Write((byte)(0x80 | (0 << 4) | (val >> 8) & 0xf)); bw.Write((byte)val); } else if (val <= 524287 && val >= -524288) // [-2**19; 2**19 - 1] { bw.Write((byte)(0x80 | (1 << 4) | (val >> 16) & 0xf)); bw.Write((byte)(val >> 8)); bw.Write((byte)val); } else if (val <= 134217727 && val >= -134217728) // [-2**27; 2**27 - 1] { bw.Write((byte)(0x80 | (2 << 4) | (val >> 24) & 0xf)); bw.Write((byte)(val >> 16)); bw.Write((byte)(val >> 8)); bw.Write((byte)val); } else { throw new ArgumentException(); } } else { Debug.Assert(value.Address != null, "value.Address != null"); var addr = checked ((ushort)value.Address.Value); if (addr < 16) { bw.Write((byte)(0x80 | (3 << 4) | addr & 0xf)); } else if (addr < 4096) { bw.Write((byte)(0x80 | (4 << 4) | (addr >> 8) & 0xf)); bw.Write((byte)addr); } else { throw new ArgumentException(); } } }
private static int NumberLength(NumberSpec value) { if (value.IsConstant) { Debug.Assert(value.Value != null, "value.Value != null"); var val = value.Value.Value; if (val <= 63 && val >= -64) // [-2**6; 2**6 - 1] { return(1); } if (val <= 2047 && val >= -2048) // [-2**11; 2**11 - 1] { return(2); } if (val <= 524287 && val >= -524288) // [-2**19; 2**19 - 1] { return(3); } if (val <= 134217727 && val >= -134217728) // [-2**27; 2**27 - 1] { return(4); } throw new ArgumentException(); } Debug.Assert(value.Address != null, "value.Address != null"); var addr = value.Address.Value; if (addr < 16) { return(1); } if (addr < 4096) { return(2); } throw new ArgumentException(); }
private string FormatElement(Opcode opcode, int index, OpcodeEncodingElement element, dynamic data) { return(element switch { OpcodeEncodingElement.Byte => $"{data}b", OpcodeEncodingElement.Short => $"{data}s", OpcodeEncodingElement.Address => FormatNumber(NumberSpec.FromAddress(data)), OpcodeEncodingElement.Int => $"{data}i", OpcodeEncodingElement.String => $"S{FormatString(data)}", OpcodeEncodingElement.LongString => $"L{FormatString(data)}", OpcodeEncodingElement.NumberArgument => FormatNumber(data), OpcodeEncodingElement.JumpOffset => FormatJumpOffset(data), OpcodeEncodingElement.AddressArray => $"a[{string.Join(",", ((ImmutableArray<ushort>) data).Select(NumberSpec.FromAddress).Select(FormatNumber))}]", OpcodeEncodingElement.StringArray => $"S[{string.Join(",", ((ImmutableArray<string>)data).Select(FormatString))}]", OpcodeEncodingElement.NumberArray => $"n[{string.Join(",", ((ImmutableArray<NumberSpec>) data).Select(FormatNumber))}]", OpcodeEncodingElement.JumpOffsetArray => $"j[{string.Join(",", ((ImmutableArray<int>) data).Select(FormatJumpOffset))}]", OpcodeEncodingElement.PostfixNotationExpression => $"rpne{{{FormatPostfixExpression(data)}}}", OpcodeEncodingElement.BitmappedNumberArguments => $"bmn[{string.Join(",", ((ImmutableArray<NumberSpec>) data).Select(FormatNumber))}]", OpcodeEncodingElement.MessageId => $"{data}mi", _ => throw new ArgumentOutOfRangeException() });
public Element(NumberSpec numberSpec) { Operation = Operation.Constant; NumberSpec = numberSpec; }
public void AddConstant(NumberSpec number) => AddElement(new PostfixExpression.Element(number));
public static BinaryOperationArgument MovValue(ushort address, NumberSpec number) { return(new BinaryOperationArgument((byte)Operation.Argument2, address, number)); }
public static BinaryOperationArgument MovZero(ushort address) { return(new BinaryOperationArgument((byte)Operation.Zero, address, NumberSpec.FromConstant(0))); }
public static Opcode65 MovValue(ushort address, NumberSpec number) { return(new Opcode65((byte)Operation.Argument2, address, number)); }
public static Opcode65 MovZero(ushort address) { return(new Opcode65((byte)Operation.Zero, address, NumberSpec.FromConstant(0))); }