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); }
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))); } } }
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; }