Skip to content

Amiga: add experimental stack swap support.#88

Merged
sezero merged 1 commit intolibxmp:masterfrom
AliceLR:add-amiga-stackswap
May 7, 2026
Merged

Amiga: add experimental stack swap support.#88
sezero merged 1 commit intolibxmp:masterfrom
AliceLR:add-amiga-stackswap

Conversation

@AliceLR
Copy link
Copy Markdown
Contributor

@AliceLR AliceLR commented Mar 20, 2026

Closes #87.

This is an updated version of the patch, but still very much needs testing. It works fine for me with both m68k toolchains I have set up + libnix for Workbench 2.

@AliceLR AliceLR added this to the 4.3.0 milestone Mar 20, 2026
@AliceLR AliceLR marked this pull request as draft March 20, 2026 01:42
@AliceLR AliceLR force-pushed the add-amiga-stackswap branch from 4302291 to bf5e2b0 Compare March 20, 2026 21:17
@AliceLR
Copy link
Copy Markdown
Contributor Author

AliceLR commented Mar 20, 2026

Updated to borrow the relevant parts from codesets.library, as it has a hand-written inline assembly routine which should be far safer than attempting to use StackSwap in C.

@AliceLR AliceLR force-pushed the add-amiga-stackswap branch from bf5e2b0 to 7d6b8ad Compare March 25, 2026 10:01
@AliceLR
Copy link
Copy Markdown
Contributor Author

AliceLR commented Mar 26, 2026

MorphOS tested, works.

@AliceLR AliceLR force-pushed the add-amiga-stackswap branch 4 times, most recently from 21846e0 to 343488c Compare April 5, 2026 02:02
@AliceLR
Copy link
Copy Markdown
Contributor Author

AliceLR commented Apr 5, 2026

Resolved a -pedantic warning from converting a function pointer to APTR for MorphOS (AROS presumably also affected).

I haven't been able to test OS 4 or AROS yet.

@AliceLR AliceLR marked this pull request as ready for review May 6, 2026 01:22
@AliceLR
Copy link
Copy Markdown
Contributor Author

AliceLR commented May 6, 2026

This should be ready. Please test AROS and fix as necessary, since I can't test it on my end.

@AliceLR AliceLR mentioned this pull request May 6, 2026
3 tasks
@sezero
Copy link
Copy Markdown
Collaborator

sezero commented May 7, 2026

The following is needed for 64 bit Aros: (will run-test shortly)

diff --git a/src/main_amiga.h b/src/main_amiga.h
index cafd4ef..ff602f0 100644
--- a/src/main_amiga.h
+++ b/src/main_amiga.h
@@ -165,7 +165,11 @@ int main(int argc, char **argv)
 			struct main_args args;
 			int ret;
 
+			#ifdef __AROS__
+			sw.stk_Upper = (APTR)((IPTR)sw.stk_Lower + MIN_STACK_SIZE);
+			#else
 			sw.stk_Upper = (ULONG)sw.stk_Lower + MIN_STACK_SIZE;
+			#endif
 			sw.stk_Pointer = (APTR)sw.stk_Upper;
 
 #if 0

One thing is that this relies on gcc for m68k, which may be mostly true,
but VBCC is also used. An #elif defined(__M68K__) && defined(__VBCC__)
case is needed in there but I can't write the asm for it, haven't messed
with that for years. If that's a hassle though, VBCC builds need ignoring
at top of main_amiga.h.

@AliceLR
Copy link
Copy Markdown
Contributor Author

AliceLR commented May 7, 2026

One thing is that this relies on gcc for m68k, which may be mostly true, but VBCC is also used. An #elif defined(__M68K__) && defined(__VBCC__) case is needed in there but I can't write the asm for it, haven't messed with that for years. If that's a hassle though, VBCC builds need ignoring at top of main_amiga.h.

The software I got this asm fragment from did not have VBCC code, so this may have to be disabled for VBCC builds.

The following is needed for 64 bit Aros: (will run-test shortly)

OK, if it works, I can try to patch it in soon. (I don't think xmp uses preprocessor macro style like that, though, it's non-indented almost everywhere.)

@sezero
Copy link
Copy Markdown
Collaborator

sezero commented May 7, 2026

Tested x86_64-aros (linux-hosted version) and it works.

Adjusted the ifdef indentation. Should I force-push the
following to your branch?

Q: Should we double the minimum stack size, e.g. 65536 for 64 bits?
EDIT: I ran the aros x64 version after running stack 4096, it ran just
fine, so I guess no bump is necessary.

diff --git a/src/main_amiga.h b/src/main_amiga.h
index 8da843b0..c3927650 100644
--- a/src/main_amiga.h
+++ b/src/main_amiga.h
@@ -32,7 +32,7 @@
 
 #include "common.h"
 
-#if defined(XMP_AMIGA)
+#if defined(XMP_AMIGA) && !defined(__VBCC__)
 
 #include <proto/exec.h>
 
@@ -165,7 +165,11 @@ int main(int argc, char **argv)
 			struct main_args args;
 			int ret;
 
+#ifdef __AROS__
+			sw.stk_Upper = (APTR)((IPTR)sw.stk_Lower + MIN_STACK_SIZE);
+#else
 			sw.stk_Upper = (ULONG)sw.stk_Lower + MIN_STACK_SIZE;
