8000 memset: load the registers and loop in one asm statement, as wmemset by codewiz · Pull Request #90 · AmigaPorts/libnix · GitHub
[go: up one dir, main page]

Skip to content

memset: load the registers and loop in one asm statement, as wmemset - #90

Merged
codewiz merged 2 commits into
masterfrom
memset-movem
Nov 4, 2026
Merged

codewiz merged 2 commits into
masterfrom
memset-movem

Conversation

@codewiz
@codewiz codewiz commented Nov 4, 2026
Copy link
Copy Markdown
Member

Follow-up to #88, which fixed the same pattern in wmemset(): @reinauer found that memset() has it too (#88 (review)).

The move.l %0,d5 statements before the movem loop only clobbered d5-d7, a1-a3 and a6, so nothing kept those registers intact until the movem, which also had no "memory" clobber. At -Og gcc reuses them in between, and the fill goes wrong.

The registers are now loaded and the loop run in one asm statement, as in #88. The rest keeps its structure: align, 32 bytes at a time with movem, then longs, then bytes. Every store now takes its operands as "+a"/"d" with a "memory" clobber. Before, the byte loop named d2 directly, and -(%0) relied on register ... asm("a0") pinning to get an address register. The stores stay in asm so that gcc can't turn the loops back into a call to memset().

Tested

test/memset.c is new, in make check-target: every length from 0 to 150 at four alignments, guards on both sides, and a value with high bits set (0x1a5). Under volamos, with memset.c built at each level and the test at -O2 -fno-builtin, failures out of 604:

memset.c flags CPU master this PR bytes, this PR
-O0 68000 0 0 280
-Og 68000 470 0 136
-O0 -m68020 68020 0 0 280
-O1 68000 0 0 160
-O2 68000 0 0 156
-O3 68000 0 0 204
-Os 68000 0 0 160
-O2 -fomit-frame-pointer 68000 0 0 156
-O2 -fbaserel 68000 0 0 156
-Os -m68020 68020 0 0 160
-O2 -m68060 -fomit-frame-pointer 68060 0 0 156

At -O2, the level libnix builds the string functions at, it goes from 168 to 156 bytes. The inner loop is the same movem.l as before.

🤖 Generated with Claude Code

@codewiz
codewiz commented Nov 4, 2026
Copy link
Copy Markdown
Member Author

Cc: @bebbo

@reinauer reinauer left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, with the same one-character fix as #88. m needs an early clobber, "+&d" (m), so that gcc can't put it and c in the same register when it knows both values (see #88). In memset() that takes equal constants for c and n / 32, so it's even less likely than in wmemset(), but it's free.

Otherwise, the rest:

  • The byte and word stores before the loop and the long and byte loops after it now take "+a"/"d" with "memory", so nothing depends on register ... asm() pinning any more.
  • c = (unsigned char) _c replaces the old c &= 0xff, now for every length and not only above 18. The byte loop used d2 directly, so it already stored the right low byte; your 0x1a5 test covers that.
  • GitHub shows it conflicting now. That's probably test/Makefile, where #89 added multibyte next to where this adds memset, so it needs a rebase.

codewiz and others added 2 commits November 4, 2026 15:04
At -Og gcc reused the registers between loading them and the movem.  The
stores now take their operands rather than naming d2 and relying on pinning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As in wmemset: without it gcc may give the count and the fill value one
register when it knows both are equal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codewiz
codewiz commented Nov 4, 2026
Copy link
Copy Markdown
Member Author

Rebased onto master (now with #88 and #89) and added "+&d" (m) as its own commit, as in #88. The memset, wmemset and multibyte tests pass under volamos at -O1, -O2, -Os and -Og, and the full target suite at -O2. @reinauer could you approve it?

@codewiz
codewiz requested a review from reinauer November 4, 2026 06:06
@codewiz
codewiz merged commit 3822052 into master Nov 4, 2026
2 checks passed
@codewiz
codewiz deleted the memset-movem branch November 4, 2026 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0