]>
Commit | Line | Data |
---|---|---|
76a66253 JM |
1 | /* |
2 | * PowerPC emulation micro-operations for qemu. | |
5fafdf24 | 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 | */ | |
9a64fbe4 | 20 | |
e7c24003 | 21 | #include "op_mem_access.h" |
d9bce9d9 | 22 | |
985a19d6 | 23 | /* Load and set reservation */ |
d9bce9d9 JM |
24 | void OPPROTO glue(op_lwarx, MEMSUFFIX) (void) |
25 | { | |
26 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 27 | raise_exception(env, POWERPC_EXCP_ALIGN); |
d9bce9d9 | 28 | } else { |
e7c24003 | 29 | T1 = glue(ldu32, MEMSUFFIX)((uint32_t)T0); |
36081602 | 30 | env->reserve = (uint32_t)T0; |
d9bce9d9 JM |
31 | } |
32 | RETURN(); | |
33 | } | |
34 | ||
35 | #if defined(TARGET_PPC64) | |
36 | void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void) | |
37 | { | |
38 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 39 | raise_exception(env, POWERPC_EXCP_ALIGN); |
d9bce9d9 | 40 | } else { |
e7c24003 | 41 | T1 = glue(ldu32, MEMSUFFIX)((uint64_t)T0); |
36081602 | 42 | env->reserve = (uint64_t)T0; |
d9bce9d9 JM |
43 | } |
44 | RETURN(); | |
45 | } | |
46 | ||
426613db JM |
47 | void OPPROTO glue(op_ldarx, MEMSUFFIX) (void) |
48 | { | |
49 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 50 | raise_exception(env, POWERPC_EXCP_ALIGN); |
426613db | 51 | } else { |
e7c24003 | 52 | T1 = glue(ldu64, MEMSUFFIX)((uint32_t)T0); |
36081602 | 53 | env->reserve = (uint32_t)T0; |
426613db JM |
54 | } |
55 | RETURN(); | |
56 | } | |
57 | ||
d9bce9d9 JM |
58 | void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void) |
59 | { | |
60 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 61 | raise_exception(env, POWERPC_EXCP_ALIGN); |
d9bce9d9 | 62 | } else { |
e7c24003 | 63 | T1 = glue(ldu64, MEMSUFFIX)((uint64_t)T0); |
36081602 | 64 | env->reserve = (uint64_t)T0; |
d9bce9d9 JM |
65 | } |
66 | RETURN(); | |
67 | } | |
68 | #endif | |
69 | ||
70 | void OPPROTO glue(op_lwarx_le, MEMSUFFIX) (void) | |
71 | { | |
72 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 73 | raise_exception(env, POWERPC_EXCP_ALIGN); |
d9bce9d9 | 74 | } else { |
e7c24003 | 75 | T1 = glue(ldu32r, MEMSUFFIX)((uint32_t)T0); |
36081602 | 76 | env->reserve = (uint32_t)T0; |
d9bce9d9 JM |
77 | } |
78 | RETURN(); | |
79 | } | |
80 | ||
81 | #if defined(TARGET_PPC64) | |
82 | void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void) | |
985a19d6 | 83 | { |
76a66253 | 84 | if (unlikely(T0 & 0x03)) { |
64adab3f | 85 | raise_exception(env, POWERPC_EXCP_ALIGN); |
985a19d6 | 86 | } else { |
e7c24003 | 87 | T1 = glue(ldu32r, MEMSUFFIX)((uint64_t)T0); |
36081602 | 88 | env->reserve = (uint64_t)T0; |
985a19d6 FB |
89 | } |
90 | RETURN(); | |
91 | } | |
92 | ||
426613db JM |
93 | void OPPROTO glue(op_ldarx_le, MEMSUFFIX) (void) |
94 | { | |
95 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 96 | raise_exception(env, POWERPC_EXCP_ALIGN); |
426613db | 97 | } else { |
e7c24003 | 98 | T1 = glue(ldu64r, MEMSUFFIX)((uint32_t)T0); |
36081602 | 99 | env->reserve = (uint32_t)T0; |
426613db JM |
100 | } |
101 | RETURN(); | |
102 | } | |
103 | ||
d9bce9d9 | 104 | void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void) |
111bfab3 | 105 | { |
76a66253 | 106 | if (unlikely(T0 & 0x03)) { |
64adab3f | 107 | raise_exception(env, POWERPC_EXCP_ALIGN); |
111bfab3 | 108 | } else { |
e7c24003 | 109 | T1 = glue(ldu64r, MEMSUFFIX)((uint64_t)T0); |
36081602 | 110 | env->reserve = (uint64_t)T0; |
111bfab3 FB |
111 | } |
112 | RETURN(); | |
113 | } | |
d9bce9d9 | 114 | #endif |
111bfab3 | 115 | |
9a64fbe4 | 116 | /* Store with reservation */ |
d9bce9d9 JM |
117 | void OPPROTO glue(op_stwcx, MEMSUFFIX) (void) |
118 | { | |
119 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 120 | raise_exception(env, POWERPC_EXCP_ALIGN); |
d9bce9d9 | 121 | } else { |
36081602 | 122 | if (unlikely(env->reserve != (uint32_t)T0)) { |
966439a6 | 123 | env->crf[0] = xer_so; |
d9bce9d9 | 124 | } else { |
e7c24003 | 125 | glue(st32, MEMSUFFIX)((uint32_t)T0, T1); |
966439a6 | 126 | env->crf[0] = xer_so | 0x02; |
d9bce9d9 JM |
127 | } |
128 | } | |
a73666f6 | 129 | env->reserve = (target_ulong)-1ULL; |
d9bce9d9 JM |
130 | RETURN(); |
131 | } | |
132 | ||
133 | #if defined(TARGET_PPC64) | |
134 | void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void) | |
135 | { | |
136 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 137 | raise_exception(env, POWERPC_EXCP_ALIGN); |
d9bce9d9 | 138 | } else { |
36081602 | 139 | if (unlikely(env->reserve != (uint64_t)T0)) { |
966439a6 | 140 | env->crf[0] = xer_so; |
d9bce9d9 | 141 | } else { |
e7c24003 | 142 | glue(st32, MEMSUFFIX)((uint64_t)T0, T1); |
966439a6 | 143 | env->crf[0] = xer_so | 0x02; |
d9bce9d9 JM |
144 | } |
145 | } | |
a73666f6 | 146 | env->reserve = (target_ulong)-1ULL; |
d9bce9d9 JM |
147 | RETURN(); |
148 | } | |
149 | ||
426613db JM |
150 | void OPPROTO glue(op_stdcx, MEMSUFFIX) (void) |
151 | { | |
152 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 153 | raise_exception(env, POWERPC_EXCP_ALIGN); |
426613db | 154 | } else { |
36081602 | 155 | if (unlikely(env->reserve != (uint32_t)T0)) { |
966439a6 | 156 | env->crf[0] = xer_so; |
426613db | 157 | } else { |
e7c24003 | 158 | glue(st64, MEMSUFFIX)((uint32_t)T0, T1); |
966439a6 | 159 | env->crf[0] = xer_so | 0x02; |
426613db JM |
160 | } |
161 | } | |
a73666f6 | 162 | env->reserve = (target_ulong)-1ULL; |
426613db JM |
163 | RETURN(); |
164 | } | |
165 | ||
d9bce9d9 | 166 | void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void) |
9a64fbe4 | 167 | { |
76a66253 | 168 | if (unlikely(T0 & 0x03)) { |
64adab3f | 169 | raise_exception(env, POWERPC_EXCP_ALIGN); |
9a64fbe4 | 170 | } else { |
36081602 | 171 | if (unlikely(env->reserve != (uint64_t)T0)) { |
966439a6 | 172 | env->crf[0] = xer_so; |
9a64fbe4 | 173 | } else { |
e7c24003 | 174 | glue(st64, MEMSUFFIX)((uint64_t)T0, T1); |
966439a6 | 175 | env->crf[0] = xer_so | 0x02; |
d9bce9d9 JM |
176 | } |
177 | } | |
a73666f6 | 178 | env->reserve = (target_ulong)-1ULL; |
d9bce9d9 JM |
179 | RETURN(); |
180 | } | |
181 | #endif | |
182 | ||
183 | void OPPROTO glue(op_stwcx_le, MEMSUFFIX) (void) | |
184 | { | |
185 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 186 | raise_exception(env, POWERPC_EXCP_ALIGN); |
d9bce9d9 | 187 | } else { |
36081602 | 188 | if (unlikely(env->reserve != (uint32_t)T0)) { |
966439a6 | 189 | env->crf[0] = xer_so; |
d9bce9d9 JM |
190 | } else { |
191 | glue(st32r, MEMSUFFIX)((uint32_t)T0, T1); | |
966439a6 | 192 | env->crf[0] = xer_so | 0x02; |
9a64fbe4 FB |
193 | } |
194 | } | |
a73666f6 | 195 | env->reserve = (target_ulong)-1ULL; |
9a64fbe4 FB |
196 | RETURN(); |
197 | } | |
198 | ||
d9bce9d9 JM |
199 | #if defined(TARGET_PPC64) |
200 | void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void) | |
111bfab3 | 201 | { |
76a66253 | 202 | if (unlikely(T0 & 0x03)) { |
64adab3f | 203 | raise_exception(env, POWERPC_EXCP_ALIGN); |
111bfab3 | 204 | } else { |
36081602 | 205 | if (unlikely(env->reserve != (uint64_t)T0)) { |
966439a6 | 206 | env->crf[0] = xer_so; |
111bfab3 | 207 | } else { |
d9bce9d9 | 208 | glue(st32r, MEMSUFFIX)((uint64_t)T0, T1); |
966439a6 | 209 | env->crf[0] = xer_so | 0x02; |
111bfab3 FB |
210 | } |
211 | } | |
a73666f6 | 212 | env->reserve = (target_ulong)-1ULL; |
111bfab3 FB |
213 | RETURN(); |
214 | } | |
215 | ||
426613db JM |
216 | void OPPROTO glue(op_stdcx_le, MEMSUFFIX) (void) |
217 | { | |
218 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 219 | raise_exception(env, POWERPC_EXCP_ALIGN); |
426613db | 220 | } else { |
36081602 | 221 | if (unlikely(env->reserve != (uint32_t)T0)) { |
966439a6 | 222 | env->crf[0] = xer_so; |
426613db JM |
223 | } else { |
224 | glue(st64r, MEMSUFFIX)((uint32_t)T0, T1); | |
966439a6 | 225 | env->crf[0] = xer_so | 0x02; |
426613db JM |
226 | } |
227 | } | |
a73666f6 | 228 | env->reserve = (target_ulong)-1ULL; |
426613db JM |
229 | RETURN(); |
230 | } | |
231 | ||
d9bce9d9 JM |
232 | void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void) |
233 | { | |
234 | if (unlikely(T0 & 0x03)) { | |
64adab3f | 235 | raise_exception(env, POWERPC_EXCP_ALIGN); |
d9bce9d9 | 236 | } else { |
36081602 | 237 | if (unlikely(env->reserve != (uint64_t)T0)) { |
966439a6 | 238 | env->crf[0] = xer_so; |
d9bce9d9 JM |
239 | } else { |
240 | glue(st64r, MEMSUFFIX)((uint64_t)T0, T1); | |
966439a6 | 241 | env->crf[0] = xer_so | 0x02; |
d9bce9d9 JM |
242 | } |
243 | } | |
a73666f6 | 244 | env->reserve = (target_ulong)-1ULL; |
d9bce9d9 JM |
245 | RETURN(); |
246 | } | |
247 | #endif | |
248 | ||
9a64fbe4 | 249 | /* External access */ |
d9bce9d9 JM |
250 | void OPPROTO glue(op_eciwx, MEMSUFFIX) (void) |
251 | { | |
e7c24003 | 252 | T1 = glue(ldu32, MEMSUFFIX)((uint32_t)T0); |
d9bce9d9 JM |
253 | RETURN(); |
254 | } | |
255 | ||
256 | #if defined(TARGET_PPC64) | |
257 | void OPPROTO glue(op_eciwx_64, MEMSUFFIX) (void) | |
258 | { | |
e7c24003 | 259 | T1 = glue(ldu32, MEMSUFFIX)((uint64_t)T0); |
d9bce9d9 JM |
260 | RETURN(); |
261 | } | |
262 | #endif | |
263 | ||
264 | void OPPROTO glue(op_ecowx, MEMSUFFIX) (void) | |
265 | { | |
e7c24003 | 266 | glue(st32, MEMSUFFIX)((uint32_t)T0, T1); |
d9bce9d9 JM |
267 | RETURN(); |
268 | } | |
269 | ||
270 | #if defined(TARGET_PPC64) | |
271 | void OPPROTO glue(op_ecowx_64, MEMSUFFIX) (void) | |
9a64fbe4 | 272 | { |
e7c24003 | 273 | glue(st32, MEMSUFFIX)((uint64_t)T0, T1); |
9a64fbe4 FB |
274 | RETURN(); |
275 | } | |
d9bce9d9 | 276 | #endif |
9a64fbe4 | 277 | |
d9bce9d9 | 278 | void OPPROTO glue(op_eciwx_le, MEMSUFFIX) (void) |
9a64fbe4 | 279 | { |
e7c24003 | 280 | T1 = glue(ldu32r, MEMSUFFIX)((uint32_t)T0); |
9a64fbe4 FB |
281 | RETURN(); |
282 | } | |
283 | ||
d9bce9d9 JM |
284 | #if defined(TARGET_PPC64) |
285 | void OPPROTO glue(op_eciwx_le_64, MEMSUFFIX) (void) | |
111bfab3 | 286 | { |
e7c24003 | 287 | T1 = glue(ldu32r, MEMSUFFIX)((uint64_t)T0); |
111bfab3 FB |
288 | RETURN(); |
289 | } | |
d9bce9d9 | 290 | #endif |
111bfab3 | 291 | |
d9bce9d9 | 292 | void OPPROTO glue(op_ecowx_le, MEMSUFFIX) (void) |
111bfab3 | 293 | { |
d9bce9d9 | 294 | glue(st32r, MEMSUFFIX)((uint32_t)T0, T1); |
111bfab3 FB |
295 | RETURN(); |
296 | } | |
297 | ||
d9bce9d9 JM |
298 | #if defined(TARGET_PPC64) |
299 | void OPPROTO glue(op_ecowx_le_64, MEMSUFFIX) (void) | |
300 | { | |
301 | glue(st32r, MEMSUFFIX)((uint64_t)T0, T1); | |
302 | RETURN(); | |
303 | } | |
304 | #endif | |
305 | ||
76a66253 JM |
306 | /* XXX: those micro-ops need tests ! */ |
307 | /* PowerPC 601 specific instructions (POWER bridge) */ | |
308 | void OPPROTO glue(op_POWER_lscbx, MEMSUFFIX) (void) | |
309 | { | |
310 | /* When byte count is 0, do nothing */ | |
d9bce9d9 | 311 | if (likely(T1 != 0)) { |
76a66253 JM |
312 | glue(do_POWER_lscbx, MEMSUFFIX)(PARAM1, PARAM2, PARAM3); |
313 | } | |
314 | RETURN(); | |
315 | } | |
316 | ||
9a64fbe4 | 317 | #undef MEMSUFFIX |