View Single Post
Old 22 October 2021, 08:53   #4
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
Quote:
Originally Posted by Jobbo View Post
I've found the need to write what is essentially a switch case.

Is there a better approach than the one I've got below?

Or is there a cleaner way to specify the same code?
The best method depends on your goals.

You want it to be "clean", and not necessarily the fastest ?
Better not to mix data and code then, and thus you have to care about the extremely limited range of (pc,ix) addressing.
This gives :
Code:
 lea tbl(pc),a0
 add.w d1,d1
 adda.w (a0,d1.w),a0
 jmp (a0)

; moved after code
tbl
 dc.w case0-tbl,case1-tbl,case2-tbl,case3-tbl,...
You did not specify the cpu type, so bare 68000 is assumed.
But if you can run code on 68020+, then :
Code:
 lea tbl(pc),a0
 adda.w (a0,d1.w*2),a0
 jmp (a0)

tbl
 dc.w case0-tbl,case1-tbl,case2-tbl,case3-tbl,...
Otherwise if the goal is speed, the fastest method might depend on the number of cases and their relative frequency.

For example :
Code:
 subq.w #1,d1
 bcs.s .case0
 beq.s .case1
 subq.w #2,d1
 bcs.s .case2
 beq.s .case3
 subq.w #2,d1
 bcs.s .case4
 beq.s .case5
; .case6 here (if range is only 0-6)
If there are few cases, if .case0 is by far the most common, and then they have decreasing frequency, then this is the fastest method.

Else, it can be the usual pair of (pc,ix) or fixed size routines - as already mentioned.

Using direct 32-bit pointers might be faster than word table (not sure for 68000 but on 020+ it is). You can preload another register with the table address :
Code:
; this goes in init code
 lea tbl,a0

; normal code
 add.w d1,d1
 add.w d1,d1
 move.l (a0,d1.w),a1    ; on 020+, use (a0,d1.w*4)
 jmp (a1)

; table
 dc.l case0,case1,case2,case3,...
meynaf is offline  
 
Page generated in 0.04858 seconds with 11 queries