+#endif
 			sw.stk_Pointer = (APTR)sw.stk_Upper;
 
 #if 0

@AliceLR
Copy link
Copy Markdown
Contributor Author

AliceLR commented May 7, 2026

Tested x86_64-aros (linux-hosted version) and it works.

Adjusted the ifdef indentation. Should I force-push the following to your branch?

OK, I will patch this in soon.

Q: Should we double the minimum stack size, e.g. 65536 for 64 bits? EDIT: I ran the aros x64 version after running stack 4096, it ran just fine, so I guess no bump is necessary.

I don't think that's necessary, because libxmp's stack usage looks something like:

  • 16k + change when computing an MD5.
  • 16k + change when depacking with an external depacker (edit: except for the XFD depacker, which allocates buffers).
  • Otherwise, predominantly structs in loaders that do not contain very many (if any) pointers or size_t. I didn't thoroughly test this, but XM and/or playback was fine with an 8k stack when I patched the aforementioned 16k buffers to be 2k. I highly doubt any individual loader is capable of putting 32k on the stack, but if I'm wrong, we can fix it later. (:
  • Glad we got rid of alloca in stb_vorbis or it'd be another consideration here... I didn't test any OggMod XMs though, so I don't know how much it puts on the stack outside of that.

@sezero
Copy link
Copy Markdown
Collaborator

sezero commented May 7, 2026

Tested x86_64-aros (linux-hosted version) and it works.
Adjusted the ifdef indentation. Should I force-push the following to your branch?

OK, I will patch this in soon.

Looked at vbcc: we don't have m68k asm for it but it responds to global var __stack
which you provide: Updated patch below.

diff --git a/src/main_amiga.h b/src/main_amiga.h
index 8da843b..931fec2 100644
--- a/src/main_amiga.h
+++ b/src/main_amiga.h
@@ -52,6 +52,11 @@ const char XMP_USED stack_cookie[] = "$STACK: 32768";
 extern int __stack;
 int XMP_USED __stack = MIN_STACK_SIZE;
 
+#if defined(__VBCC__) && !defined(XMP_NO_STACKSWAP)
+/* no m68k asm for vbcc, but it responds to global var `__stack` */
+#define XMP_NO_STACKSWAP
+#endif
+
 /* Workbench 2.04 through 3.1: manually set stack size via StackSwap.
  * This needs to be performed through inline ASM to be safe.
  *
@@ -165,7 +170,11 @@ int main(int argc, char **argv)
 			struct main_args args;
 			int ret;
 
+#ifdef __AROS__
+			sw.stk_Upper = (APTR)((IPTR)sw.stk_Lower + MIN_STACK_SIZE);
+#else
 			sw.stk_Upper = (ULONG)sw.stk_Lower + MIN_STACK_SIZE;
+#endif
 			sw.stk_Pointer = (APTR)sw.stk_Upper;
 
 #if 0

Q: Should we double the minimum stack size, e.g. 65536 for 64 bits? EDIT: I ran the aros x64 version after running stack 4096, it ran just fine, so I guess no bump is necessary.

I don't think that's necessary, because libxmp's stack usage looks something like:

* 16k + change when computing an MD5.

* 16k + change when depacking with an external depacker (edit: except for the XFD depacker, which allocates buffers).

* Otherwise, predominantly structs in loaders that do not contain very many (if any) pointers or `size_t`. I didn't thoroughly test this, but XM and/or playback was fine with an 8k stack when I patched the aforementioned 16k buffers to be 2k. I highly doubt any individual loader is capable of putting 32k on the stack, but if I'm wrong, we can fix it later. (:

* Glad we got rid of `alloca` in stb_vorbis or it'd be another consideration here... I didn't test any OggMod XMs though, so I don't know how much it puts on the stack outside of that.

OK :)

* Workbench 2.04 onward: use StackSwap (inline ASM borrowed from
  codesets.library, LGPL 2.1).
* AROS: use NewStackSwap.
* MorphOS: use NewPPCStackSwap.
* AmigaOS 3.2, 4.x: use a stack cookie.
* VBCC: use __stack.

Co-authored-by: Özkan Sezer <sezero@users.noreply.github.com>
@AliceLR AliceLR force-pushed the add-amiga-stackswap branch from 343488c to d0ac3ca Compare May 7, 2026 11:00
@AliceLR
Copy link
Copy Markdown
Contributor Author

AliceLR commented May 7, 2026

OK, I've applied the vbcc and AROS patch.

Looked at vbcc: we don't have m68k asm for it but it responds to global var __stack which you provide: Updated patch below.

+#if defined(__VBCC__) && !defined(XMP_NO_STACKSWAP)
+/* no m68k asm for vbcc, but it responds to global var `__stack` */
+#define XMP_NO_STACKSWAP
+#endif

I slimmed this part down a little bit by combining it into the existing #if, though.

@AliceLR AliceLR requested a review from sezero May 7, 2026 11:02
@sezero sezero merged commit 353c8b0 into libxmp:master May 7, 2026
1 check passed
@AliceLR AliceLR deleted the add-amiga-stackswap branch May 7, 2026 20:37
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.

Amiga: automatically set stack size?

2 participants