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
)(T0
);
44 void glue(do_stmw
, MEMSUFFIX
) (int src
)
46 for (; src
< 32; src
++, T0
+= 4) {
47 glue(stl
, MEMSUFFIX
)(T0
, ugpr(src
));
51 void glue(do_lmw_le
, MEMSUFFIX
) (int dst
)
53 for (; dst
< 32; dst
++, T0
+= 4) {
54 ugpr(dst
) = glue(ld32r
, MEMSUFFIX
)(T0
);
58 void glue(do_stmw_le
, MEMSUFFIX
) (int src
)
60 for (; src
< 32; src
++, T0
+= 4) {
61 glue(st32r
, MEMSUFFIX
)(T0
, ugpr(src
));
65 void glue(do_lsw
, MEMSUFFIX
) (int dst
)
70 for (; T1
> 3; T1
-= 4, T0
+= 4) {
71 ugpr(dst
++) = glue(ldl
, MEMSUFFIX
)(T0
);
72 if (unlikely(dst
== 32))
75 if (unlikely(T1
!= 0)) {
77 for (sh
= 24; T1
> 0; T1
--, T0
++, sh
-= 8) {
78 tmp
|= glue(ldub
, MEMSUFFIX
)(T0
) << sh
;
84 void glue(do_stsw
, MEMSUFFIX
) (int src
)
88 for (; T1
> 3; T1
-= 4, T0
+= 4) {
89 glue(stl
, MEMSUFFIX
)(T0
, ugpr(src
++));
90 if (unlikely(src
== 32))
93 if (unlikely(T1
!= 0)) {
94 for (sh
= 24; T1
> 0; T1
--, T0
++, sh
-= 8)
95 glue(stb
, MEMSUFFIX
)(T0
, (ugpr(src
) >> sh
) & 0xFF);
99 void glue(do_lsw_le
, MEMSUFFIX
) (int dst
)
104 for (; T1
> 3; T1
-= 4, T0
+= 4) {
105 ugpr(dst
++) = glue(ld32r
, MEMSUFFIX
)(T0
);
106 if (unlikely(dst
== 32))
109 if (unlikely(T1
!= 0)) {
111 for (sh
= 0; T1
> 0; T1
--, T0
++, sh
+= 8) {
112 tmp
|= glue(ldub
, MEMSUFFIX
)(T0
) << sh
;
118 void glue(do_stsw_le
, MEMSUFFIX
) (int src
)
122 for (; T1
> 3; T1
-= 4, T0
+= 4) {
123 glue(st32r
, MEMSUFFIX
)(T0
, ugpr(src
++));
124 if (unlikely(src
== 32))
127 if (unlikely(T1
!= 0)) {
128 for (sh
= 0; T1
> 0; T1
--, T0
++, sh
+= 8)
129 glue(stb
, MEMSUFFIX
)(T0
, (ugpr(src
) >> sh
) & 0xFF);
133 /* PPC 601 specific instructions (POWER bridge) */
135 void glue(do_POWER_lscbx
, MEMSUFFIX
) (int dest
, int ra
, int rb
)
141 for (i
= 0; i
< T1
; i
++) {
142 c
= glue(ldub
, MEMSUFFIX
)(T0
++);
143 /* ra (if not 0) and rb are never modified */
144 if (likely(reg
!= rb
&& (ra
== 0 || reg
!= ra
))) {
145 ugpr(reg
) = (ugpr(reg
) & ~(0xFF << d
)) | (c
<< d
);
147 if (unlikely(c
== T2
))
149 if (likely(d
!= 0)) {
160 /* XXX: TAGs are not managed */
161 void glue(do_POWER2_lfq
, MEMSUFFIX
) (void)
163 FT0
= glue(ldfq
, MEMSUFFIX
)(T0
);
164 FT1
= glue(ldfq
, MEMSUFFIX
)(T0
+ 4);
167 static inline double glue(ldfqr
, MEMSUFFIX
) (target_ulong EA
)
174 u
.d
= glue(ldfq
, MEMSUFFIX
)(EA
);
175 u
.u
= ((u
.u
& 0xFF00000000000000ULL
) >> 56) |
176 ((u
.u
& 0x00FF000000000000ULL
) >> 40) |
177 ((u
.u
& 0x0000FF0000000000ULL
) >> 24) |
178 ((u
.u
& 0x000000FF00000000ULL
) >> 8) |
179 ((u
.u
& 0x00000000FF000000ULL
) << 8) |
180 ((u
.u
& 0x0000000000FF0000ULL
) << 24) |
181 ((u
.u
& 0x000000000000FF00ULL
) << 40) |
182 ((u
.u
& 0x00000000000000FFULL
) << 56);
187 void glue(do_POWER2_lfq_le
, MEMSUFFIX
) (void)
189 FT0
= glue(ldfqr
, MEMSUFFIX
)(T0
+ 4);
190 FT1
= glue(ldfqr
, MEMSUFFIX
)(T0
);
193 void glue(do_POWER2_stfq
, MEMSUFFIX
) (void)
195 glue(stfq
, MEMSUFFIX
)(T0
, FT0
);
196 glue(stfq
, MEMSUFFIX
)(T0
+ 4, FT1
);
199 static inline void glue(stfqr
, MEMSUFFIX
) (target_ulong EA
, double d
)
207 u
.u
= ((u
.u
& 0xFF00000000000000ULL
) >> 56) |
208 ((u
.u
& 0x00FF000000000000ULL
) >> 40) |
209 ((u
.u
& 0x0000FF0000000000ULL
) >> 24) |
210 ((u
.u
& 0x000000FF00000000ULL
) >> 8) |
211 ((u
.u
& 0x00000000FF000000ULL
) << 8) |
212 ((u
.u
& 0x0000000000FF0000ULL
) << 24) |
213 ((u
.u
& 0x000000000000FF00ULL
) << 40) |
214 ((u
.u
& 0x00000000000000FFULL
) << 56);
215 glue(stfq
, MEMSUFFIX
)(EA
, u
.d
);
218 void glue(do_POWER2_stfq_le
, MEMSUFFIX
) (void)
220 glue(stfqr
, MEMSUFFIX
)(T0
+ 4, FT0
);
221 glue(stfqr
, MEMSUFFIX
)(T0
, FT1
);