Esempio n. 1
0
        public static Operand Parse(BytecodeReader reader, OpcodeType parentType)
        {
            uint token0 = reader.ReadUInt32();

            if (token0 == 0)
            {
                return(null);
            }

            var operand = new Operand(parentType);

            var numComponents = token0.DecodeValue <OperandNumComponents>(0, 1);

            switch (numComponents)
            {
            case OperandNumComponents.Zero:
            {
                operand.NumComponents = 0;
                break;
            }

            case OperandNumComponents.One:
            {
                operand.NumComponents = 1;
                break;
            }

            case OperandNumComponents.Four:
            {
                operand.NumComponents = 4;
                operand.SelectionMode = token0.DecodeValue <Operand4ComponentSelectionMode>(2, 3);
                switch (operand.SelectionMode)
                {
                case Operand4ComponentSelectionMode.Mask:
                {
                    operand.ComponentMask = token0.DecodeValue <ComponentMask>(4, 7);
                    break;
                }

                case Operand4ComponentSelectionMode.Swizzle:
                {
                    var swizzle = token0.DecodeValue(4, 11);
                    Func <uint, byte, Operand4ComponentName> swizzleDecoder = (s, i) =>
                                                                              (Operand4ComponentName)((s >> (i * 2)) & 3);
                    operand.Swizzles[0] = swizzleDecoder(swizzle, 0);
                    operand.Swizzles[1] = swizzleDecoder(swizzle, 1);
                    operand.Swizzles[2] = swizzleDecoder(swizzle, 2);
                    operand.Swizzles[3] = swizzleDecoder(swizzle, 3);
                    break;
                }

                case Operand4ComponentSelectionMode.Select1:
                {
                    var swizzle = token0.DecodeValue <Operand4ComponentName>(4, 5);
                    operand.Swizzles[0] = operand.Swizzles[1] = operand.Swizzles[2] = operand.Swizzles[3] = swizzle;
                    break;
                }

                default:
                {
                    throw new ParseException("Unrecognized selection method: " + operand.SelectionMode);
                }
                }
                break;
            }

            case OperandNumComponents.N:
            {
                throw new ParseException("OperandNumComponents.N is not currently supported.");
            }
            }

            operand.OperandType    = token0.DecodeValue <OperandType>(12, 19);
            operand.IndexDimension = token0.DecodeValue <OperandIndexDimension>(20, 21);

            operand.IsExtended = token0.DecodeValue(31, 31) == 1;
            if (operand.IsExtended)
            {
                ReadExtendedOperand(operand, reader);
            }

            Func <uint, byte, OperandIndexRepresentation> indexRepresentationDecoder = (t, i) =>
                                                                                       (OperandIndexRepresentation)t.DecodeValue((byte)(22 + (i * 3)), (byte)(22 + (i * 3) + 2));

            for (byte i = 0; i < (byte)operand.IndexDimension; i++)
            {
                operand.Indices[i] = new OperandIndex();

                var indexRepresentation = indexRepresentationDecoder(token0, i);
                operand.Indices[i].Representation = indexRepresentation;

                switch (indexRepresentation)
                {
                case OperandIndexRepresentation.Immediate32:
                    operand.Indices[i].Value = reader.ReadUInt32();
                    break;

                case OperandIndexRepresentation.Immediate64:
                    operand.Indices[i].Value = reader.ReadUInt64();
                    goto default;

                case OperandIndexRepresentation.Relative:
                    operand.Indices[i].Register = Parse(reader, parentType);
                    break;

                case OperandIndexRepresentation.Immediate32PlusRelative:
                    operand.Indices[i].Value = reader.ReadUInt32();
                    goto case OperandIndexRepresentation.Relative;

                case OperandIndexRepresentation.Immediate64PlusRelative:
                    operand.Indices[i].Value = reader.ReadUInt64();
                    goto case OperandIndexRepresentation.Relative;

                default:
                    throw new ParseException("Unrecognised index representation: " + indexRepresentation);
                }
            }

            var numberType = parentType.GetNumberType();

            switch (operand.OperandType)
            {
            case OperandType.Immediate32:
            {
                var immediateValues = new Number4();
                for (var i = 0; i < operand.NumComponents; i++)
                {
                    immediateValues.SetNumber(i, Number.Parse(reader));
                }
                operand.ImmediateValues = immediateValues;
                break;
            }

            case OperandType.Immediate64:
            {
                var immediateValues = new Number4();
                for (var i = 0; i < operand.NumComponents; i++)
                {
                    immediateValues.SetDouble(i, reader.ReadDouble());
                }
                operand.ImmediateValues = immediateValues;
                break;
            }
            }

            return(operand);
        }
