2 * PowerPC emulation micro-operations helpers for qemu.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
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.
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.
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
21 /* Multiple word / string load and store */
22 static inline target_ulong
glue(ld32r
, MEMSUFFIX
) (target_ulong EA
)
24 uint32_t tmp
= glue(ldl
, MEMSUFFIX
)(EA
);
25 return ((tmp
& 0xFF000000UL
) >> 24) | ((tmp
& 0x00FF0000UL
) >> 8) |
26 ((tmp
& 0x0000FF00UL
) << 8) | ((tmp
& 0x000000FFUL
) << 24);
29 static inline void glue(st32r
, MEMSUFFIX
) (target_ulong EA
, target_ulong data
)
32 ((data
& 0xFF000000UL
) >> 24) | ((data
& 0x00FF0000UL
) >> 8) |
33 ((data
& 0x0000FF00UL
) << 8) | ((data
& 0x000000FFUL
) << 24);
34 glue(stl
, MEMSUFFIX
)(EA
, tmp
);
37 void glue(do_lmw
, MEMSUFFIX
) (int dst
)
39 for (; dst
< 32; dst
++, T0
+= 4) {
40 ugpr(dst
) = glue(ldl
, MEMSUFFIX
)((uint32_t)T0
);
44 #if defined(TARGET_PPC64)
45 void glue(do_lmw_64
, MEMSUFFIX
) (int dst
)
47 for (; dst
< 32; dst
++, T0
+= 4) {
48 ugpr(dst
) = glue(ldl
, MEMSUFFIX
)((uint64_t)T0
);
53 void glue(do_stmw
, MEMSUFFIX
) (int src
)
55 for (; src
< 32; src
++, T0
+= 4) {
56 glue(stl
, MEMSUFFIX
)((uint32_t)T0
, ugpr(src
));
60 #if defined(TARGET_PPC64)
61 void glue(do_stmw_64
, MEMSUFFIX
) (int src
)
63 for (; src
< 32; src
++, T0
+= 4) {
64 glue(stl
, MEMSUFFIX
)((uint64_t)T0
, ugpr(src
));
69 void glue(do_lmw_le
, MEMSUFFIX
) (int dst
)
71 for (; dst
< 32; dst
++, T0
+= 4) {
72 ugpr(dst
) = glue(ld32r
, MEMSUFFIX
)((uint32_t)T0
);
76 #if defined(TARGET_PPC64)
77 void glue(do_lmw_le_64
, MEMSUFFIX
) (int dst
)
79 for (; dst
< 32; dst
++, T0
+= 4) {
80 ugpr(dst
) = glue(ld32r
, MEMSUFFIX
)((uint64_t)T0
);
85 void glue(do_stmw_le
, MEMSUFFIX
) (int src
)
87 for (; src
< 32; src
++, T0
+= 4) {
88 glue(st32r
, MEMSUFFIX
)((uint32_t)T0
, ugpr(src
));
92 #if defined(TARGET_PPC64)
93 void glue(do_stmw_le_64
, MEMSUFFIX
) (int src
)
95 for (; src
< 32; src
++, T0
+= 4) {
96 glue(st32r
, MEMSUFFIX
)((uint64_t)T0
, ugpr(src
));
101 void glue(do_lsw
, MEMSUFFIX
) (int dst
)
106 for (; T1
> 3; T1
-= 4, T0
+= 4) {
107 ugpr(dst
++) = glue(ldl
, MEMSUFFIX
)((uint32_t)T0
);
108 if (unlikely(dst
== 32))
111 if (unlikely(T1
!= 0)) {
113 for (sh
= 24; T1
> 0; T1
--, T0
++, sh
-= 8) {
114 tmp
|= glue(ldub
, MEMSUFFIX
)((uint32_t)T0
) << sh
;
120 #if defined(TARGET_PPC64)
121 void glue(do_lsw_64
, MEMSUFFIX
) (int dst
)
126 for (; T1
> 3; T1
-= 4, T0
+= 4) {
127 ugpr(dst
++) = glue(ldl
, MEMSUFFIX
)((uint64_t)T0
);
128 if (unlikely(dst
== 32))
131 if (unlikely(T1
!= 0)) {
133 for (sh
= 24; T1
> 0; T1
--, T0
++, sh
-= 8) {
134 tmp
|= glue(ldub
, MEMSUFFIX
)((uint64_t)T0
) << sh
;
141 void glue(do_stsw
, MEMSUFFIX
) (int src
)
145 for (; T1
> 3; T1
-= 4, T0
+= 4) {
146 glue(stl
, MEMSUFFIX
)((uint32_t)T0
, ugpr(src
++));
147 if (unlikely(src
== 32))
150 if (unlikely(T1
!= 0)) {
151 for (sh
= 24; T1
> 0; T1
--, T0
++, sh
-= 8)
152 glue(stb
, MEMSUFFIX
)((uint32_t)T0
, (ugpr(src
) >> sh
) & 0xFF);
156 #if defined(TARGET_PPC64)
157 void glue(do_stsw_64
, MEMSUFFIX
) (int src
)
161 for (; T1
> 3; T1
-= 4, T0
+= 4) {
162 glue(stl
, MEMSUFFIX
)((uint64_t)T0
, ugpr(src
++));
163 if (unlikely(src
== 32))
166 if (unlikely(T1
!= 0)) {
167 for (sh
= 24; T1
> 0; T1
--, T0
++, sh
-= 8)
168 glue(stb
, MEMSUFFIX
)((uint64_t)T0
, (ugpr(src
) >> sh
) & 0xFF);
173 void glue(do_lsw_le
, MEMSUFFIX
) (int dst
)
178 for (; T1
> 3; T1
-= 4, T0
+= 4) {
179 ugpr(dst
++) = glue(ld32r
, MEMSUFFIX
)((uint32_t)T0
);
180 if (unlikely(dst
== 32))
183 if (unlikely(T1
!= 0)) {
185 for (sh
= 0; T1
> 0; T1
--, T0
++, sh
+= 8) {
186 tmp
|= glue(ldub
, MEMSUFFIX
)((uint32_t)T0
) << sh
;
192 #if defined(TARGET_PPC64)
193 void glue(do_lsw_le_64
, MEMSUFFIX
) (int dst
)
198 for (; T1
> 3; T1
-= 4, T0
+= 4) {
199 ugpr(dst
++) = glue(ld32r
, MEMSUFFIX
)((uint64_t)T0
);
200 if (unlikely(dst
== 32))
203 if (unlikely(T1
!= 0)) {
205 for (sh
= 0; T1
> 0; T1
--, T0
++, sh
+= 8) {
206 tmp
|= glue(ldub
, MEMSUFFIX
)((uint64_t)T0
) << sh
;
213 void glue(do_stsw_le
, MEMSUFFIX
) (int src
)
217 for (; T1
> 3; T1
-= 4, T0
+= 4) {
218 glue(st32r
, MEMSUFFIX
)((uint32_t)T0
, ugpr(src
++));
219 if (unlikely(src
== 32))
222 if (unlikely(T1
!= 0)) {
223 for (sh
= 0; T1
> 0; T1
--, T0
++, sh
+= 8)
224 glue(stb
, MEMSUFFIX
)((uint32_t)T0
, (ugpr(src
) >> sh
) & 0xFF);
228 #if defined(TARGET_PPC64)
229 void glue(do_stsw_le_64
, MEMSUFFIX
) (int src
)
233 for (; T1
> 3; T1
-= 4, T0
+= 4) {
234 glue(st32r
, MEMSUFFIX
)((uint64_t)T0
, ugpr(src
++));
235 if (unlikely(src
== 32))
238 if (unlikely(T1
!= 0)) {
239 for (sh
= 0; T1
> 0; T1
--, T0
++, sh
+= 8)
240 glue(stb
, MEMSUFFIX
)((uint64_t)T0
, (ugpr(src
) >> sh
) & 0xFF);
245 /* PPC 601 specific instructions (POWER bridge) */
247 void glue(do_POWER_lscbx
, MEMSUFFIX
) (int dest
, int ra
, int rb
)
253 for (i
= 0; i
< T1
; i
++) {
254 c
= glue(ldub
, MEMSUFFIX
)((uint32_t)T0
++);
255 /* ra (if not 0) and rb are never modified */
256 if (likely(reg
!= rb
&& (ra
== 0 || reg
!= ra
))) {
257 ugpr(reg
) = (ugpr(reg
) & ~(0xFF << d
)) | (c
<< d
);
259 if (unlikely(c
== T2
))
261 if (likely(d
!= 0)) {
272 /* XXX: TAGs are not managed */
273 void glue(do_POWER2_lfq
, MEMSUFFIX
) (void)
275 FT0
= glue(ldfq
, MEMSUFFIX
)((uint32_t)T0
);
276 FT1
= glue(ldfq
, MEMSUFFIX
)((uint32_t)(T0
+ 4));
279 static inline double glue(ldfqr
, MEMSUFFIX
) (target_ulong EA
)
286 u
.d
= glue(ldfq
, MEMSUFFIX
)(EA
);
287 u
.u
= ((u
.u
& 0xFF00000000000000ULL
) >> 56) |
288 ((u
.u
& 0x00FF000000000000ULL
) >> 40) |
289 ((u
.u
& 0x0000FF0000000000ULL
) >> 24) |
290 ((u
.u
& 0x000000FF00000000ULL
) >> 8) |
291 ((u
.u
& 0x00000000FF000000ULL
) << 8) |
292 ((u
.u
& 0x0000000000FF0000ULL
) << 24) |
293 ((u
.u
& 0x000000000000FF00ULL
) << 40) |
294 ((u
.u
& 0x00000000000000FFULL
) << 56);
299 void glue(do_POWER2_lfq_le
, MEMSUFFIX
) (void)
301 FT0
= glue(ldfqr
, MEMSUFFIX
)((uint32_t)(T0
+ 4));
302 FT1
= glue(ldfqr
, MEMSUFFIX
)((uint32_t)T0
);
305 void glue(do_POWER2_stfq
, MEMSUFFIX
) (void)
307 glue(stfq
, MEMSUFFIX
)((uint32_t)T0
, FT0
);
308 glue(stfq
, MEMSUFFIX
)((uint32_t)(T0
+ 4), FT1
);
311 static inline void glue(stfqr
, MEMSUFFIX
) (target_ulong EA
, double d
)
319 u
.u
= ((u
.u
& 0xFF00000000000000ULL
) >> 56) |
320 ((u
.u
& 0x00FF000000000000ULL
) >> 40) |
321 ((u
.u
& 0x0000FF0000000000ULL
) >> 24) |
322 ((u
.u
& 0x000000FF00000000ULL
) >> 8) |
323 ((u
.u
& 0x00000000FF000000ULL
) << 8) |
324 ((u
.u
& 0x0000000000FF0000ULL
) << 24) |
325 ((u
.u
& 0x000000000000FF00ULL
) << 40) |
326 ((u
.u
& 0x00000000000000FFULL
) << 56);
327 glue(stfq
, MEMSUFFIX
)(EA
, u
.d
);
330 void glue(do_POWER2_stfq_le
, MEMSUFFIX
) (void)
332 glue(stfqr
, MEMSUFFIX
)((uint32_t)(T0
+ 4), FT0
);
333 glue(stfqr
, MEMSUFFIX
)((uint32_t)T0
, FT1
);