cff531af |
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 | */ |
fa1e5e29 |
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 | |
0a051f55 |
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 | |
fa1e5e29 |
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 | |
cff531af |
182 | @ vim:filetype=armasm |