Quote:
Originally Posted by Jobbo
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,...