Bun Runner Devlog -- 2025-01-10
Not much in the way of visuals to show this week. My focus has been to flesh out more of the unit test suite, allowing me to fix a few bugs in the process as well as perform some nice optimizations on some oft-called code.
I also discovered a good, extensible approach to building switch statements
in assember without using a big list of CMP
/BEQ
statements, which requires
writing lots of code and is also costly execution-wise. Any code I’ve run
into that uses the CMP
/BEQ
approach I’ve been converting to this new approach,
which is another reason for no real visuals this week.
The approach comes from a post on English Amiga Board: https://eab.abime.net/showpost.php?p=1548231&postcount=7
The example in the post is specific to the original asker’s use case, so I’ll provide a more generic example for DevPac, along with a unit test written in CuTest for SAS/C:
; switch.asm
ENUM ; MyChoices
EITEM ItemOne
EITEM ItemTwo
EITEM ItemThree
; make accessible to C
XDEF _MySwitch
; @inreg D0 enum MyChoices
; @outreg D0 final value
_MySwitch:
ADD.W D0,D0 ; jumpTable entries are word sized
MOVE.W .jumpTable(pc,D0.W),D0 ; get the offset from .jumpTargets
JMP .jumpTargets(pc,D0.W) ; go!
.jumpTable:
; these are in enum order
DC.W .itemOne-.jumpTargets
DC.W .itemTwo-.jumpTargets
DC.W .itemThree-.jumpTargets
.jumpTargets:
.itemOne:
MOVE.L #4,D0
RTS
.itemTwo:
MOVE.L #20,D0
RTS
.itemThree:
MOVE.L #50,D0
RTS
// switch_test.c
#include "cutest.h"
enum MyChoices {
ItemOne,
ItemTwo,
ItemThree
};
// this looks for an exported _MySwitch symbol
uint32_t __asm MySwitch(register __d0 uint32_t myChoice);
void T_switch(CuTest *tc) {
uinit32_t result;
result = MySwitch(ItemOne);
CuAssertIntEquals(tc, 4, result);
result = MySwitch(ItemTwo);
CuAssertIntEquals(tc, 20, result);
result = MySwitch(ItemThree);
CuAssertIntEquals(tc, 50, result);
}
void switchSuite(CuSuite *suite) {
SUITE_ADD_TEST(suite, T_switch);
}