15662a7bb80be652e6d98ab90fda005a0d907bd4
[picodrive.git] / pico / misc_arm.s
1 /*
2  * Generic memory routines.
3  * (C) notaz, 2007-2008
4  *
5  * This work is licensed under the terms of MAME license.
6  * See COPYING file in the top-level directory.
7  */
8
9 .global memcpy16 @ unsigned short *dest, unsigned short *src, int count
10
11 memcpy16:
12     eor     r3, r0, r1
13     tst     r3, #2
14     bne     mcp16_cant_align
15
16     tst     r0, #2
17     ldrneh  r3, [r1], #2
18     subne   r2, r2, #1
19     strneh  r3, [r0], #2
20
21     subs    r2, r2, #4
22     bmi     mcp16_fin
23
24 mcp16_loop:
25     ldmia   r1!, {r3,r12}
26     subs    r2, r2, #4
27     stmia   r0!, {r3,r12}
28     bpl     mcp16_loop
29
30 mcp16_fin:
31     tst     r2, #2
32     ldrne   r3, [r1], #4
33     strne   r3, [r0], #4
34     ands    r2, r2, #1
35     bxeq    lr
36
37 mcp16_cant_align:
38     ldrh    r3, [r1], #2
39     subs    r2, r2, #1
40     strh    r3, [r0], #2
41     bne     mcp16_cant_align
42
43     bx      lr
44
45
46
47 @ 0x12345678 -> 0x34127856
48 @ r4=temp, lr=0x00ff00ff
49 .macro bswap reg
50     and     r4,   \reg, lr
51     and     \reg, lr,   \reg, lsr #8
52     orr     \reg, \reg, r4,   lsl #8
53 .endm
54
55
56 @ dest must be halfword aligned, src can be unaligned
57 .global memcpy16bswap @ unsigned short *dest, void *src, int count
58
59 memcpy16bswap:
60     tst     r1, #1
61     bne     mcp16bs_cant_align2
62
63     eor     r3, r0, r1
64     tst     r3, #2
65     bne     mcp16bs_cant_align
66
67     tst     r0, #2
68     beq     mcp16bs_aligned
69     ldrh    r3, [r1], #2
70     sub     r2, r2, #1
71     orr     r3, r3, r3, lsl #16
72     mov     r3, r3, lsr #8
73     strh    r3, [r0], #2
74
75 mcp16bs_aligned:
76     stmfd   sp!, {r4,lr}
77     mov     lr, #0xff
78     orr     lr, lr, lr, lsl #16
79
80     subs    r2, r2, #4
81     bmi     mcp16bs_fin4
82
83 mcp16bs_loop:
84     ldmia   r1!, {r3,r12}
85     subs    r2, r2, #4
86     bswap   r3
87     bswap   r12
88     stmia   r0!, {r3,r12}
89     bpl     mcp16bs_loop
90
91 mcp16bs_fin4:
92     tst     r2, #2
93     beq     mcp16bs_fin2
94     ldr     r3, [r1], #4
95     bswap   r3
96     str     r3, [r0], #4
97
98 mcp16bs_fin2:
99     ldmfd   sp!, {r4,lr}
100     ands    r2, r2, #1
101     bxeq    lr
102
103 mcp16bs_cant_align:
104     ldrh    r3, [r1], #2
105     subs    r2, r2, #1
106     orr     r3, r3, r3, lsl #16
107     mov     r3, r3, lsr #8
108     strh    r3, [r0], #2
109     bne     mcp16bs_cant_align
110     bx      lr
111
112     @ worst case
113 mcp16bs_cant_align2:
114     ldrb    r3, [r1], #1
115     ldrb    r12,[r1], #1
116     subs    r2, r2, #1
117     mov     r3, r3, lsl #8
118     orr     r3, r3, r12
119     strh    r3, [r0], #2
120     bne     mcp16bs_cant_align2
121     bx      lr
122
123
124
125 .global memcpy32 @ int *dest, int *src, int count
126
127 memcpy32:
128     stmfd   sp!, {r4,lr}
129
130     subs    r2, r2, #4
131     bmi     mcp32_fin
132
133 mcp32_loop:
134     ldmia   r1!, {r3,r4,r12,lr}
135     subs    r2, r2, #4
136     stmia   r0!, {r3,r4,r12,lr}
137     bpl     mcp32_loop
138
139 mcp32_fin:
140     tst     r2, #3
141     ldmeqfd sp!, {r4,pc}
142     tst     r2, #1
143     ldrne   r3, [r1], #4
144     strne   r3, [r0], #4
145
146 mcp32_no_unal1:
147     tst     r2, #2
148     ldmneia r1!, {r3,r12}
149     ldmfd   sp!, {r4,lr}
150     stmneia r0!, {r3,r12}
151     bx      lr
152
153
154
155 .global memset32 @ int *dest, int c, int count
156
157 memset32:
158     stmfd   sp!, {lr}
159
160     mov     r3, r1
161     subs    r2, r2, #4
162     bmi     mst32_fin
163
164     mov     r12,r1
165     mov     lr, r1
166
167 mst32_loop:
168     subs    r2, r2, #4
169     stmia   r0!, {r1,r3,r12,lr}
170     bpl     mst32_loop
171
172 mst32_fin:
173     tst     r2, #1
174     strne   r1, [r0], #4
175
176     tst     r2, #2
177     stmneia r0!, {r1,r3}
178
179     ldmfd   sp!, {lr}
180     bx      lr
181
182 @ vim:filetype=armasm