]>
Commit | Line | Data |
---|---|---|
76a66253 JM |
1 | /* |
2 | * PowerPC emulation micro-operations helpers for qemu. | |
3 | * | |
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 */ | |
22 | static inline target_ulong glue(ld32r, MEMSUFFIX) (target_ulong EA) | |
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 | ||
29 | static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, target_ulong data) | |
30 | { | |
31 | uint32_t tmp = | |
32 | ((data & 0xFF000000UL) >> 24) | ((data & 0x00FF0000UL) >> 8) | | |
33 | ((data & 0x0000FF00UL) << 8) | ((data & 0x000000FFUL) << 24); | |
34 | glue(stl, MEMSUFFIX)(EA, tmp); | |
35 | } | |
36 | ||
37 | void glue(do_lmw, MEMSUFFIX) (int dst) | |
38 | { | |
39 | for (; dst < 32; dst++, T0 += 4) { | |
40 | ugpr(dst) = glue(ldl, MEMSUFFIX)(T0); | |
41 | } | |
42 | } | |
43 | ||
44 | void glue(do_stmw, MEMSUFFIX) (int src) | |
45 | { | |
46 | for (; src < 32; src++, T0 += 4) { | |
47 | glue(stl, MEMSUFFIX)(T0, ugpr(src)); | |
48 | } | |
49 | } | |
50 | ||
51 | void glue(do_lmw_le, MEMSUFFIX) (int dst) | |
52 | { | |
53 | for (; dst < 32; dst++, T0 += 4) { | |
54 | ugpr(dst) = glue(ld32r, MEMSUFFIX)(T0); | |
55 | } | |
56 | } | |
57 | ||
58 | void glue(do_stmw_le, MEMSUFFIX) (int src) | |
59 | { | |
60 | for (; src < 32; src++, T0 += 4) { | |
61 | glue(st32r, MEMSUFFIX)(T0, ugpr(src)); | |
62 | } | |
63 | } | |
64 | ||
9a64fbe4 FB |
65 | void glue(do_lsw, MEMSUFFIX) (int dst) |
66 | { | |
67 | uint32_t tmp; | |
68 | int sh; | |
69 | ||
9a64fbe4 | 70 | for (; T1 > 3; T1 -= 4, T0 += 4) { |
0fa85d43 | 71 | ugpr(dst++) = glue(ldl, MEMSUFFIX)(T0); |
76a66253 | 72 | if (unlikely(dst == 32)) |
9a64fbe4 FB |
73 | dst = 0; |
74 | } | |
76a66253 | 75 | if (unlikely(T1 != 0)) { |
9a64fbe4 FB |
76 | tmp = 0; |
77 | for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) { | |
0fa85d43 | 78 | tmp |= glue(ldub, MEMSUFFIX)(T0) << sh; |
9a64fbe4 FB |
79 | } |
80 | ugpr(dst) = tmp; | |
81 | } | |
82 | } | |
83 | ||
84 | void glue(do_stsw, MEMSUFFIX) (int src) | |
85 | { | |
86 | int sh; | |
87 | ||
9a64fbe4 | 88 | for (; T1 > 3; T1 -= 4, T0 += 4) { |
0fa85d43 | 89 | glue(stl, MEMSUFFIX)(T0, ugpr(src++)); |
76a66253 | 90 | if (unlikely(src == 32)) |
9a64fbe4 FB |
91 | src = 0; |
92 | } | |
76a66253 | 93 | if (unlikely(T1 != 0)) { |
9a64fbe4 | 94 | for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) |
0fa85d43 | 95 | glue(stb, MEMSUFFIX)(T0, (ugpr(src) >> sh) & 0xFF); |
9a64fbe4 FB |
96 | } |
97 | } | |
98 | ||
111bfab3 FB |
99 | void glue(do_lsw_le, MEMSUFFIX) (int dst) |
100 | { | |
101 | uint32_t tmp; | |
102 | int sh; | |
103 | ||
111bfab3 | 104 | for (; T1 > 3; T1 -= 4, T0 += 4) { |
76a66253 JM |
105 | ugpr(dst++) = glue(ld32r, MEMSUFFIX)(T0); |
106 | if (unlikely(dst == 32)) | |
111bfab3 FB |
107 | dst = 0; |
108 | } | |
76a66253 | 109 | if (unlikely(T1 != 0)) { |
111bfab3 FB |
110 | tmp = 0; |
111 | for (sh = 0; T1 > 0; T1--, T0++, sh += 8) { | |
112 | tmp |= glue(ldub, MEMSUFFIX)(T0) << sh; | |
113 | } | |
114 | ugpr(dst) = tmp; | |
115 | } | |
116 | } | |
117 | ||
118 | void glue(do_stsw_le, MEMSUFFIX) (int src) | |
119 | { | |
111bfab3 FB |
120 | int sh; |
121 | ||
111bfab3 | 122 | for (; T1 > 3; T1 -= 4, T0 += 4) { |
76a66253 JM |
123 | glue(st32r, MEMSUFFIX)(T0, ugpr(src++)); |
124 | if (unlikely(src == 32)) | |
111bfab3 FB |
125 | src = 0; |
126 | } | |
76a66253 | 127 | if (unlikely(T1 != 0)) { |
111bfab3 FB |
128 | for (sh = 0; T1 > 0; T1--, T0++, sh += 8) |
129 | glue(stb, MEMSUFFIX)(T0, (ugpr(src) >> sh) & 0xFF); | |
130 | } | |
131 | } | |
132 | ||
76a66253 JM |
133 | /* PPC 601 specific instructions (POWER bridge) */ |
134 | // XXX: to be tested | |
135 | void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) | |
136 | { | |
137 | int i, c, d, reg; | |
138 | ||
139 | d = 24; | |
140 | reg = dest; | |
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); | |
146 | } | |
147 | if (unlikely(c == T2)) | |
148 | break; | |
149 | if (likely(d != 0)) { | |
150 | d -= 8; | |
151 | } else { | |
152 | d = 24; | |
153 | reg++; | |
154 | reg = reg & 0x1F; | |
155 | } | |
156 | } | |
157 | T0 = i; | |
158 | } | |
159 | ||
160 | /* XXX: TAGs are not managed */ | |
161 | void glue(do_POWER2_lfq, MEMSUFFIX) (void) | |
162 | { | |
163 | FT0 = glue(ldfq, MEMSUFFIX)(T0); | |
164 | FT1 = glue(ldfq, MEMSUFFIX)(T0 + 4); | |
165 | } | |
166 | ||
167 | static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA) | |
168 | { | |
169 | union { | |
170 | double d; | |
171 | uint64_t u; | |
172 | } u; | |
173 | ||
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); | |
183 | ||
184 | return u.d; | |
185 | } | |
186 | ||
187 | void glue(do_POWER2_lfq_le, MEMSUFFIX) (void) | |
188 | { | |
189 | FT0 = glue(ldfqr, MEMSUFFIX)(T0 + 4); | |
190 | FT1 = glue(ldfqr, MEMSUFFIX)(T0); | |
191 | } | |
192 | ||
193 | void glue(do_POWER2_stfq, MEMSUFFIX) (void) | |
194 | { | |
195 | glue(stfq, MEMSUFFIX)(T0, FT0); | |
196 | glue(stfq, MEMSUFFIX)(T0 + 4, FT1); | |
197 | } | |
198 | ||
199 | static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d) | |
200 | { | |
201 | union { | |
202 | double d; | |
203 | uint64_t u; | |
204 | } u; | |
205 | ||
206 | u.d = 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); | |
216 | } | |
217 | ||
218 | void glue(do_POWER2_stfq_le, MEMSUFFIX) (void) | |
219 | { | |
220 | glue(stfqr, MEMSUFFIX)(T0 + 4, FT0); | |
221 | glue(stfqr, MEMSUFFIX)(T0, FT1); | |
222 | } | |
223 | ||
9a64fbe4 | 224 | #undef MEMSUFFIX |