Add special handling for known OPR instructions

This commit is contained in:
Yoshi Askharoun
2025-09-21 21:19:14 -05:00
parent ebb41f0384
commit 7cc0702c14
5 changed files with 31 additions and 9 deletions
+4 -3
View File
@@ -25,10 +25,11 @@ internal static class InstructionSet
public static string GetMnemonic(OpCode opCode, OperationType? opType = null) public static string GetMnemonic(OpCode opCode, OperationType? opType = null)
{ {
if (opCode is OpCode.Operation && opType.HasValue && OperationMnemonicMap.TryGetLeft(opType.Value, out var operationMnemonic))
return operationMnemonic;
if (MnemonicMap.TryGetLeft(opCode, out var mnemonic)) if (MnemonicMap.TryGetLeft(opCode, out var mnemonic))
return mnemonic; return mnemonic;
else if (opType.HasValue && OperationMnemonicMap.TryGetLeft(opType.Value, out var operationMnemonic))
return operationMnemonic;
throw new System.ArgumentException($"'{opCode}' is not a known UIXA instruction.", nameof(opCode)); throw new System.ArgumentException($"'{opCode}' is not a known UIXA instruction.", nameof(opCode));
} }
@@ -163,7 +164,7 @@ internal static class InstructionSet
[OpCode.ConstructFromBinary] = [LiteralDataType.TypeIndex, LiteralDataType.Bytes], [OpCode.ConstructFromBinary] = [LiteralDataType.TypeIndex, LiteralDataType.Bytes],
[OpCode.Operation] = [LiteralDataType.OpHostIndex, LiteralDataType.Byte], [OpCode.Operation] = [LiteralDataType.OpHostIndex, LiteralDataType.Operation],
[OpCode.Listen] = [LiteralDataType.UInt16, LiteralDataType.Byte, LiteralDataType.UInt16, LiteralDataType.UInt32], [OpCode.Listen] = [LiteralDataType.UInt16, LiteralDataType.Byte, LiteralDataType.UInt16, LiteralDataType.UInt32],
[OpCode.DestructiveListen] = [LiteralDataType.UInt16, LiteralDataType.Byte, LiteralDataType.UInt16, LiteralDataType.UInt32, LiteralDataType.UInt32], [OpCode.DestructiveListen] = [LiteralDataType.UInt16, LiteralDataType.Byte, LiteralDataType.UInt16, LiteralDataType.UInt32, LiteralDataType.UInt32],
+21 -4
View File
@@ -12,10 +12,6 @@ public record Instruction(string Mnemonic, IEnumerable<Operand> Operands, uint O
: this(InstructionSet.GetMnemonic(opCode, operationType), operands, offset) : this(InstructionSet.GetMnemonic(opCode, operationType), operands, offset)
{ {
} }
public Instruction(OpCode opCode, IEnumerable<Operand> operands, uint offset)
: this(opCode, null, operands, offset)
{
}
public OpCode OpCode => InstructionSet.MnemonicToOpCode(Mnemonic); public OpCode OpCode => InstructionSet.MnemonicToOpCode(Mnemonic);
@@ -30,4 +26,25 @@ public record Instruction(string Mnemonic, IEnumerable<Operand> Operands, uint O
? $"{mnemonic} {string.Join(", ", Operands)}" ? $"{mnemonic} {string.Join(", ", Operands)}"
: mnemonic; : mnemonic;
} }
public static Instruction Create(OpCode opCode, IEnumerable<Operand> operands, uint offset)
{
OperationType? operationType = null;
if (opCode is OpCode.Operation)
{
var operandsList = operands.ToList();
if (operandsList.Count != 2)
throw new System.ArgumentException("Operation instructions must have exactly two operands: the operation host index and the operation type.", nameof(operands));
var operandOperationValue = operandsList[1].Value;
if (operandOperationValue is byte or Markup.OperationType)
operationType = (OperationType?)(int?)(byte?)operandOperationValue;
operandsList.RemoveAt(1);
operands = operandsList;
}
return new(opCode, operationType, operands, offset);
}
} }
+4
View File
@@ -14,6 +14,7 @@ public enum LiteralDataType : byte
Int32 = 0b0011, Int32 = 0b0011,
Bytes = 0b0100, Bytes = 0b0100,
Operation = 0b0101,
TypeIndex = 0b1000, TypeIndex = 0b1000,
PropertyIndex = 0b1001, PropertyIndex = 0b1001,
@@ -41,6 +42,9 @@ public record OperandLiteral : Operand
public static LiteralDataType ReduceDataType(LiteralDataType dataType) public static LiteralDataType ReduceDataType(LiteralDataType dataType)
{ {
if (dataType is LiteralDataType.Operation)
return LiteralDataType.Byte;
return IsIndex(dataType) ? LiteralDataType.UInt16 : dataType; return IsIndex(dataType) ? LiteralDataType.UInt16 : dataType;
} }
+1 -1
View File
@@ -133,7 +133,7 @@ public class ObjectSection
operands[i] = operand; operands[i] = operand;
} }
yield return new Instruction(opCode, operands, offset); yield return Instruction.Create(opCode, operands, offset);
} }
} }
} }
+1 -1
View File
@@ -536,7 +536,7 @@ partial class Decompiler
private ExpressionSyntax DecompileOperation(Instruction instruction, Stack<object> stack) private ExpressionSyntax DecompileOperation(Instruction instruction, Stack<object> stack)
{ {
var op = (OperationType)(int)(byte)instruction.Operands.ElementAt(1).Value; var op = instruction.OperationType.Value;
var isUnary = TypeSchema.IsUnaryOperation(op); var isUnary = TypeSchema.IsUnaryOperation(op);
var opSyntax = OperationToSyntaxKind(op); var opSyntax = OperationToSyntaxKind(op);