]>
Commit | Line | Data |
---|---|---|
9a64fbe4 FB |
1 | /* External helpers */ |
2 | void glue(do_lsw, MEMSUFFIX) (int dst); | |
3 | void glue(do_stsw, MEMSUFFIX) (int src); | |
4 | ||
0fa85d43 | 5 | static inline uint16_t glue(ld16r, MEMSUFFIX) (target_ulong EA) |
9a64fbe4 | 6 | { |
ac9eb073 | 7 | uint16_t tmp = glue(lduw, MEMSUFFIX)(EA); |
9a64fbe4 FB |
8 | return ((tmp & 0xFF00) >> 8) | ((tmp & 0x00FF) << 8); |
9 | } | |
10 | ||
111bfab3 FB |
11 | static inline int32_t glue(ld16rs, MEMSUFFIX) (target_ulong EA) |
12 | { | |
13 | int16_t tmp = glue(lduw, MEMSUFFIX)(EA); | |
14 | return ((tmp & 0xFF00) >> 8) | ((tmp & 0x00FF) << 8); | |
15 | } | |
16 | ||
0fa85d43 | 17 | static inline uint32_t glue(ld32r, MEMSUFFIX) (target_ulong EA) |
9a64fbe4 | 18 | { |
ac9eb073 | 19 | uint32_t tmp = glue(ldl, MEMSUFFIX)(EA); |
9a64fbe4 FB |
20 | return ((tmp & 0xFF000000) >> 24) | ((tmp & 0x00FF0000) >> 8) | |
21 | ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24); | |
22 | } | |
23 | ||
0fa85d43 | 24 | static inline void glue(st16r, MEMSUFFIX) (target_ulong EA, uint16_t data) |
9a64fbe4 FB |
25 | { |
26 | uint16_t tmp = ((data & 0xFF00) >> 8) | ((data & 0x00FF) << 8); | |
ac9eb073 | 27 | glue(stw, MEMSUFFIX)(EA, tmp); |
9a64fbe4 FB |
28 | } |
29 | ||
0fa85d43 | 30 | static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, uint32_t data) |
9a64fbe4 FB |
31 | { |
32 | uint32_t tmp = ((data & 0xFF000000) >> 24) | ((data & 0x00FF0000) >> 8) | | |
33 | ((data & 0x0000FF00) << 8) | ((data & 0x000000FF) << 24); | |
ac9eb073 | 34 | glue(stl, MEMSUFFIX)(EA, tmp); |
9a64fbe4 FB |
35 | } |
36 | ||
37 | /*** Integer load ***/ | |
38 | #define PPC_LD_OP(name, op) \ | |
39 | PPC_OP(glue(glue(l, name), MEMSUFFIX)) \ | |
40 | { \ | |
0fa85d43 | 41 | T1 = glue(op, MEMSUFFIX)(T0); \ |
9a64fbe4 FB |
42 | RETURN(); \ |
43 | } | |
44 | ||
45 | #define PPC_ST_OP(name, op) \ | |
46 | PPC_OP(glue(glue(st, name), MEMSUFFIX)) \ | |
47 | { \ | |
0fa85d43 | 48 | glue(op, MEMSUFFIX)(T0, T1); \ |
9a64fbe4 FB |
49 | RETURN(); \ |
50 | } | |
51 | ||
ac9eb073 FB |
52 | PPC_LD_OP(bz, ldub); |
53 | PPC_LD_OP(ha, ldsw); | |
54 | PPC_LD_OP(hz, lduw); | |
55 | PPC_LD_OP(wz, ldl); | |
9a64fbe4 | 56 | |
111bfab3 FB |
57 | PPC_LD_OP(ha_le, ld16rs); |
58 | PPC_LD_OP(hz_le, ld16r); | |
59 | PPC_LD_OP(wz_le, ld32r); | |
60 | ||
9a64fbe4 | 61 | /*** Integer store ***/ |
ac9eb073 FB |
62 | PPC_ST_OP(b, stb); |
63 | PPC_ST_OP(h, stw); | |
64 | PPC_ST_OP(w, stl); | |
9a64fbe4 | 65 | |
111bfab3 FB |
66 | PPC_ST_OP(h_le, st16r); |
67 | PPC_ST_OP(w_le, st32r); | |
68 | ||
9a64fbe4 | 69 | /*** Integer load and store with byte reverse ***/ |
ac9eb073 FB |
70 | PPC_LD_OP(hbr, ld16r); |
71 | PPC_LD_OP(wbr, ld32r); | |
72 | PPC_ST_OP(hbr, st16r); | |
73 | PPC_ST_OP(wbr, st32r); | |
9a64fbe4 | 74 | |
111bfab3 FB |
75 | PPC_LD_OP(hbr_le, lduw); |
76 | PPC_LD_OP(wbr_le, ldl); | |
77 | PPC_ST_OP(hbr_le, stw); | |
78 | PPC_ST_OP(wbr_le, stl); | |
79 | ||
9a64fbe4 FB |
80 | /*** Integer load and store multiple ***/ |
81 | PPC_OP(glue(lmw, MEMSUFFIX)) | |
82 | { | |
83 | int dst = PARAM(1); | |
84 | ||
85 | for (; dst < 32; dst++, T0 += 4) { | |
0fa85d43 | 86 | ugpr(dst) = glue(ldl, MEMSUFFIX)(T0); |
9a64fbe4 FB |
87 | } |
88 | RETURN(); | |
89 | } | |
90 | ||
91 | PPC_OP(glue(stmw, MEMSUFFIX)) | |
92 | { | |
93 | int src = PARAM(1); | |
94 | ||
95 | for (; src < 32; src++, T0 += 4) { | |
0fa85d43 | 96 | glue(stl, MEMSUFFIX)(T0, ugpr(src)); |
9a64fbe4 FB |
97 | } |
98 | RETURN(); | |
99 | } | |
100 | ||
111bfab3 FB |
101 | PPC_OP(glue(lmw_le, MEMSUFFIX)) |
102 | { | |
103 | int dst = PARAM(1); | |
104 | ||
105 | for (; dst < 32; dst++, T0 += 4) { | |
106 | ugpr(dst) = glue(ld32r, MEMSUFFIX)(T0); | |
107 | } | |
108 | RETURN(); | |
109 | } | |
110 | ||
111 | PPC_OP(glue(stmw_le, MEMSUFFIX)) | |
112 | { | |
113 | int src = PARAM(1); | |
114 | ||
115 | for (; src < 32; src++, T0 += 4) { | |
116 | glue(st32r, MEMSUFFIX)(T0, ugpr(src)); | |
117 | } | |
118 | RETURN(); | |
119 | } | |
120 | ||
9a64fbe4 FB |
121 | /*** Integer load and store strings ***/ |
122 | PPC_OP(glue(lswi, MEMSUFFIX)) | |
123 | { | |
124 | glue(do_lsw, MEMSUFFIX)(PARAM(1)); | |
125 | RETURN(); | |
126 | } | |
127 | ||
111bfab3 FB |
128 | void glue(do_lsw_le, MEMSUFFIX) (int dst); |
129 | PPC_OP(glue(lswi_le, MEMSUFFIX)) | |
130 | { | |
131 | glue(do_lsw_le, MEMSUFFIX)(PARAM(1)); | |
132 | RETURN(); | |
133 | } | |
134 | ||
9a64fbe4 FB |
135 | /* PPC32 specification says we must generate an exception if |
136 | * rA is in the range of registers to be loaded. | |
137 | * In an other hand, IBM says this is valid, but rA won't be loaded. | |
138 | * For now, I'll follow the spec... | |
139 | */ | |
140 | PPC_OP(glue(lswx, MEMSUFFIX)) | |
141 | { | |
142 | if (T1 > 0) { | |
143 | if ((PARAM(1) < PARAM(2) && (PARAM(1) + T1) > PARAM(2)) || | |
144 | (PARAM(1) < PARAM(3) && (PARAM(1) + T1) > PARAM(3))) { | |
9fddaa0c | 145 | do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); |
9a64fbe4 FB |
146 | } else { |
147 | glue(do_lsw, MEMSUFFIX)(PARAM(1)); | |
148 | } | |
149 | } | |
150 | RETURN(); | |
151 | } | |
152 | ||
111bfab3 FB |
153 | PPC_OP(glue(lswx_le, MEMSUFFIX)) |
154 | { | |
155 | if (T1 > 0) { | |
156 | if ((PARAM(1) < PARAM(2) && (PARAM(1) + T1) > PARAM(2)) || | |
157 | (PARAM(1) < PARAM(3) && (PARAM(1) + T1) > PARAM(3))) { | |
158 | do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); | |
159 | } else { | |
160 | glue(do_lsw_le, MEMSUFFIX)(PARAM(1)); | |
161 | } | |
162 | } | |
163 | RETURN(); | |
164 | } | |
165 | ||
9a64fbe4 FB |
166 | PPC_OP(glue(stsw, MEMSUFFIX)) |
167 | { | |
168 | glue(do_stsw, MEMSUFFIX)(PARAM(1)); | |
169 | RETURN(); | |
170 | } | |
171 | ||
111bfab3 FB |
172 | void glue(do_stsw_le, MEMSUFFIX) (int src); |
173 | PPC_OP(glue(stsw_le, MEMSUFFIX)) | |
174 | { | |
175 | glue(do_stsw_le, MEMSUFFIX)(PARAM(1)); | |
176 | RETURN(); | |
177 | } | |
178 | ||
9a64fbe4 FB |
179 | /*** Floating-point store ***/ |
180 | #define PPC_STF_OP(name, op) \ | |
181 | PPC_OP(glue(glue(st, name), MEMSUFFIX)) \ | |
182 | { \ | |
0fa85d43 | 183 | glue(op, MEMSUFFIX)(T0, FT1); \ |
9a64fbe4 FB |
184 | RETURN(); \ |
185 | } | |
186 | ||
187 | PPC_STF_OP(fd, stfq); | |
188 | PPC_STF_OP(fs, stfl); | |
189 | ||
111bfab3 FB |
190 | static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d) |
191 | { | |
192 | union { | |
193 | double d; | |
194 | uint64_t u; | |
195 | } u; | |
196 | ||
197 | u.d = d; | |
198 | u.u = ((u.u & 0xFF00000000000000ULL) >> 56) | | |
199 | ((u.u & 0x00FF000000000000ULL) >> 40) | | |
200 | ((u.u & 0x0000FF0000000000ULL) >> 24) | | |
201 | ((u.u & 0x000000FF00000000ULL) >> 8) | | |
202 | ((u.u & 0x00000000FF000000ULL) << 8) | | |
203 | ((u.u & 0x0000000000FF0000ULL) << 24) | | |
204 | ((u.u & 0x000000000000FF00ULL) << 40) | | |
205 | ((u.u & 0x00000000000000FFULL) << 56); | |
206 | glue(stfq, MEMSUFFIX)(EA, u.d); | |
207 | } | |
208 | ||
209 | static inline void glue(stflr, MEMSUFFIX) (target_ulong EA, float f) | |
210 | { | |
211 | union { | |
212 | float f; | |
213 | uint32_t u; | |
214 | } u; | |
215 | ||
216 | u.f = f; | |
217 | u.u = ((u.u & 0xFF000000UL) >> 24) | | |
218 | ((u.u & 0x00FF0000ULL) >> 8) | | |
219 | ((u.u & 0x0000FF00UL) << 8) | | |
220 | ((u.u & 0x000000FFULL) << 24); | |
221 | glue(stfl, MEMSUFFIX)(EA, u.f); | |
222 | } | |
223 | ||
224 | PPC_STF_OP(fd_le, stfqr); | |
225 | PPC_STF_OP(fs_le, stflr); | |
226 | ||
9a64fbe4 FB |
227 | /*** Floating-point load ***/ |
228 | #define PPC_LDF_OP(name, op) \ | |
229 | PPC_OP(glue(glue(l, name), MEMSUFFIX)) \ | |
230 | { \ | |
0fa85d43 | 231 | FT1 = glue(op, MEMSUFFIX)(T0); \ |
9a64fbe4 FB |
232 | RETURN(); \ |
233 | } | |
234 | ||
235 | PPC_LDF_OP(fd, ldfq); | |
236 | PPC_LDF_OP(fs, ldfl); | |
237 | ||
111bfab3 FB |
238 | static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA) |
239 | { | |
240 | union { | |
241 | double d; | |
242 | uint64_t u; | |
243 | } u; | |
244 | ||
245 | u.d = glue(ldfq, MEMSUFFIX)(EA); | |
246 | u.u = ((u.u & 0xFF00000000000000ULL) >> 56) | | |
247 | ((u.u & 0x00FF000000000000ULL) >> 40) | | |
248 | ((u.u & 0x0000FF0000000000ULL) >> 24) | | |
249 | ((u.u & 0x000000FF00000000ULL) >> 8) | | |
250 | ((u.u & 0x00000000FF000000ULL) << 8) | | |
251 | ((u.u & 0x0000000000FF0000ULL) << 24) | | |
252 | ((u.u & 0x000000000000FF00ULL) << 40) | | |
253 | ((u.u & 0x00000000000000FFULL) << 56); | |
254 | ||
255 | return u.d; | |
256 | } | |
257 | ||
258 | static inline float glue(ldflr, MEMSUFFIX) (target_ulong EA) | |
259 | { | |
260 | union { | |
261 | float f; | |
262 | uint32_t u; | |
263 | } u; | |
264 | ||
265 | u.f = glue(ldfl, MEMSUFFIX)(EA); | |
266 | u.u = ((u.u & 0xFF000000UL) >> 24) | | |
267 | ((u.u & 0x00FF0000ULL) >> 8) | | |
268 | ((u.u & 0x0000FF00UL) << 8) | | |
269 | ((u.u & 0x000000FFULL) << 24); | |
270 | ||
271 | return u.f; | |
272 | } | |
273 | ||
274 | PPC_LDF_OP(fd_le, ldfqr); | |
275 | PPC_LDF_OP(fs_le, ldflr); | |
276 | ||
985a19d6 FB |
277 | /* Load and set reservation */ |
278 | PPC_OP(glue(lwarx, MEMSUFFIX)) | |
279 | { | |
280 | if (T0 & 0x03) { | |
9fddaa0c | 281 | do_raise_exception(EXCP_ALIGN); |
985a19d6 | 282 | } else { |
0fa85d43 | 283 | T1 = glue(ldl, MEMSUFFIX)(T0); |
28fbe299 | 284 | regs->reserve = T0; |
985a19d6 FB |
285 | } |
286 | RETURN(); | |
287 | } | |
288 | ||
111bfab3 FB |
289 | PPC_OP(glue(lwarx_le, MEMSUFFIX)) |
290 | { | |
291 | if (T0 & 0x03) { | |
292 | do_raise_exception(EXCP_ALIGN); | |
293 | } else { | |
294 | T1 = glue(ld32r, MEMSUFFIX)(T0); | |
295 | regs->reserve = T0; | |
296 | } | |
297 | RETURN(); | |
298 | } | |
299 | ||
9a64fbe4 FB |
300 | /* Store with reservation */ |
301 | PPC_OP(glue(stwcx, MEMSUFFIX)) | |
302 | { | |
303 | if (T0 & 0x03) { | |
9fddaa0c | 304 | do_raise_exception(EXCP_ALIGN); |
9a64fbe4 FB |
305 | } else { |
306 | if (regs->reserve != T0) { | |
307 | env->crf[0] = xer_ov; | |
308 | } else { | |
0fa85d43 | 309 | glue(stl, MEMSUFFIX)(T0, T1); |
9a64fbe4 FB |
310 | env->crf[0] = xer_ov | 0x02; |
311 | } | |
312 | } | |
313 | regs->reserve = 0; | |
314 | RETURN(); | |
315 | } | |
316 | ||
111bfab3 FB |
317 | PPC_OP(glue(stwcx_le, MEMSUFFIX)) |
318 | { | |
319 | if (T0 & 0x03) { | |
320 | do_raise_exception(EXCP_ALIGN); | |
321 | } else { | |
322 | if (regs->reserve != T0) { | |
323 | env->crf[0] = xer_ov; | |
324 | } else { | |
325 | glue(st32r, MEMSUFFIX)(T0, T1); | |
326 | env->crf[0] = xer_ov | 0x02; | |
327 | } | |
328 | } | |
329 | regs->reserve = 0; | |
330 | RETURN(); | |
331 | } | |
332 | ||
9a64fbe4 FB |
333 | PPC_OP(glue(dcbz, MEMSUFFIX)) |
334 | { | |
0fa85d43 FB |
335 | glue(stl, MEMSUFFIX)(T0 + 0x00, 0); |
336 | glue(stl, MEMSUFFIX)(T0 + 0x04, 0); | |
337 | glue(stl, MEMSUFFIX)(T0 + 0x08, 0); | |
338 | glue(stl, MEMSUFFIX)(T0 + 0x0C, 0); | |
339 | glue(stl, MEMSUFFIX)(T0 + 0x10, 0); | |
340 | glue(stl, MEMSUFFIX)(T0 + 0x14, 0); | |
341 | glue(stl, MEMSUFFIX)(T0 + 0x18, 0); | |
342 | glue(stl, MEMSUFFIX)(T0 + 0x1C, 0); | |
9a64fbe4 FB |
343 | RETURN(); |
344 | } | |
345 | ||
346 | /* External access */ | |
347 | PPC_OP(glue(eciwx, MEMSUFFIX)) | |
348 | { | |
0fa85d43 | 349 | T1 = glue(ldl, MEMSUFFIX)(T0); |
9a64fbe4 FB |
350 | RETURN(); |
351 | } | |
352 | ||
353 | PPC_OP(glue(ecowx, MEMSUFFIX)) | |
354 | { | |
0fa85d43 | 355 | glue(stl, MEMSUFFIX)(T0, T1); |
9a64fbe4 FB |
356 | RETURN(); |
357 | } | |
358 | ||
111bfab3 FB |
359 | PPC_OP(glue(eciwx_le, MEMSUFFIX)) |
360 | { | |
361 | T1 = glue(ld32r, MEMSUFFIX)(T0); | |
362 | RETURN(); | |
363 | } | |
364 | ||
365 | PPC_OP(glue(ecowx_le, MEMSUFFIX)) | |
366 | { | |
367 | glue(st32r, MEMSUFFIX)(T0, T1); | |
368 | RETURN(); | |
369 | } | |
370 | ||
9a64fbe4 | 371 | #undef MEMSUFFIX |