Live data from Hacker News

Make the most of compiled C loops on the 68000

dciabrin.net

1–10 of 20 posts

Re: Make the most of compiled C loops on the 68000

#3
The step with declaring hw registers in assembly reminds me how assignment of value to pointer is IIRC at best implementation defined, and at worst UB, and playing around with volatile saves you not from zealous optimizer.

Arguably every hardware register should be declared that way as a symbol

Re: Make the most of compiled C loops on the 68000

#5
Interestingly, gcc-amigaos-gcc 6.5 uses dbra without having to jump through any of those contortions, as long as the optimisation level is set to at least -O1:

  _clear_screen:
        move.w #28672,3932160
        move.w #1,3932164
        move.l #3932162,a0
        move.w #-13570,d1
        move.w #1279,d0
  .L2:
        move.w d1,(a0)
        dbra d0,.L2
        rts

Re: Make the most of compiled C loops on the 68000

#6
SNK were the gods of the 68000. I still remember back in the day getting a bug report on my 68000 emulator:

When playing King of Fighters, the time counter would go down to 0 and then wrap around to 99, effectively preventing the round from ending.

Eventually I tracked it down to the behavior of SBCD (Subtract Binary Coded Decimal): Internally, the chip actually does update the overflow flag reliably (it's marked as undefined in the docs). SNK was checking the V flag and ending the round when it got set.

https://github.com/kstenerud/Musashi/blob/master/m68k_in.c#L...

SBCD was an old throwback instruction that was hardly used anymore, and the register variant took 6 cycles to complete (vs 4 for binary subtraction).

HOWEVER... For displaying the timer counter on-screen, they saved a ton of cycles with this scheme because extracting the digits from a BCD value is a simple shift by 4 bits (6 cycles) rather than a VERY expensive divide (140 cycles).

Re: Make the most of compiled C loops on the 68000

#7
post #3

The step with declaring hw registers in assembly reminds me how assignment of value to pointer is IIRC at best implementation defined, and at worst UB, and playing around with volatile saves you not from zealous optimizer. Arguably every hardware register should be declared that way as a symbol

That was a common feature on Borland and Microsoft compilers for MS-DOS.

Re: Make the most of compiled C loops on the 68000

#8
> Note how gcc is smart enough to detect that the expression ((0xcThis is actually required rather than an optimisation for any C compiler, from early on, as C semantically allows constant expressions rather than just constants to be used for statically allocated sizes, etc. While the 'optimisation' is not guaranteed you'll see even on -O0 the constant was evaluated at compile-time, as it's harder to not fold constant expressions sometimes than it is to just always fold them for the already required constant expression features.

Re: Make the most of compiled C loops on the 68000

#9

Interestingly, gcc-amigaos-gcc 6.5 uses dbra without having to jump through any of those contortions, as long as the optimisation level is set to at least -O1: _clear_screen: move.w #28672,3932160 move.w #1,3932164 move.l #3932162,a0 move.w #-13570,d1 move.w #1279,d0 .L2: move.w d1,(a0) dbra d0,.L2 rts

I tried this with the old SAS/C Amiga compiler. It put addresses in A0 and then moved value into (A0) on next instruction, so the setup part was a bit more inefficient. And refused to use "dbra" no matter what I tried.
Post reply on HN