Esempio n. 2
0
        public override string ToString()
        {
            switch (OperandType)
            {
            case OperandType.Immediate32:
            case OperandType.Immediate64:
            {
                string result    = (OperandType == OperandType.Immediate64) ? "d(" : "l(";
                bool   addSpaces = ParentType != OpcodeType.Mov && ParentType != OpcodeType.MovC && ParentType != OpcodeType.StoreStructured;
                for (int i = 0; i < NumComponents; i++)
                {
                    var parentType = ParentType.GetNumberType();
                    result += (OperandType == OperandType.Immediate64)
                                                                ? ImmediateValues.GetDouble(i).ToString()
                                                                : ImmediateValues.GetNumber(i).ToString(parentType);

                    if (i < NumComponents - 1)
                    {
                        result += ",";
                        if (addSpaces)
                        {
                            result += " ";
                        }
                    }
                }
                result += ")";
                return(result);
            }

            case OperandType.Null:
            {
                return(OperandType.GetDescription());
            }

            default:
            {
                string index = string.Empty;
                switch (IndexDimension)
                {
                case OperandIndexDimension._0D:
                    break;

                case OperandIndexDimension._1D:
                    index = (Indices[0].Representation == OperandIndexRepresentation.Relative ||
                             Indices[0].Representation == OperandIndexRepresentation.Immediate32PlusRelative ||
                             !OperandType.RequiresRegisterNumberFor1DIndex())
                                                                        ? string.Format("[{0}]", Indices[0])
                                                                        : Indices[0].ToString();
                    break;

                case OperandIndexDimension._2D:
                    index = (Indices[0].Representation == OperandIndexRepresentation.Relative ||
                             Indices[0].Representation == OperandIndexRepresentation.Immediate32PlusRelative ||
                             !OperandType.RequiresRegisterNumberFor2DIndex())
                                                                        ? string.Format("[{0}][{1}]", Indices[0], Indices[1])
                                                                        : string.Format("{0}[{1}]", Indices[0], Indices[1]);
                    break;

                case OperandIndexDimension._3D:
                    index = ParentType.IsDeclaration()
                                                                                ? string.Format("{0}[{1}:{2}]", Indices[0], Indices[1], Indices[2])
                                                                                : string.Format("{0}[{1}][{2}]", Indices[0], Indices[1], Indices[2]);
                    break;
                }

                string components = string.Empty;
                if (ParentType.OpcodeHasSwizzle())
                {
                    switch (SelectionMode)
                    {
                    case Operand4ComponentSelectionMode.Mask:
                        components = ComponentMask.GetDescription();
                        break;

                    case Operand4ComponentSelectionMode.Swizzle:
                        components = Swizzles[0].GetDescription()
                                     + Swizzles[1].GetDescription()
                                     + Swizzles[2].GetDescription()
                                     + Swizzles[3].GetDescription();
                        break;

                    case Operand4ComponentSelectionMode.Select1:
                        components = Swizzles[0].GetDescription();
                        break;

                    default:
                        throw new InvalidOperationException("Unrecognised selection mode: " + SelectionMode);
                    }
                    if (!string.IsNullOrEmpty(components))
                    {
                        components = "." + components;
                    }
                }
                string minPrecision = MinPrecision == OperandMinPrecision.Default ?
                                      string.Empty : $" {MinPrecision.GetDescription()}";
                return(Modifier.Wrap(string.Format("{0}{1}{2}{3}", GetOperandDescription(), index, components, minPrecision)));
            }
            }
        }
