4 ms·
My faster (?, see [0]) strlen seems to compile (using MIT 68k syntax): > cat > test.asm strlen: movem.l %a0-%a1,-(%sp) movl %a0, %a1 ;
by vardump 9y ago
My faster (?, see [0]) strlen seems to compile (using MIT 68k syntax):
> cat > test.asm
strlen: movem.l %a0-%a1,-(%sp)
movl %a0, %a1 ;# copy a0 to a1
slenloop: tst.b (%a0)+
bne.b slenloop
addq.l #1, %a1
sub.l %a0, %a1
move.l %a1, %d0
movem.l (%sp)+,%a0-%a1
rts
^D
> m68k-linux-gnu-as test.asm && m68k-linux-gnu-objdump -d a.out
a.out: file format elf32-m68k
Disassembly of section .text:
00000000 <strlen>:
0: 48e7 00c0 moveml %a0-%a1,%sp@-
4: 2248 moveal %a0,%a1
00000006 <slenloop>:
6: 4a18 tstb %a0@+
8: 66fc bnes 6 <slenloop>
a: 5289 addql #1,%a1
c: 93c8 subal %a0,%a1
e: 2009 movel %a1,%d0
10: 4cdf 0300 moveml %sp@+,%a0-%a1
14: 4e75 rts
I wonder whether it actually works... I think same idea should be translatable to PDP-11 as well.
[0]: It runs slower for short strings, though. Not sure where the break even point is.
- vardump 9y agoPrevious one didn't work, because I mixed up a0 and a1 pointers when subtracting. But that gave me a new idea: copy pointer to d0 and complement the difference instead of addq, saving a1 register (+stack operations) and a move-instruction: strlen: move.l %a0,-(%sp) movl %a0, %d0 ;# d0 = a0; slenloop: tst.b (%a0)+ ;# test *a0, post incr bneb slenloop ;# loop if non-zero sub.l %a0, %d0 ;# d0 = d0 - a0; not.l %d0 ;# d0 = ~d0; move.l (%sp)+,%a0 rts ;# d0 is the return value Equivalent C-code (http://cpp.sh/2oecd http://cpp.sh/2oecd): #include <stdio.h> #include <stdint.h> size_t strlen68k(char* a0) { int zero_flag; uintptr_t d0 = (uintptr_t) a0; do { // tstb (%a0)+ if (*a0 == 0) zero_flag = 1; else zero_flag = 0; a0++; // (%a0)+ (post increment) } while(!zero_flag); // bneb slenloop d0 = d0 - (uintptr_t) a0; // sub.l %a0, %d0 d0 = ~d0; // not.l %d0 return d0; } void strlen_test(char* str) { printf("str \"%s\" length is %lu\n", str, strlen68k(str)); } int main(void) { strlen_test(""); strlen_test("a"); strlen_test("abcd"); return 0; } Again, untested, but I think it probably works. I guess this is also faster for all string lengths >0 as well. This idea might not work on PDP-11 anymore, depending on how binary arithmetic is implemented.