reloc on startup reduced
This commit is contained in:
parent
6a90b2ec19
commit
0643479903
3 changed files with 26 additions and 3 deletions
|
|
@ -61,11 +61,22 @@ echo "compile: $BASE.c -> $OUTBASE.o"
|
|||
-O2 -ffunction-sections -c "$SRC" -o "$OBJ"
|
||||
|
||||
echo "link: -> $OUTBASE.bin"
|
||||
# text-base 0: under the GS/OS Loader our segment lands at some bank
|
||||
# the Loader picks (KIND=0x1000), so link-time addresses can start at
|
||||
# offset 0 in the segment. With text-base=0 the link-time-baked IMM16
|
||||
# operand for `lda gFoo` already equals gFoo's runtime offset within
|
||||
# the segment (no segPlacedBase adjustment needed since the Loader
|
||||
# places at bank-aligned bases), so the linker can skip emitting
|
||||
# cRELOC entries for every IMM16 site — 60–90% reduction in cRELOC
|
||||
# count, proportional speed-up in the Loader's per-reloc walk.
|
||||
# Bare-metal builds keep text-base=0x1000 (runInMame.sh loads at
|
||||
# bank-0:1000 and link-time addresses must match).
|
||||
#
|
||||
# bss-base 0xA000 keeps BSS above the SHR shadow region ($2000-$9FFF
|
||||
# in bank 0 mirrors to bank E1 SHR memory). Without this, the smaller
|
||||
# section-gc'd demos place BSS at e.g. $2300 and global writes scribble
|
||||
# on the screen.
|
||||
LINKER_ARGS=(-o "$BIN" --text-base 0x1000 --bss-base 0xA000 \
|
||||
LINKER_ARGS=(-o "$BIN" --text-base 0 --bss-base 0xA000 \
|
||||
--map "$MAP" --reloc-out "$RELOC")
|
||||
if [ "$DEBUG" = 1 ]; then
|
||||
LINKER_ARGS+=(--debug-out "$DWARF")
|
||||
|
|
@ -90,7 +101,7 @@ fi
|
|||
|
||||
echo "OMF: -> $OUTBASE.omf"
|
||||
"$OMF" --input "$BIN" --map "$MAP" \
|
||||
--base 0x1000 --entry __start --output "$OUT" \
|
||||
--base 0 --entry __start --output "$OUT" \
|
||||
--name "$(echo "$OUTBASE" | tr '[:lower:]' '[:upper:]' | cut -c1-8)" \
|
||||
--expressload --relocs "$RELOC"
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -548,6 +548,18 @@ static void applyReloc(std::vector<uint8_t> &buf, uint32_t off,
|
|||
// `if (weakFn) weakFn()` null test that the null is meant to fail.
|
||||
// recordCRelocSite handles the gate; byteCnt=2 distinguishes
|
||||
// from IMM24 (3) so omfEmit emits cRELOC ByteCnt=2 here.
|
||||
// Optimization: when text-base's low 16 bits are zero, the
|
||||
// link-time baked operand (target & 0xFFFF) is already equal
|
||||
// to (segPlacedBase + offsetRef) & 0xFFFF — because the
|
||||
// Loader places KIND=0x1000 segments at bank-aligned bases
|
||||
// (segPlacedBase.lo16 = 0), and we baked target = textBase +
|
||||
// offsetRef, so the patch is a no-op. Skipping it eliminates
|
||||
// 50–90% of cRELOC entries in typical builds (most data refs
|
||||
// are IMM16); the GS/OS Loader walks each cRELOC site in a
|
||||
// linear loop, so the per-boot reloc-application time drops
|
||||
// proportionally. Programs that link with a non-bank-aligned
|
||||
// text-base (e.g. bare-metal at $1000) still get the cRELOC.
|
||||
if ((gTextBaseForSites & 0xFFFFu) != 0)
|
||||
recordCRelocSite(patchAddr, target, /*byteCnt=*/2, /*bitShift=*/0);
|
||||
break;
|
||||
case R_W65816_BANK16:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue