public static FxlcToken Parse(BytecodeReader reader)
        {
            var result = new FxlcToken();
            var token  = reader.ReadUInt32();
            var tokenComponentCount = token.DecodeValue(0, 2);

            result.Opcode = (FxlcOpcode)token.DecodeValue(20, 30);
            result.IsScalarInstruction = token.DecodeValue <bool>(31, 31);

            Debug.Assert(Enum.IsDefined(typeof(FxlcOpcode), result.Opcode),
                         $"Unknown FxlcOpcode {result.Opcode}");

            Debug.Assert(token.DecodeValue(3, 19) == 0,
                         $"Unexpected data in FxlcToken bits 3-19 {token.DecodeValue(3, 19)}");

            var operandCount = reader.ReadUInt32();

            for (int i = 0; i < operandCount; i++)
            {
                var isScalarOp = i == 0 && result.IsScalarInstruction;
                result.Operands.Add(FxlcOperand.Parse(reader, tokenComponentCount, isScalarOp));
            }
            // destination operand
            result.Operands.Insert(0, FxlcOperand.Parse(reader, tokenComponentCount, false));
            return(result);
        }
        public static FxlcOperand Parse(BytecodeReader reader, uint componentCount, bool isScalarOp)
        {
            var result = new FxlcOperand()
            {
                IsArray = reader.ReadUInt32(),
                OpType  = (FxlcOperandType)reader.ReadUInt32(),
                OpIndex = reader.ReadUInt32(),
            };

            result.ComponentCount = isScalarOp && result.OpType != FxlcOperandType.Literal ? 1 : componentCount;
            Debug.Assert(Enum.IsDefined(typeof(FxlcOperandType), result.OpType),
                         $"Unexpected FxlcOperandType OpType {result.OpType}");
            if (result.IsArray == 1)
            {
                result.ArrayType  = (FxlcOperandType)reader.ReadUInt32();
                result.ArrayIndex = reader.ReadUInt32();

                Debug.Assert(Enum.IsDefined(typeof(FxlcOperandType), result.ArrayType),
                             $"Unexpected FxlcOperandType ArrayType {result.ArrayType}");
            }

            return(result);
        }