Show "ptr" for pointer use in cross-reference list

Consider:
 LDA $00 loads a value from address $00
 LDA $00,X might load from $00, or might not
 LDA ($00),Y dereferences $00 as a 16-bit pointer
 LDA ($00,X) dereferences a pointer, not necessarily from $00

When perusing the cross-reference list, it's useful to be able to
tell whether an instruction is accessing the location, using it as a
base address, or deferencing it as a pointer.  We now show "ptr" in
the list for pointer dereferences.  (We already showed "idx" for
indexed accesses.)
This commit is contained in:
Andy McFadden 2020-09-04 13:26:41 -07:00
parent 7c506dceb6
commit bd5b556a7f
5 changed files with 61 additions and 15 deletions

View File

@ -253,6 +253,23 @@ namespace Asm65 {
}
}
/// <summary>
/// True for instructions that dereference the operand.
/// </summary>
public bool IsPointerAccessInstruction {
get {
return AddrMode == AddressMode.DPIndexXInd ||
AddrMode == AddressMode.DPInd ||
AddrMode == AddressMode.DPIndLong ||
AddrMode == AddressMode.DPIndIndexY ||
AddrMode == AddressMode.DPIndIndexYLong ||
// indirect JMP/JSR
AddrMode == AddressMode.AbsInd ||
AddrMode == AddressMode.AbsIndLong ||
AddrMode == AddressMode.AbsIndexXInd;
}
}
/// <summary>
/// True if this is an absolute-address instruction whose operand is combined with
/// the Program Bank Register.

View File

@ -1550,7 +1550,7 @@ namespace SourceGen {
XrefSet.XrefType xrefType = XrefSet.XrefType.Unknown;
OpDef.MemoryEffect accType = OpDef.MemoryEffect.Unknown;
bool isIndexedDirect = false;
XrefSet.Xref.AccessFlags accessFlags = XrefSet.Xref.AccessFlags.None;
if (attr.IsInstruction) {
OpDef op = CpuDef.GetOpDef(FileData[offset]);
if (op.IsSubroutineCall) {
@ -1560,7 +1560,12 @@ namespace SourceGen {
} else {
xrefType = XrefSet.XrefType.MemAccessOp;
accType = op.MemEffect;
isIndexedDirect = op.IsIndexedAccessInstruction;
}
if (op.IsIndexedAccessInstruction) {
accessFlags |= XrefSet.Xref.AccessFlags.Indexed;
}
if (op.IsPointerAccessInstruction) {
accessFlags |= XrefSet.Xref.AccessFlags.Pointer;
}
} else if (attr.IsData || attr.IsInlineData) {
xrefType = XrefSet.XrefType.RefFromData;
@ -1589,7 +1594,7 @@ namespace SourceGen {
}
AddXref(symOffset, new XrefSet.Xref(offset, true, xrefType, accType,
isIndexedDirect, adj));
accessFlags, adj));
if (adj == 0) {
hasZeroOffsetSym = true;
}
@ -1601,7 +1606,7 @@ namespace SourceGen {
adj = defSym.Value - operandOffset;
}
defSym.Xrefs.Add(new XrefSet.Xref(offset, true, xrefType, accType,
isIndexedDirect, adj));
accessFlags, adj));
}
} else if (SymbolTable.TryGetValue(dfd.SymbolRef.Label, out Symbol sym)) {
// Is this a reference to a project/platform symbol?
@ -1628,7 +1633,7 @@ namespace SourceGen {
// to tweak the adjustment math appropriately.
}
defSym.Xrefs.Add(new XrefSet.Xref(offset, true, xrefType, accType,
isIndexedDirect, adj));
accessFlags, adj));
} else {
// Can get here if somebody creates an address operand symbol
// that refers to a local variable.
@ -1668,7 +1673,7 @@ namespace SourceGen {
Debug.WriteLine("HEY: found unlabeled addr ref at +" +
offset.ToString("x6"));
AddXref(targetOffset, new XrefSet.Xref(offset, false, xrefType,
accType, isIndexedDirect, 0));
accType, accessFlags, 0));
}
}
@ -1678,7 +1683,7 @@ namespace SourceGen {
// it for the label localizer and possibly the label refactorer.)
if (!hasZeroOffsetSym && attr.IsInstructionStart && attr.OperandOffset >= 0) {
AddXref(attr.OperandOffset, new XrefSet.Xref(offset, false, xrefType,
accType, isIndexedDirect, 0));
accType, accessFlags, 0));
}
}

