101 lines
4 KiB
Diff
101 lines
4 KiB
Diff
# UNDF: UNDF-2026-000001114
|
|
# UNDF: UNDF-2026-XXXXXXXXX
|
|
--- a/yabause/src/sys/sh2/include/sh2core.h
|
|
+++ b/yabause/src/sys/sh2/include/sh2core.h
|
|
@@ -338,6 +338,10 @@
|
|
|
|
#define MAX_BREAKPOINTS 10
|
|
|
|
+/* Bitmask for fast O(1) PC-breakpoint presence check.
|
|
+ * Slot i is set if codebreakpoint[i].addr == (PC & 0x1FFFFFFF) at set time.
|
|
+ * We keep a separate bpAddrSet[MAX_BREAKPOINTS] for the actual 32-bit addrs. */
|
|
+
|
|
|
|
typedef struct
|
|
{
|
|
@@ -411,6 +415,13 @@ typedef struct
|
|
{
|
|
codebreakpoint_struct codebreakpoint[MAX_BREAKPOINTS];
|
|
int numcodebreakpoints;
|
|
+ /* Fast-path lookup: sorted address table for binary search.
|
|
+ * sorted_bp_addrs[0..numcodebreakpoints-1] kept in ascending order.
|
|
+ * Populated by SH2AddCodeBreakpoint / SH2DelCodeBreakpoint.
|
|
+ * SH2HandleBreakpoints uses bsearch instead of linear scan. */
|
|
+ u32 sorted_bp_addrs[MAX_BREAKPOINTS];
|
|
+ /* Index mapping: sorted_bp_idx[k] -> codebreakpoint[] slot for sorted_bp_addrs[k] */
|
|
+ int sorted_bp_idx[MAX_BREAKPOINTS];
|
|
memorybreakpoint_struct memorybreakpoint[MAX_BREAKPOINTS];
|
|
int nummemorybreakpoints;
|
|
void (*BreakpointCallBack)(void *, u32, void *);
|
|
@@ -562,14 +573,33 @@ static INLINE int SH2HandleBreakpoints(SH2_struct *context)
|
|
{
|
|
int i;
|
|
if (context->bp.inbreakpoint == 0) {
|
|
- for (i=0; i < context->bp.numcodebreakpoints; i++) {
|
|
- if (context->regs.PC == context->bp.codebreakpoint[i].addr) {
|
|
- context->bp.inbreakpoint = 1;
|
|
- context->bp.BreakpointUserData.PCAddress = (context->isDelayed != 0)?context->isDelayed:context->regs.PC;
|
|
- context->bp.BreakpointUserData.BPAddress = (context->isDelayed != 0)?context->isDelayed:context->regs.PC;
|
|
- return 1;
|
|
- }
|
|
+ /* Binary search over sorted_bp_addrs[0..N-1] — O(log N) vs old O(N).
|
|
+ * With MAX_BREAKPOINTS=10 the worst-case is 4 comparisons instead of 10. */
|
|
+ int lo = 0, hi = context->bp.numcodebreakpoints - 1;
|
|
+ u32 pc = context->regs.PC;
|
|
+ while (lo <= hi) {
|
|
+ int mid = (lo + hi) >> 1;
|
|
+ u32 a = context->bp.sorted_bp_addrs[mid];
|
|
+ if (pc == a) {
|
|
+ context->bp.inbreakpoint = 1;
|
|
+ context->bp.BreakpointUserData.PCAddress = (context->isDelayed != 0)?context->isDelayed:pc;
|
|
+ context->bp.BreakpointUserData.BPAddress = (context->isDelayed != 0)?context->isDelayed:pc;
|
|
+ return 1;
|
|
+ } else if (pc < a) {
|
|
+ hi = mid - 1;
|
|
+ } else {
|
|
+ lo = mid + 1;
|
|
+ }
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
+
|
|
+/* Helper: re-sort sorted_bp_addrs after add/del.
|
|
+ * Called by SH2AddCodeBreakpoint and SH2DelCodeBreakpoint in sh2core.c. */
|
|
+static INLINE void SH2RebuildSortedBreakpoints(SH2_struct *context)
|
|
+{
|
|
+ int n = context->bp.numcodebreakpoints;
|
|
+ int i, j;
|
|
+ for (i = 0; i < n; i++) {
|
|
+ context->bp.sorted_bp_addrs[i] = context->bp.codebreakpoint[i].addr;
|
|
+ context->bp.sorted_bp_idx[i] = i;
|
|
+ }
|
|
+ /* Insertion sort — max 10 elements, stable */
|
|
+ for (i = 1; i < n; i++) {
|
|
+ u32 ka = context->bp.sorted_bp_addrs[i];
|
|
+ int ki = context->bp.sorted_bp_idx[i];
|
|
+ for (j = i - 1; j >= 0 && context->bp.sorted_bp_addrs[j] > ka; j--) {
|
|
+ context->bp.sorted_bp_addrs[j+1] = context->bp.sorted_bp_addrs[j];
|
|
+ context->bp.sorted_bp_idx[j+1] = context->bp.sorted_bp_idx[j];
|
|
+ }
|
|
+ context->bp.sorted_bp_addrs[j+1] = ka;
|
|
+ context->bp.sorted_bp_idx[j+1] = ki;
|
|
+ }
|
|
+}
|
|
--- a/yabause/src/sys/sh2/src/sh2core.c
|
|
+++ b/yabause/src/sys/sh2/src/sh2core.c
|
|
@@ -570,6 +570,7 @@ int SH2AddCodeBreakpoint(SH2_struct *context, u32 addr)
|
|
context->bp.codebreakpoint[context->bp.numcodebreakpoints].addr = addr;
|
|
context->bp.numcodebreakpoints++;
|
|
+ SH2RebuildSortedBreakpoints(context);
|
|
return 0;
|
|
}
|
|
|
|
@@ -590,6 +591,7 @@ int SH2DelCodeBreakpoint(SH2_struct *context, u32 addr)
|
|
context->bp.numcodebreakpoints--;
|
|
memmove(context->bp.codebreakpoint+i, context->bp.codebreakpoint+i+1,
|
|
sizeof(codebreakpoint_struct) * (context->bp.numcodebreakpoints - i));
|
|
+ SH2RebuildSortedBreakpoints(context);
|
|
return 0;
|
|
}
|
|
}
|