diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/bitswap.S | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/firmware/bitswap.S b/firmware/bitswap.S index f825be22d1..9a4f760261 100644 --- a/firmware/bitswap.S +++ b/firmware/bitswap.S | |||
@@ -25,28 +25,56 @@ | |||
25 | /* Registers used: | 25 | /* Registers used: |
26 | * | 26 | * |
27 | * r0 Temporary (required by some instructions) | 27 | * r0 Temporary (required by some instructions) |
28 | * r1 Flip table | 28 | * r1 Low byte |
29 | * r4 Argument: Data pointer | 29 | * r2 High byte |
30 | * r5 Argument: Length (in bytes) | 30 | * r3 Result after flip |
31 | * r4 Data | ||
32 | * r5 Length | ||
33 | * r6 1 | ||
34 | * r7 Flip table | ||
31 | */ | 35 | */ |
32 | 36 | ||
33 | /* TODO: Optimize for DRAM burst operation by reading and writing in chunks | ||
34 | We do not want to optimize by reading/writing words, because the data | ||
35 | pointer may be odd */ | ||
36 | |||
37 | _bitswap: | 37 | _bitswap: |
38 | mov.l .fliptable,r1 | 38 | mov.l .fliptable,r7 |
39 | add r4,r5 /* Calculate end of buffer */ | 39 | mov #1,r6 |
40 | mov r4,r0 | ||
41 | and #1,r0 /* odd address? */ | ||
42 | cmp/eq #0,r0 | ||
43 | bt .init /* no, address is even */ | ||
44 | |||
45 | mov.b @r4,r0 /* swap first byte */ | ||
46 | extu.b r0,r0 | ||
47 | mov.b @(r0,r7),r0 | ||
48 | mov.b r0,@r4 | ||
49 | add #1,r4 | ||
50 | add #-1,r5 | ||
40 | bra .init | 51 | bra .init |
41 | .loop: | 52 | .loop: |
42 | mov.b @r4,r0 /* Data to flip */ | 53 | mov.w @r4,r1 /* data to flip */ |
43 | extu.b r0,r0 /* Zero extend */ | 54 | swap.b r1,r2 |
44 | mov.b @(r0,r1),r0 /* Look up in the flip table */ | 55 | extu.b r2,r0 /* high byte */ |
45 | mov.b r0,@r4 /* Store result */ | 56 | mov.b @(r0,r7),r2 |
46 | add #1,r4 | 57 | extu.b r2,r0 /* Zero extend */ |
58 | swap.b r0,r3 /* put high byte in result */ | ||
59 | extu.b r1,r0 /* low byte */ | ||
60 | mov.b @(r0,r7),r1 | ||
61 | extu.b r1,r0 /* Zero extend */ | ||
62 | or r0,r3 /* put low byte in result */ | ||
63 | mov.w r3,@r4 /* store result */ | ||
64 | add #2,r4 | ||
65 | add #-2,r5 | ||
47 | .init: | 66 | .init: |
48 | cmp/gt r4,r5 /* while (dataptr < start+length) */ | 67 | cmp/gt r6,r5 /* while [bytes remaining] > 1 */ |
49 | bt .loop | 68 | bt .loop /* (at least 2 bytes left) */ |
69 | |||
70 | cmp/eq r6,r5 | ||
71 | bf .exit /* if not 1 byte left, exit */ | ||
72 | |||
73 | mov.b @r4,r0 /* swap last byte */ | ||
74 | extu.b r0,r0 | ||
75 | mov.b @(r0,r7),r0 | ||
76 | mov.b r0,@r4 | ||
77 | .exit: | ||
50 | rts | 78 | rts |
51 | 79 | ||
52 | .align 4 | 80 | .align 4 |