static uint GetFirstStringIndex(StringsTable stringsTable, object[] info, out bool hasVPrefix) { if (!(info[2] is string s)) { throw new InvalidOperationException(); } return(stringsTable.GetIndex(s, ignoreVPrefix: true, out hasVPrefix)); }
public void Initialize(GenTypes genTypes, StringsTable stringsTable) { var expectedLength = genTypes[TypeIds.Code].Values.Length; if (defs.Length != expectedLength) { throw new InvalidOperationException($"Found {defs.Length} elements, expected {expectedLength}"); } for (int i = 0; i < defs.Length; i++) { var def = defs[i]; stringsTable.Add((uint)i, def.Mnemonic, true); } }
protected void Initialize(StringsTable stringsTable, object[][] infos) { foreach (var info in infos) { bool ignoreVPrefix = true; foreach (var o in info) { if (o is string s) { stringsTable.Add(s, ignoreVPrefix); ignoreVPrefix = false; } } } }
public void Initialize(StringsTable stringsTable) { var expectedLength = CodeEnum.Instance.Values.Length; if (infos.Length != expectedLength) { throw new InvalidOperationException($"Found {infos.Length} elements, expected {expectedLength}"); } foreach (var info in infos) { bool ignoreVPrefix = true; foreach (var o in info) { if (o is string s) { stringsTable.Add(s, ignoreVPrefix); ignoreVPrefix = false; } } } }
public void Initialize(GenTypes genTypes, StringsTable stringsTable) { var expectedLength = genTypes[TypeIds.Code].Values.Length; if (infos.Length != expectedLength) { throw new InvalidOperationException($"Found {infos.Length} elements, expected {expectedLength}"); } for (int i = 0; i < infos.Length; i++) { var info = infos[i]; bool ignoreVPrefix = true; foreach (var o in info) { if (o is string s) { stringsTable.Add((uint)i, s, ignoreVPrefix); ignoreVPrefix = false; } } } }
protected void SerializeTable(FileWriter writer, StringsTable stringsTable) { int index = -1; for (int i = 0; i < defs.Length; i++) { var def = defs[i]; index++; var ctorKind = def.CtorKind; var code = def.Code; if (code.Value != (uint)index) { throw new InvalidOperationException(); } if (index != 0) { writer.WriteLine(); } writer.WriteCommentLine(code.ToStringValue(idConverter)); bool isSame = i > 0 && IsSame(defs[i - 1], def); if (isSame) { ctorKind = previousCtorKind; } uint si = stringsTable.GetIndex(def.Mnemonic, ignoreVPrefix: true, out bool hasVPrefix); if (ctorKind.Value > 0x7F) { throw new InvalidOperationException(); } writer.WriteByte((byte)(ctorKind.Value | (hasVPrefix ? 0x80U : 0))); if (hasVPrefix) { writer.WriteCommentLine($"'v', {ctorKind.ToStringValue(idConverter)}"); } else { writer.WriteCommentLine($"{ctorKind.ToStringValue(idConverter)}"); } if (isSame) { continue; } writer.WriteCompressedUInt32(si); writer.WriteCommentLine($"{si} = \"{def.Mnemonic}\""); foreach (var arg in def.Args) { switch (arg) { case string s: si = stringsTable.GetIndex(s, ignoreVPrefix: true, out hasVPrefix); if (hasVPrefix) { throw new InvalidOperationException(); } writer.WriteCompressedUInt32(si); writer.WriteCommentLine($"{si} = \"{s}\""); break; case char c: if ((ushort)c > byte.MaxValue) { throw new InvalidOperationException(); } writer.WriteByte((byte)c); if (c == '\0') { writer.WriteCommentLine(@"'\0'"); } else { writer.WriteCommentLine($"'{c}'"); } break; case int ival: writer.WriteCompressedUInt32((uint)ival); writer.WriteCommentLine($"0x{ival:X}"); break; case bool b: writer.WriteByte((byte)(b ? 1 : 0)); writer.WriteCommentLine(b.ToString()); break; case IEnumValue enumValue: var typeId = enumValue.DeclaringType.TypeId; if (typeId == TypeIds.GasInstrOpInfoFlags) { writer.WriteCompressedUInt32(enumValue.Value); writer.WriteCommentLine($"0x{enumValue.Value:X} = {enumValue.ToStringValue(idConverter)}"); } else if (typeId == TypeIds.IntelInstrOpInfoFlags) { writer.WriteCompressedUInt32(enumValue.Value); writer.WriteCommentLine($"0x{enumValue.Value:X} = {enumValue.ToStringValue(idConverter)}"); } else if (typeId == TypeIds.MasmInstrOpInfoFlags) { writer.WriteCompressedUInt32(enumValue.Value); writer.WriteCommentLine($"0x{enumValue.Value:X} = {enumValue.ToStringValue(idConverter)}"); } else if (typeId == TypeIds.NasmInstrOpInfoFlags) { writer.WriteCompressedUInt32(enumValue.Value); writer.WriteCommentLine($"0x{enumValue.Value:X} = {enumValue.ToStringValue(idConverter)}"); } else if (typeId == TypeIds.PseudoOpsKind) { if (enumValue.Value > byte.MaxValue) { throw new InvalidOperationException(); } writer.WriteByte((byte)enumValue.Value); writer.WriteCommentLine(enumValue.ToStringValue(idConverter)); } else if (typeId == TypeIds.CodeSize) { if (enumValue.Value > byte.MaxValue) { throw new InvalidOperationException(); } writer.WriteByte((byte)enumValue.Value); writer.WriteCommentLine(enumValue.ToStringValue(idConverter)); } else if (typeId == TypeIds.Register) { if (enumValue.Value > byte.MaxValue) { throw new InvalidOperationException(); } writer.WriteByte((byte)enumValue.Value); writer.WriteCommentLine(enumValue.ToStringValue(idConverter)); } else if (typeId == TypeIds.MemorySize) { if (enumValue.Value > byte.MaxValue) { throw new InvalidOperationException(); } writer.WriteByte((byte)enumValue.Value); writer.WriteCommentLine(enumValue.ToStringValue(idConverter)); } else if (typeId == TypeIds.NasmSignExtendInfo) { if (enumValue.Value > byte.MaxValue) { throw new InvalidOperationException(); } writer.WriteByte((byte)enumValue.Value); writer.WriteCommentLine(enumValue.ToStringValue(idConverter)); } else { throw new InvalidOperationException(); } break; default: throw new InvalidOperationException(); } } } }
public abstract void Serialize(GenTypes genTypes, FileWriter writer, StringsTable stringsTable);
protected void SerializeTable(GenTypes genTypes, FileWriter writer, StringsTable stringsTable) { var fastFmtFlags = genTypes[TypeIds.FastFmtFlags]; var hasVPrefixEnum = fastFmtFlags[nameof(FastFmtFlags.HasVPrefix)]; var sameAsPrevEnum = fastFmtFlags[nameof(FastFmtFlags.SameAsPrev)]; var flagsValues = new List <EnumValue>(); int index = -1; uint prevMnemonicStringIndex = uint.MaxValue; foreach (var def in defs) { index++; var code = def.Code; if (code.Value != (uint)index) { throw new InvalidOperationException(); } flagsValues.Clear(); if (index != 0) { writer.WriteLine(); } writer.WriteCommentLine(code.ToStringValue(idConverter)); var mnemonic = def.Mnemonic; uint mnemonicStringIndex = stringsTable.GetIndex(mnemonic, ignoreVPrefix: true, out var hasVPrefix); var flags = def.Flags; if (hasVPrefix) { flagsValues.Add(hasVPrefixEnum); } bool isSame = false; if (mnemonicStringIndex == prevMnemonicStringIndex) { isSame = true; flagsValues.Add(sameAsPrevEnum); } if (def.Flags is EnumValue flags2) { flagsValues.Add(flags2); } else if (def.Flags is OrEnumValue flags3) { flagsValues.AddRange(flags3.Values); } else { throw new InvalidOperationException(); } uint flagsValue = 0; foreach (var enumValue in flagsValues) { flagsValue |= enumValue.Value; } if (flagsValue > byte.MaxValue) { throw new InvalidOperationException(); } writer.WriteByte((byte)flagsValue); string comment = flagsValues.Count switch { 0 => "No flags set", 1 => flagsValues[0].ToStringValue(idConverter), _ => new OrEnumValue(fastFmtFlags, flagsValues.ToArray()).ToStringValue(idConverter), }; writer.WriteCommentLine(comment); // We save 4KB (11,595 -> 7,435 bytes) if (!isSame) { writer.WriteCompressedUInt32(mnemonicStringIndex); writer.WriteCommentLine($"{mnemonicStringIndex} = \"{mnemonic}\""); } prevMnemonicStringIndex = mnemonicStringIndex; } }
public abstract void Serialize(FileWriter writer, StringsTable stringsTable);
public abstract void Initialize(StringsTable stringsTable);
protected void SerializeTable(GenTypes genTypes, FileWriter writer, StringsTable stringsTable) { var fastFmtFlags = genTypes[TypeIds.FastFmtFlags]; var hasVPrefixEnum = fastFmtFlags[nameof(FastFmtFlags.HasVPrefix)]; var sameAsPrevEnum = fastFmtFlags[nameof(FastFmtFlags.SameAsPrev)]; var flagsValues = new List <EnumValue>(); int index = -1; uint prevMnemonicStringIndex = uint.MaxValue; foreach (var info in infos) { if (info.Length < 2) { throw new InvalidOperationException(); } index++; var code = (EnumValue)info[0]; if (code.Value != (uint)index) { throw new InvalidOperationException(); } flagsValues.Clear(); if (index != 0) { writer.WriteLine(); } writer.WriteCommentLine(code.ToStringValue(idConverter)); var mnemonic = info[1] as string ?? throw new InvalidOperationException(); uint mnemonicStringIndex = stringsTable.GetIndex(mnemonic, ignoreVPrefix: true, out var hasVPrefix); if (hasVPrefix) { flagsValues.Add(hasVPrefixEnum); } bool isSame = false; if (mnemonicStringIndex == prevMnemonicStringIndex) { isSame = true; flagsValues.Add(sameAsPrevEnum); } for (int i = 2; i < info.Length; i++) { switch (info[i]) { case IEnumValue enumValue: var typeId = enumValue.DeclaringType.TypeId; if (typeId == TypeIds.FastFmtFlags) { if (enumValue is EnumValue enumValue2) { flagsValues.Add(enumValue2); } else if (enumValue is OrEnumValue orEnumValue) { flagsValues.AddRange(orEnumValue.Values); } else { throw new InvalidOperationException(); } } else { throw new InvalidOperationException(); } break; default: throw new InvalidOperationException(); } } uint flagsValue = 0; foreach (var enumValue in flagsValues) { flagsValue |= enumValue.Value; } if (flagsValue > byte.MaxValue) { throw new InvalidOperationException(); } writer.WriteByte((byte)flagsValue); string comment; switch (flagsValues.Count) { case 0: comment = "No flags set"; break; case 1: comment = flagsValues[0].ToStringValue(idConverter); break; default: comment = new OrEnumValue(fastFmtFlags, flagsValues.ToArray()).ToStringValue(idConverter); break; } writer.WriteCommentLine(comment); // We save 4KB (11,595 -> 7,435 bytes) if (!isSame) { writer.WriteCompressedUInt32(mnemonicStringIndex); writer.WriteCommentLine($"{mnemonicStringIndex} = \"{mnemonic}\""); } prevMnemonicStringIndex = mnemonicStringIndex; } }