diff --git a/SourceGen/AsmGen/GenCommon.cs b/SourceGen/AsmGen/GenCommon.cs index c3e6c51..740d865 100644 --- a/SourceGen/AsmGen/GenCommon.cs +++ b/SourceGen/AsmGen/GenCommon.cs @@ -445,12 +445,13 @@ namespace SourceGen.AsmGen { if (dfd.FormatSubType == FormatDescriptor.SubType.None) { return true; } + Debug.Assert(dfd.IsAlignedJunk); // Just check the address. Shouldn't need to check the length. int lastOffset = offset + dfd.Length - 1; int alignToAddr = addrMap.OffsetToAddress(lastOffset) + 1; int alignPwr = FormatDescriptor.AlignmentToPower(dfd.FormatSubType); - int alignMask = alignPwr - 1; + int alignMask = (1 << alignPwr) - 1; bool result = (alignToAddr & alignMask) == 0; //Debug.WriteLine(dfd.FormatSubType + " at +" + offset.ToString("x6") + // "(" + alignToAddr.ToString("x4") + "): " + result); diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs index e902e3d..d2ddcba 100644 --- a/SourceGen/DisasmProject.cs +++ b/SourceGen/DisasmProject.cs @@ -441,6 +441,7 @@ namespace SourceGen { /// /// Walks the list of format descriptors, fixing places where the data doesn't match. + /// This is run once, after the file is loaded. /// private void FixAndValidate(ref FileLoadReport report) { // Can't modify a list while we're iterating through it, so gather changes here. @@ -863,10 +864,11 @@ namespace SourceGen { foreach (KeyValuePair kvp in OperandFormats) { int offset = kvp.Key; + FormatDescriptor dfd = kvp.Value; // Check offset. if (offset < 0 || offset >= mFileData.Length) { - string msg = "invalid offset (desc=" + kvp.Value + ")"; + string msg = "invalid offset (desc=" + dfd + ")"; genLog.LogE("+" + offset.ToString("x6") + ": " + msg); Messages.Add(new MessageList.MessageEntry( MessageList.MessageEntry.SeverityLevel.Error, @@ -879,8 +881,8 @@ namespace SourceGen { } // Make sure it doesn't run off the end - if (offset + kvp.Value.Length > mFileData.Length) { - string msg = "invalid offset+len: len=" + kvp.Value.Length + + if (offset + dfd.Length > mFileData.Length) { + string msg = "invalid offset+len: len=" + dfd.Length + " file=" + mFileData.Length; genLog.LogE("+" + offset.ToString("x6") + ": " + msg); Messages.Add(new MessageList.MessageEntry( @@ -893,8 +895,8 @@ namespace SourceGen { continue; } - if (!AddrMap.IsContiguous(offset, kvp.Value.Length)) { - string msg = "descriptor straddles address change; len=" + kvp.Value.Length; + if (!AddrMap.IsContiguous(offset, dfd.Length)) { + string msg = "descriptor straddles address change; len=" + dfd.Length; genLog.LogE("+" + offset.ToString("x6") + ": " + msg); Messages.Add(new MessageList.MessageEntry( MessageList.MessageEntry.SeverityLevel.Warning, @@ -909,9 +911,9 @@ namespace SourceGen { // Check length for instruction formatters. This can happen if you format // a bunch of bytes as single-byte data items and then add a code entry // point. - if (kvp.Value.Length != mAnattribs[offset].Length) { + if (dfd.Length != mAnattribs[offset].Length) { string msg = "unexpected length on instr format descriptor (" + - kvp.Value.Length + " vs " + mAnattribs[offset].Length + ")"; + dfd.Length + " vs " + mAnattribs[offset].Length + ")"; genLog.LogW("+" + offset.ToString("x6") + ": " + msg); Messages.Add(new MessageList.MessageEntry( MessageList.MessageEntry.SeverityLevel.Warning, @@ -921,7 +923,7 @@ namespace SourceGen { MessageList.MessageEntry.ProblemResolution.FormatDescriptorIgnored)); continue; } - if (kvp.Value.Length == 1) { + if (dfd.Length == 1) { // No operand to format! string msg = "unexpected format descriptor on single-byte op"; genLog.LogW("+" + offset.ToString("x6") + ": " + msg); @@ -933,8 +935,8 @@ namespace SourceGen { MessageList.MessageEntry.ProblemResolution.FormatDescriptorIgnored)); continue; } - if (!kvp.Value.IsValidForInstruction) { - string msg = "descriptor not valid for instruction: " + kvp.Value; + if (!dfd.IsValidForInstruction) { + string msg = "descriptor not valid for instruction: " + dfd; genLog.LogW("+" + offset.ToString("x6") + ": " + msg); Messages.Add(new MessageList.MessageEntry( MessageList.MessageEntry.SeverityLevel.Warning, @@ -969,7 +971,7 @@ namespace SourceGen { // All instruction bytes have been marked, so we just need to confirm that // none of the bytes spanned by this descriptor are instructions. bool overlap = false; - for (int i = offset; i < offset + kvp.Value.Length; i++) { + for (int i = offset; i < offset + dfd.Length; i++) { if (mAnattribs[i].IsInstruction) { string msg = "data format descriptor overlaps code at +" + i.ToString("x6"); @@ -987,10 +989,31 @@ namespace SourceGen { if (overlap) { continue; } + +#if false + // Check junk+align directive. We don't outright reject the descriptor, + // because it still works as junk+unalign, but we want to add a warning + // message. + // + // NOTE: currently disabled because some relevant changes, such as editing + // a format descriptor sub-type, don't cause data re-analysis. I don't think + // this is important enough to special-case or implement elsewhere. + if (dfd.IsAlignedJunk) { + if (!AsmGen.GenCommon.CheckJunkAlign(offset, dfd, AddrMap)) { + string msg = "junk alignment not valid"; + Messages.Add(new MessageList.MessageEntry( + MessageList.MessageEntry.SeverityLevel.Info, + offset, + MessageList.MessageEntry.MessageType.InvalidDescriptor, + msg, + MessageList.MessageEntry.ProblemResolution.None)); + } + } +#endif } // All tests passed. Apply the descriptor. - mAnattribs[offset].DataDescriptor = kvp.Value; + mAnattribs[offset].DataDescriptor = dfd; } } diff --git a/SourceGen/FormatDescriptor.cs b/SourceGen/FormatDescriptor.cs index 07ddfaa..9fd836e 100644 --- a/SourceGen/FormatDescriptor.cs +++ b/SourceGen/FormatDescriptor.cs @@ -392,6 +392,9 @@ namespace SourceGen { /// Returns true if the sub-type is exclusively for use with the Junk type. Notably, /// returns false for SubType.None. /// + public bool IsAlignedJunk { + get { return IsJunkSubType(FormatSubType); } + } private static bool IsJunkSubType(SubType subType) { return ((int)subType >= (int)SubType.Align2 && (int)subType <= (int)SubType.Align65536);