]>
Commit | Line | Data |
---|---|---|
76a66253 JM |
1 | /* |
2 | * PowerPC emulation micro-operations helpers for qemu. | |
d9bce9d9 | 3 | * |
76a66253 JM |
4 | * Copyright (c) 2003-2007 Jocelyn Mayer |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | */ | |
20 | ||
21 | /* Multiple word / string load and store */ | |
b068d6a7 | 22 | static always_inline target_ulong glue(ld32r, MEMSUFFIX) (target_ulong EA) |
76a66253 JM |
23 | { |
24 | uint32_t tmp = glue(ldl, MEMSUFFIX)(EA); | |
25 | return ((tmp & 0xFF000000UL) >> 24) | ((tmp & 0x00FF0000UL) >> 8) | | |
26 | ((tmp & 0x0000FF00UL) << 8) | ((tmp & 0x000000FFUL) << 24); | |
27 | } | |
28 | ||
b068d6a7 JM |
29 | static always_inline void glue(st32r, MEMSUFFIX) (target_ulong EA, |
30 | target_ulong data) | |
76a66253 JM |
31 | { |
32 | uint32_t tmp = | |
33 | ((data & 0xFF000000UL) >> 24) | ((data & 0x00FF0000UL) >> 8) | | |
34 | ((data & 0x0000FF00UL) << 8) | ((data & 0x000000FFUL) << 24); | |
35 | glue(stl, MEMSUFFIX)(EA, tmp); | |
36 | } | |
37 | ||
38 | void glue(do_lmw, MEMSUFFIX) (int dst) | |
39 | { | |
40 | for (; dst < 32; dst++, T0 += 4) { | |
8b67546f | 41 | env->gpr[dst] = glue(ldl, MEMSUFFIX)((uint32_t)T0); |
d9bce9d9 JM |
42 | } |
43 | } | |
44 | ||
45 | #if defined(TARGET_PPC64) | |
46 | void glue(do_lmw_64, MEMSUFFIX) (int dst) | |
47 | { | |
48 | for (; dst < 32; dst++, T0 += 4) { | |
8b67546f | 49 | env->gpr[dst] = glue(ldl, MEMSUFFIX)((uint64_t)T0); |
76a66253 JM |
50 | } |
51 | } | |
d9bce9d9 | 52 | #endif |
76a66253 JM |
53 | |
54 | void glue(do_stmw, MEMSUFFIX) (int src) | |
55 | { | |
56 | for (; src < 32; src++, T0 += 4) { | |
8b67546f | 57 | glue(stl, MEMSUFFIX)((uint32_t)T0, env->gpr[src]); |
d9bce9d9 JM |
58 | } |
59 | } | |
60 | ||
61 | #if defined(TARGET_PPC64) | |
62 | void glue(do_stmw_64, MEMSUFFIX) (int src) | |
63 | { | |
64 | for (; src < 32; src++, T0 += 4) { | |
8b67546f | 65 | glue(stl, MEMSUFFIX)((uint64_t)T0, env->gpr[src]); |
76a66253 JM |
66 | } |
67 | } | |
d9bce9d9 | 68 | #endif |
76a66253 JM |
69 | |
70 | void glue(do_lmw_le, MEMSUFFIX) (int dst) | |
71 | { | |
72 | for (; dst < 32; dst++, T0 += 4) { | |
8b67546f | 73 | env->gpr[dst] = glue(ld32r, MEMSUFFIX)((uint32_t)T0); |
d9bce9d9 JM |
74 | } |
75 | } | |
76 | ||
77 | #if defined(TARGET_PPC64) | |
78 | void glue(do_lmw_le_64, MEMSUFFIX) (int dst) | |
79 | { | |
80 | for (; dst < 32; dst++, T0 += 4) { | |
8b67546f | 81 | env->gpr[dst] = glue(ld32r, MEMSUFFIX)((uint64_t)T0); |
76a66253 JM |
82 | } |
83 | } | |
d9bce9d9 | 84 | #endif |
76a66253 JM |
85 | |
86 | void glue(do_stmw_le, MEMSUFFIX) (int src) | |
87 | { | |
88 | for (; src < 32; src++, T0 += 4) { | |
8b67546f | 89 | glue(st32r, MEMSUFFIX)((uint32_t)T0, env->gpr[src]); |
76a66253 JM |
90 | } |
91 | } | |
92 | ||
d9bce9d9 JM |
93 | #if defined(TARGET_PPC64) |
94 | void glue(do_stmw_le_64, MEMSUFFIX) (int src) | |
95 | { | |
96 | for (; src < 32; src++, T0 += 4) { | |
8b67546f | 97 | glue(st32r, MEMSUFFIX)((uint64_t)T0, env->gpr[src]); |
d9bce9d9 JM |
98 | } |
99 | } | |
100 | #endif | |
101 | ||
9a64fbe4 FB |
102 | void glue(do_lsw, MEMSUFFIX) (int dst) |
103 | { | |
104 | uint32_t tmp; | |
105 | int sh; | |
106 | ||
9a64fbe4 | 107 | for (; T1 > 3; T1 -= 4, T0 += 4) { |
8b67546f | 108 | env->gpr[dst++] = glue(ldl, MEMSUFFIX)((uint32_t)T0); |
76a66253 | 109 | if (unlikely(dst == 32)) |
9a64fbe4 FB |
110 | dst = 0; |
111 | } | |
76a66253 | 112 | if (unlikely(T1 != 0)) { |
9a64fbe4 FB |
113 | tmp = 0; |
114 | for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) { | |
d9bce9d9 | 115 | tmp |= glue(ldub, MEMSUFFIX)((uint32_t)T0) << sh; |
9a64fbe4 | 116 | } |
8b67546f | 117 | env->gpr[dst] = tmp; |
9a64fbe4 FB |
118 | } |
119 | } | |
120 | ||
d9bce9d9 JM |
121 | #if defined(TARGET_PPC64) |
122 | void glue(do_lsw_64, MEMSUFFIX) (int dst) | |
123 | { | |
124 | uint32_t tmp; | |
125 | int sh; | |
126 | ||
127 | for (; T1 > 3; T1 -= 4, T0 += 4) { | |
8b67546f | 128 | env->gpr[dst++] = glue(ldl, MEMSUFFIX)((uint64_t)T0); |
d9bce9d9 JM |
129 | if (unlikely(dst == 32)) |
130 | dst = 0; | |
131 | } | |
132 | if (unlikely(T1 != 0)) { | |
133 | tmp = 0; | |
134 | for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) { | |
135 | tmp |= glue(ldub, MEMSUFFIX)((uint64_t)T0) << sh; | |
136 | } | |
8b67546f | 137 | env->gpr[dst] = tmp; |
d9bce9d9 JM |
138 | } |
139 | } | |
140 | #endif | |
141 | ||
9a64fbe4 FB |
142 | void glue(do_stsw, MEMSUFFIX) (int src) |
143 | { | |
144 | int sh; | |
145 | ||
9a64fbe4 | 146 | for (; T1 > 3; T1 -= 4, T0 += 4) { |
8b67546f | 147 | glue(stl, MEMSUFFIX)((uint32_t)T0, env->gpr[src++]); |
76a66253 | 148 | if (unlikely(src == 32)) |
9a64fbe4 FB |
149 | src = 0; |
150 | } | |
76a66253 | 151 | if (unlikely(T1 != 0)) { |
9a64fbe4 | 152 | for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) |
8b67546f | 153 | glue(stb, MEMSUFFIX)((uint32_t)T0, (env->gpr[src] >> sh) & 0xFF); |
9a64fbe4 FB |
154 | } |
155 | } | |
156 | ||
d9bce9d9 JM |
157 | #if defined(TARGET_PPC64) |
158 | void glue(do_stsw_64, MEMSUFFIX) (int src) | |
159 | { | |
160 | int sh; | |
161 | ||
162 | for (; T1 > 3; T1 -= 4, T0 += 4) { | |
8b67546f | 163 | glue(stl, MEMSUFFIX)((uint64_t)T0, env->gpr[src++]); |
d9bce9d9 JM |
164 | if (unlikely(src == 32)) |
165 | src = 0; | |
166 | } | |
167 | if (unlikely(T1 != 0)) { | |
168 | for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) | |
8b67546f | 169 | glue(stb, MEMSUFFIX)((uint64_t)T0, (env->gpr[src] >> sh) & 0xFF); |
d9bce9d9 JM |
170 | } |
171 | } | |
172 | #endif | |
173 | ||
111bfab3 FB |
174 | void glue(do_lsw_le, MEMSUFFIX) (int dst) |
175 | { | |
176 | uint32_t tmp; | |
177 | int sh; | |
178 | ||
111bfab3 | 179 | for (; T1 > 3; T1 -= 4, T0 += 4) { |
8b67546f | 180 | env->gpr[dst++] = glue(ld32r, MEMSUFFIX)((uint32_t)T0); |
d9bce9d9 JM |
181 | if (unlikely(dst == 32)) |
182 | dst = 0; | |
183 | } | |
184 | if (unlikely(T1 != 0)) { | |
185 | tmp = 0; | |
186 | for (sh = 0; T1 > 0; T1--, T0++, sh += 8) { | |
187 | tmp |= glue(ldub, MEMSUFFIX)((uint32_t)T0) << sh; | |
188 | } | |
8b67546f | 189 | env->gpr[dst] = tmp; |
d9bce9d9 JM |
190 | } |
191 | } | |
192 | ||
193 | #if defined(TARGET_PPC64) | |
194 | void glue(do_lsw_le_64, MEMSUFFIX) (int dst) | |
195 | { | |
196 | uint32_t tmp; | |
197 | int sh; | |
198 | ||
199 | for (; T1 > 3; T1 -= 4, T0 += 4) { | |
8b67546f | 200 | env->gpr[dst++] = glue(ld32r, MEMSUFFIX)((uint64_t)T0); |
76a66253 | 201 | if (unlikely(dst == 32)) |
111bfab3 FB |
202 | dst = 0; |
203 | } | |
76a66253 | 204 | if (unlikely(T1 != 0)) { |
111bfab3 FB |
205 | tmp = 0; |
206 | for (sh = 0; T1 > 0; T1--, T0++, sh += 8) { | |
d9bce9d9 | 207 | tmp |= glue(ldub, MEMSUFFIX)((uint64_t)T0) << sh; |
111bfab3 | 208 | } |
8b67546f | 209 | env->gpr[dst] = tmp; |
111bfab3 FB |
210 | } |
211 | } | |
d9bce9d9 | 212 | #endif |
111bfab3 FB |
213 | |
214 | void glue(do_stsw_le, MEMSUFFIX) (int src) | |
215 | { | |
111bfab3 FB |
216 | int sh; |
217 | ||
111bfab3 | 218 | for (; T1 > 3; T1 -= 4, T0 += 4) { |
8b67546f | 219 | glue(st32r, MEMSUFFIX)((uint32_t)T0, env->gpr[src++]); |
d9bce9d9 JM |
220 | if (unlikely(src == 32)) |
221 | src = 0; | |
222 | } | |
223 | if (unlikely(T1 != 0)) { | |
224 | for (sh = 0; T1 > 0; T1--, T0++, sh += 8) | |
8b67546f | 225 | glue(stb, MEMSUFFIX)((uint32_t)T0, (env->gpr[src] >> sh) & 0xFF); |
d9bce9d9 JM |
226 | } |
227 | } | |
228 | ||
229 | #if defined(TARGET_PPC64) | |
230 | void glue(do_stsw_le_64, MEMSUFFIX) (int src) | |
231 | { | |
232 | int sh; | |
233 | ||
234 | for (; T1 > 3; T1 -= 4, T0 += 4) { | |
8b67546f | 235 | glue(st32r, MEMSUFFIX)((uint64_t)T0, env->gpr[src++]); |
76a66253 | 236 | if (unlikely(src == 32)) |
111bfab3 FB |
237 | src = 0; |
238 | } | |
76a66253 | 239 | if (unlikely(T1 != 0)) { |
111bfab3 | 240 | for (sh = 0; T1 > 0; T1--, T0++, sh += 8) |
8b67546f | 241 | glue(stb, MEMSUFFIX)((uint64_t)T0, (env->gpr[src] >> sh) & 0xFF); |
111bfab3 FB |
242 | } |
243 | } | |
d9bce9d9 | 244 | #endif |
111bfab3 | 245 | |
36f69651 JM |
246 | /* Instruction cache invalidation helper */ |
247 | void glue(do_icbi, MEMSUFFIX) (void) | |
248 | { | |
249 | uint32_t tmp; | |
250 | /* Invalidate one cache line : | |
251 | * PowerPC specification says this is to be treated like a load | |
252 | * (not a fetch) by the MMU. To be sure it will be so, | |
253 | * do the load "by hand". | |
254 | */ | |
d63001d1 | 255 | T0 &= ~(env->icache_line_size - 1); |
f0685f6e | 256 | tmp = glue(ldl, MEMSUFFIX)((uint32_t)T0); |
d63001d1 JM |
257 | tb_invalidate_page_range((uint32_t)T0, |
258 | (uint32_t)(T0 + env->icache_line_size)); | |
36f69651 JM |
259 | } |
260 | ||
261 | #if defined(TARGET_PPC64) | |
262 | void glue(do_icbi_64, MEMSUFFIX) (void) | |
263 | { | |
264 | uint64_t tmp; | |
265 | /* Invalidate one cache line : | |
266 | * PowerPC specification says this is to be treated like a load | |
267 | * (not a fetch) by the MMU. To be sure it will be so, | |
268 | * do the load "by hand". | |
269 | */ | |
d63001d1 | 270 | T0 &= ~(env->icache_line_size - 1); |
f0685f6e | 271 | tmp = glue(ldq, MEMSUFFIX)((uint64_t)T0); |
d63001d1 JM |
272 | tb_invalidate_page_range((uint64_t)T0, |
273 | (uint64_t)(T0 + env->icache_line_size)); | |
274 | } | |
275 | #endif | |
276 | ||
277 | void glue(do_dcbz, MEMSUFFIX) (void) | |
278 | { | |
279 | int dcache_line_size = env->dcache_line_size; | |
280 | ||
281 | /* XXX: should be 970 specific (?) */ | |
282 | if (((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) | |
283 | dcache_line_size = 32; | |
284 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0); | |
285 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0); | |
286 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x08), 0); | |
287 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x0C), 0); | |
288 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x10), 0); | |
289 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0); | |
290 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0); | |
291 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0); | |
292 | if (dcache_line_size >= 64) { | |
293 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x20UL), 0); | |
294 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x24UL), 0); | |
295 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x28UL), 0); | |
296 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x2CUL), 0); | |
297 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x30UL), 0); | |
298 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x34UL), 0); | |
299 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x38UL), 0); | |
300 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x3CUL), 0); | |
301 | if (dcache_line_size >= 128) { | |
302 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x40UL), 0); | |
303 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x44UL), 0); | |
304 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x48UL), 0); | |
305 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x4CUL), 0); | |
306 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x50UL), 0); | |
307 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x54UL), 0); | |
308 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x58UL), 0); | |
309 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x5CUL), 0); | |
310 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x60UL), 0); | |
311 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x64UL), 0); | |
312 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x68UL), 0); | |
313 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x6CUL), 0); | |
314 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x70UL), 0); | |
315 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x74UL), 0); | |
316 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x78UL), 0); | |
317 | glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x7CUL), 0); | |
318 | } | |
319 | } | |
320 | } | |
321 | ||
322 | #if defined(TARGET_PPC64) | |
323 | void glue(do_dcbz_64, MEMSUFFIX) (void) | |
324 | { | |
325 | int dcache_line_size = env->dcache_line_size; | |
326 | ||
327 | /* XXX: should be 970 specific (?) */ | |
e57448f1 | 328 | if (((env->spr[SPR_970_HID5] >> 6) & 0x3) == 0x2) |
d63001d1 JM |
329 | dcache_line_size = 32; |
330 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0); | |
331 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0); | |
332 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x08), 0); | |
333 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x0C), 0); | |
334 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x10), 0); | |
335 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0); | |
336 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0); | |
337 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0); | |
338 | if (dcache_line_size >= 64) { | |
339 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x20UL), 0); | |
340 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x24UL), 0); | |
341 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x28UL), 0); | |
342 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x2CUL), 0); | |
343 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x30UL), 0); | |
344 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x34UL), 0); | |
345 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x38UL), 0); | |
346 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x3CUL), 0); | |
347 | if (dcache_line_size >= 128) { | |
348 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x40UL), 0); | |
349 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x44UL), 0); | |
350 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x48UL), 0); | |
351 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x4CUL), 0); | |
352 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x50UL), 0); | |
353 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x54UL), 0); | |
354 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x58UL), 0); | |
355 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x5CUL), 0); | |
356 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x60UL), 0); | |
357 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x64UL), 0); | |
358 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x68UL), 0); | |
359 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x6CUL), 0); | |
360 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x70UL), 0); | |
361 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x74UL), 0); | |
362 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x78UL), 0); | |
363 | glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x7CUL), 0); | |
364 | } | |
365 | } | |
36f69651 JM |
366 | } |
367 | #endif | |
368 | ||
36081602 | 369 | /* PowerPC 601 specific instructions (POWER bridge) */ |
76a66253 JM |
370 | // XXX: to be tested |
371 | void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) | |
372 | { | |
373 | int i, c, d, reg; | |
374 | ||
375 | d = 24; | |
376 | reg = dest; | |
377 | for (i = 0; i < T1; i++) { | |
d9bce9d9 | 378 | c = glue(ldub, MEMSUFFIX)((uint32_t)T0++); |
76a66253 JM |
379 | /* ra (if not 0) and rb are never modified */ |
380 | if (likely(reg != rb && (ra == 0 || reg != ra))) { | |
8b67546f | 381 | env->gpr[reg] = (env->gpr[reg] & ~(0xFF << d)) | (c << d); |
76a66253 JM |
382 | } |
383 | if (unlikely(c == T2)) | |
384 | break; | |
385 | if (likely(d != 0)) { | |
386 | d -= 8; | |
387 | } else { | |
388 | d = 24; | |
389 | reg++; | |
390 | reg = reg & 0x1F; | |
391 | } | |
392 | } | |
393 | T0 = i; | |
394 | } | |
395 | ||
396 | /* XXX: TAGs are not managed */ | |
397 | void glue(do_POWER2_lfq, MEMSUFFIX) (void) | |
398 | { | |
d9bce9d9 JM |
399 | FT0 = glue(ldfq, MEMSUFFIX)((uint32_t)T0); |
400 | FT1 = glue(ldfq, MEMSUFFIX)((uint32_t)(T0 + 4)); | |
76a66253 JM |
401 | } |
402 | ||
b068d6a7 | 403 | static always_inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA) |
76a66253 JM |
404 | { |
405 | union { | |
406 | double d; | |
407 | uint64_t u; | |
408 | } u; | |
409 | ||
410 | u.d = glue(ldfq, MEMSUFFIX)(EA); | |
411 | u.u = ((u.u & 0xFF00000000000000ULL) >> 56) | | |
412 | ((u.u & 0x00FF000000000000ULL) >> 40) | | |
413 | ((u.u & 0x0000FF0000000000ULL) >> 24) | | |
414 | ((u.u & 0x000000FF00000000ULL) >> 8) | | |
415 | ((u.u & 0x00000000FF000000ULL) << 8) | | |
416 | ((u.u & 0x0000000000FF0000ULL) << 24) | | |
417 | ((u.u & 0x000000000000FF00ULL) << 40) | | |
418 | ((u.u & 0x00000000000000FFULL) << 56); | |
419 | ||
420 | return u.d; | |
421 | } | |
422 | ||
423 | void glue(do_POWER2_lfq_le, MEMSUFFIX) (void) | |
424 | { | |
d9bce9d9 JM |
425 | FT0 = glue(ldfqr, MEMSUFFIX)((uint32_t)(T0 + 4)); |
426 | FT1 = glue(ldfqr, MEMSUFFIX)((uint32_t)T0); | |
76a66253 JM |
427 | } |
428 | ||
429 | void glue(do_POWER2_stfq, MEMSUFFIX) (void) | |
430 | { | |
d9bce9d9 JM |
431 | glue(stfq, MEMSUFFIX)((uint32_t)T0, FT0); |
432 | glue(stfq, MEMSUFFIX)((uint32_t)(T0 + 4), FT1); | |
76a66253 JM |
433 | } |
434 | ||
b068d6a7 | 435 | static always_inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d) |
76a66253 JM |
436 | { |
437 | union { | |
438 | double d; | |
439 | uint64_t u; | |
440 | } u; | |
441 | ||
442 | u.d = d; | |
443 | u.u = ((u.u & 0xFF00000000000000ULL) >> 56) | | |
444 | ((u.u & 0x00FF000000000000ULL) >> 40) | | |
445 | ((u.u & 0x0000FF0000000000ULL) >> 24) | | |
446 | ((u.u & 0x000000FF00000000ULL) >> 8) | | |
447 | ((u.u & 0x00000000FF000000ULL) << 8) | | |
448 | ((u.u & 0x0000000000FF0000ULL) << 24) | | |
449 | ((u.u & 0x000000000000FF00ULL) << 40) | | |
450 | ((u.u & 0x00000000000000FFULL) << 56); | |
451 | glue(stfq, MEMSUFFIX)(EA, u.d); | |
452 | } | |
453 | ||
454 | void glue(do_POWER2_stfq_le, MEMSUFFIX) (void) | |
455 | { | |
d9bce9d9 JM |
456 | glue(stfqr, MEMSUFFIX)((uint32_t)(T0 + 4), FT0); |
457 | glue(stfqr, MEMSUFFIX)((uint32_t)T0, FT1); | |
76a66253 JM |
458 | } |
459 | ||
9a64fbe4 | 460 | #undef MEMSUFFIX |