Esempio n. 3
0
		public static Operand Parse(BytecodeReader reader, OpcodeType parentType)
		{
			uint token0 = reader.ReadUInt32();
		    if (token0 == 0)
		        return null;

			var operand = new Operand(parentType);

			var numComponents = token0.DecodeValue<OperandNumComponents>(0, 1);
			switch (numComponents)
			{
				case OperandNumComponents.Zero:
					{
						operand.NumComponents = 0;
						break;
					}
				case OperandNumComponents.One:
					{
						operand.NumComponents = 1;
						break;
					}
				case OperandNumComponents.Four:
					{
						operand.NumComponents = 4;
						operand.SelectionMode = token0.DecodeValue<Operand4ComponentSelectionMode>(2, 3);
						switch (operand.SelectionMode)
						{
							case Operand4ComponentSelectionMode.Mask:
								{
									operand.ComponentMask = token0.DecodeValue<ComponentMask>(4, 7);
									break;
								}
							case Operand4ComponentSelectionMode.Swizzle:
								{
									var swizzle = token0.DecodeValue(4, 11);
									Func<uint, byte, Operand4ComponentName> swizzleDecoder = (s, i) =>
										(Operand4ComponentName) ((s >> (i * 2)) & 3);
									operand.Swizzles[0] = swizzleDecoder(swizzle, 0);
									operand.Swizzles[1] = swizzleDecoder(swizzle, 1);
									operand.Swizzles[2] = swizzleDecoder(swizzle, 2);
									operand.Swizzles[3] = swizzleDecoder(swizzle, 3);
									break;
								}
							case Operand4ComponentSelectionMode.Select1:
								{
									var swizzle = token0.DecodeValue<Operand4ComponentName>(4, 5);
									operand.Swizzles[0] = operand.Swizzles[1] = operand.Swizzles[2] = operand.Swizzles[3] = swizzle;
									break;
								}
							default:
								{
									throw new ParseException("Unrecognized selection method: " + operand.SelectionMode);
								}
						}
						break;
					}
				case OperandNumComponents.N:
					{
						throw new ParseException("OperandNumComponents.N is not currently supported.");
					}
			}

			operand.OperandType = token0.DecodeValue<OperandType>(12, 19);
			operand.IndexDimension = token0.DecodeValue<OperandIndexDimension>(20, 21);

			operand.IsExtended = token0.DecodeValue(31, 31) == 1;
			if (operand.IsExtended)
				ReadExtendedOperand(operand, reader);

			Func<uint, byte, OperandIndexRepresentation> indexRepresentationDecoder = (t, i) =>
				(OperandIndexRepresentation) t.DecodeValue((byte) (22 + (i * 3)), (byte) (22 + (i * 3) + 2));

			for (byte i = 0; i < (byte) operand.IndexDimension; i++)
			{
				operand.Indices[i] = new OperandIndex();

				var indexRepresentation = indexRepresentationDecoder(token0, i);
				operand.Indices[i].Representation = indexRepresentation;

				switch (indexRepresentation)
				{
					case OperandIndexRepresentation.Immediate32:
						operand.Indices[i].Value = reader.ReadUInt32();
						break;
					case OperandIndexRepresentation.Immediate64:
						operand.Indices[i].Value = reader.ReadUInt64();
						goto default;
					case OperandIndexRepresentation.Relative:
						operand.Indices[i].Register = Parse(reader, parentType);
						break;
					case OperandIndexRepresentation.Immediate32PlusRelative:
						operand.Indices[i].Value = reader.ReadUInt32();
						goto case OperandIndexRepresentation.Relative;
					case OperandIndexRepresentation.Immediate64PlusRelative:
						operand.Indices[i].Value = reader.ReadUInt64();
						goto case OperandIndexRepresentation.Relative;
					default:
						throw new ParseException("Unrecognised index representation: " + indexRepresentation);
				}
			}

			var numberType = parentType.GetNumberType();
			switch (operand.OperandType)
			{
				case OperandType.Immediate32:
				{
					var immediateValues = new Number4();
					for (var i = 0; i < operand.NumComponents; i++)
						immediateValues.SetNumber(i, Number.Parse(reader));
					operand.ImmediateValues = immediateValues;
					break;
				}
				case OperandType.Immediate64:
				{
					var immediateValues = new Number4();
					for (var i = 0; i < operand.NumComponents; i++)
						immediateValues.SetDouble(i, reader.ReadDouble());
					operand.ImmediateValues = immediateValues;
					break;
				}
			}

			return operand;
		}