View File

@ -3741,9 +3741,6 @@ namespace SourceGen {
typeStr = "??! ";
break;
}
if (xr.IsIndexedAccess) {
idxStr = "idx ";
}
break;
default:
Debug.Assert(false);
@ -3751,6 +3748,14 @@ namespace SourceGen {
break;
}
// "LDA (dp,X)" gets both of these
if (xr.IsIndexedAccess) {
idxStr += "idx ";
}
if (xr.IsPointerAccess) {
idxStr += "ptr ";
}
MainWindow.ReferencesListItem rli = new MainWindow.ReferencesListItem(xr.Offset,
formatter.FormatOffset24(xr.Offset),
formatter.FormatAddress(mProject.GetAnattrib(xr.Offset).Address, showBank),
@ -3759,6 +3764,8 @@ namespace SourceGen {
mMainWin.ReferencesList.Add(rli);
}
// TODO(maybe): set the selection to something, instead of just inheriting it?
}
#endregion References panel

View File

@ -259,6 +259,10 @@ data operand, and provides an indication of the nature of the reference:</p>
<p>References from instructions that use indexed addressing
(e.g. <code>LDA addr,Y</code>) will also show "idx" to indicate that
the instruction is using the location as a base address.</p>
<p>References from instructions that treat the address as a pointer
(e.g. <code>LDA (dp),Y</code>) will show "ptr". This makes it easy
to identify the locations that are reading or writing through the
pointer from those that are reading or writing the pointer itself.</p>
<p>This will be prefixed with "Sym" or "Oth" to indicate whether or not
the reference used the label at the current address. To understand
this, consider that addresses can be referenced in different ways.

View File

@ -69,11 +69,24 @@ namespace SourceGen {
/// </summary>
public Asm65.OpDef.MemoryEffect AccType { get; private set; }
[Flags]
public enum AccessFlags {
None = 0,
Indexed = 1 << 0,
Pointer = 1 << 1
}
/// <summary>
/// For Type==MemAccessOp, true if the instruction applies an index offset, to
/// For Type==MemAccessOp, true if the instruction applies an index offset to
/// the operand, meaning the referenced address might not actually be accessed.
/// </summary>
public bool IsIndexedAccess { get; private set; }
public AccessFlags Flags { get; private set; }
public bool IsIndexedAccess {
get { return (Flags & AccessFlags.Indexed) != 0; }
}
public bool IsPointerAccess {
get { return (Flags & AccessFlags.Pointer) != 0; }
}
/// <summary>
/// Adjustment to symbol. For example, "LDA label+2" adds an xref entry to
@ -82,18 +95,18 @@ namespace SourceGen {
public int Adjustment { get; private set; }
public Xref(int offset, bool isByName, XrefType type,
Asm65.OpDef.MemoryEffect accType, bool isIndexedAccess, int adjustment) {
Asm65.OpDef.MemoryEffect accType, AccessFlags accessFlags, int adjustment) {
Offset = offset;
IsByName = isByName;
Type = type;
AccType = accType;
IsIndexedAccess = isIndexedAccess;
Flags = accessFlags;
Adjustment = adjustment;
}
public override string ToString() {
return "Xref off=+" + Offset.ToString("x6") + " sym=" + IsByName +
" type=" + Type + " accType= " + AccType + " idx=" + IsIndexedAccess +
" type=" + Type + " accType= " + AccType + " flags=" + Flags +
" adj=" + Adjustment;
}
}