]>
Commit | Line | Data |
---|---|---|
79aceca5 | 1 | /* |
3fc6c082 | 2 | * PowerPC emulation micro-operations for qemu. |
5fafdf24 | 3 | * |
76a66253 | 4 | * Copyright (c) 2003-2007 Jocelyn Mayer |
79aceca5 FB |
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 | ||
a541f297 FB |
21 | //#define DEBUG_OP |
22 | ||
79aceca5 FB |
23 | #include "config.h" |
24 | #include "exec.h" | |
603fccce | 25 | #include "host-utils.h" |
0411a972 | 26 | #include "helper_regs.h" |
76a66253 | 27 | #include "op_helper.h" |
79aceca5 | 28 | |
76a66253 JM |
29 | #if !defined(CONFIG_USER_ONLY) |
30 | /* Segment registers load and store */ | |
36081602 | 31 | void OPPROTO op_load_sr (void) |
76a66253 | 32 | { |
36081602 | 33 | T0 = env->sr[T1]; |
76a66253 JM |
34 | RETURN(); |
35 | } | |
36 | ||
36081602 | 37 | void OPPROTO op_store_sr (void) |
76a66253 JM |
38 | { |
39 | do_store_sr(env, T1, T0); | |
40 | RETURN(); | |
41 | } | |
42 | ||
12de9a39 JM |
43 | #if defined(TARGET_PPC64) |
44 | void OPPROTO op_load_slb (void) | |
45 | { | |
46 | T0 = ppc_load_slb(env, T1); | |
47 | RETURN(); | |
48 | } | |
49 | ||
50 | void OPPROTO op_store_slb (void) | |
51 | { | |
52 | ppc_store_slb(env, T1, T0); | |
53 | RETURN(); | |
54 | } | |
55 | #endif /* defined(TARGET_PPC64) */ | |
56 | ||
36081602 | 57 | void OPPROTO op_load_sdr1 (void) |
76a66253 | 58 | { |
36081602 | 59 | T0 = env->sdr1; |
76a66253 JM |
60 | RETURN(); |
61 | } | |
62 | ||
36081602 | 63 | void OPPROTO op_store_sdr1 (void) |
76a66253 JM |
64 | { |
65 | do_store_sdr1(env, T0); | |
79aceca5 FB |
66 | RETURN(); |
67 | } | |
68 | ||
d9bce9d9 JM |
69 | #if defined (TARGET_PPC64) |
70 | void OPPROTO op_load_asr (void) | |
71 | { | |
72 | T0 = env->asr; | |
73 | RETURN(); | |
74 | } | |
75 | ||
76 | void OPPROTO op_store_asr (void) | |
77 | { | |
78 | ppc_store_asr(env, T0); | |
79 | RETURN(); | |
80 | } | |
81 | #endif | |
82 | ||
6676f424 AJ |
83 | void OPPROTO op_load_msr (void) |
84 | { | |
85 | T0 = env->msr; | |
86 | RETURN(); | |
87 | } | |
88 | ||
89 | void OPPROTO op_store_msr (void) | |
90 | { | |
91 | do_store_msr(); | |
92 | RETURN(); | |
93 | } | |
94 | ||
95 | #if defined (TARGET_PPC64) | |
96 | void OPPROTO op_store_msr_32 (void) | |
97 | { | |
98 | T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF); | |
99 | do_store_msr(); | |
100 | RETURN(); | |
101 | } | |
102 | #endif | |
103 | ||
0411a972 | 104 | void OPPROTO op_update_riee (void) |
d9bce9d9 | 105 | { |
0411a972 JM |
106 | /* We don't call do_store_msr here as we won't trigger |
107 | * any special case nor change hflags | |
108 | */ | |
109 | T0 &= (1 << MSR_RI) | (1 << MSR_EE); | |
110 | env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE); | |
111 | env->msr |= T0; | |
d9bce9d9 JM |
112 | RETURN(); |
113 | } | |
114 | #endif | |
9a64fbe4 FB |
115 | |
116 | /* SPR */ | |
a496775f JM |
117 | void OPPROTO op_load_spr (void) |
118 | { | |
119 | T0 = env->spr[PARAM1]; | |
120 | RETURN(); | |
121 | } | |
122 | ||
123 | void OPPROTO op_store_spr (void) | |
124 | { | |
125 | env->spr[PARAM1] = T0; | |
126 | RETURN(); | |
127 | } | |
128 | ||
129 | void OPPROTO op_load_dump_spr (void) | |
130 | { | |
131 | T0 = ppc_load_dump_spr(PARAM1); | |
132 | RETURN(); | |
133 | } | |
134 | ||
135 | void OPPROTO op_store_dump_spr (void) | |
9a64fbe4 | 136 | { |
a496775f | 137 | ppc_store_dump_spr(PARAM1, T0); |
9a64fbe4 FB |
138 | RETURN(); |
139 | } | |
140 | ||
a496775f | 141 | void OPPROTO op_mask_spr (void) |
9a64fbe4 | 142 | { |
a496775f | 143 | env->spr[PARAM1] &= ~T0; |
79aceca5 FB |
144 | RETURN(); |
145 | } | |
146 | ||
36081602 | 147 | void OPPROTO op_load_tbl (void) |
9a64fbe4 | 148 | { |
36081602 | 149 | T0 = cpu_ppc_load_tbl(env); |
9a64fbe4 FB |
150 | RETURN(); |
151 | } | |
152 | ||
36081602 | 153 | void OPPROTO op_load_tbu (void) |
9a64fbe4 | 154 | { |
36081602 | 155 | T0 = cpu_ppc_load_tbu(env); |
9a64fbe4 FB |
156 | RETURN(); |
157 | } | |
158 | ||
a062e36c JM |
159 | void OPPROTO op_load_atbl (void) |
160 | { | |
161 | T0 = cpu_ppc_load_atbl(env); | |
162 | RETURN(); | |
163 | } | |
164 | ||
165 | void OPPROTO op_load_atbu (void) | |
166 | { | |
167 | T0 = cpu_ppc_load_atbu(env); | |
168 | RETURN(); | |
169 | } | |
170 | ||
76a66253 | 171 | #if !defined(CONFIG_USER_ONLY) |
36081602 | 172 | void OPPROTO op_store_tbl (void) |
9a64fbe4 | 173 | { |
36081602 | 174 | cpu_ppc_store_tbl(env, T0); |
79aceca5 FB |
175 | RETURN(); |
176 | } | |
177 | ||
36081602 | 178 | void OPPROTO op_store_tbu (void) |
9a64fbe4 | 179 | { |
36081602 | 180 | cpu_ppc_store_tbu(env, T0); |
9a64fbe4 FB |
181 | RETURN(); |
182 | } | |
183 | ||
a062e36c JM |
184 | void OPPROTO op_store_atbl (void) |
185 | { | |
186 | cpu_ppc_store_atbl(env, T0); | |
187 | RETURN(); | |
188 | } | |
189 | ||
190 | void OPPROTO op_store_atbu (void) | |
191 | { | |
192 | cpu_ppc_store_atbu(env, T0); | |
193 | RETURN(); | |
194 | } | |
195 | ||
36081602 | 196 | void OPPROTO op_load_decr (void) |
9a64fbe4 | 197 | { |
36081602 | 198 | T0 = cpu_ppc_load_decr(env); |
76a66253 JM |
199 | RETURN(); |
200 | } | |
9fddaa0c | 201 | |
36081602 | 202 | void OPPROTO op_store_decr (void) |
9fddaa0c | 203 | { |
36081602 | 204 | cpu_ppc_store_decr(env, T0); |
9a64fbe4 FB |
205 | RETURN(); |
206 | } | |
207 | ||
36081602 | 208 | void OPPROTO op_load_ibat (void) |
9a64fbe4 | 209 | { |
36081602 | 210 | T0 = env->IBAT[PARAM1][PARAM2]; |
76a66253 | 211 | RETURN(); |
9a64fbe4 FB |
212 | } |
213 | ||
76a66253 | 214 | void OPPROTO op_store_ibatu (void) |
9a64fbe4 | 215 | { |
3fc6c082 FB |
216 | do_store_ibatu(env, PARAM1, T0); |
217 | RETURN(); | |
218 | } | |
219 | ||
76a66253 | 220 | void OPPROTO op_store_ibatl (void) |
3fc6c082 FB |
221 | { |
222 | #if 1 | |
223 | env->IBAT[1][PARAM1] = T0; | |
224 | #else | |
225 | do_store_ibatl(env, PARAM1, T0); | |
226 | #endif | |
227 | RETURN(); | |
9a64fbe4 FB |
228 | } |
229 | ||
36081602 | 230 | void OPPROTO op_load_dbat (void) |
9a64fbe4 | 231 | { |
36081602 | 232 | T0 = env->DBAT[PARAM1][PARAM2]; |
76a66253 | 233 | RETURN(); |
9a64fbe4 FB |
234 | } |
235 | ||
76a66253 | 236 | void OPPROTO op_store_dbatu (void) |
3fc6c082 FB |
237 | { |
238 | do_store_dbatu(env, PARAM1, T0); | |
239 | RETURN(); | |
240 | } | |
241 | ||
76a66253 | 242 | void OPPROTO op_store_dbatl (void) |
9a64fbe4 | 243 | { |
3fc6c082 FB |
244 | #if 1 |
245 | env->DBAT[1][PARAM1] = T0; | |
246 | #else | |
247 | do_store_dbatl(env, PARAM1, T0); | |
248 | #endif | |
249 | RETURN(); | |
9a64fbe4 | 250 | } |
76a66253 | 251 | #endif /* !defined(CONFIG_USER_ONLY) */ |
9a64fbe4 | 252 | |
79aceca5 | 253 | /*** Integer shift ***/ |
76a66253 JM |
254 | void OPPROTO op_srli_T1 (void) |
255 | { | |
d9bce9d9 | 256 | T1 = (uint32_t)T1 >> PARAM1; |
76a66253 JM |
257 | RETURN(); |
258 | } | |
259 | ||
9a64fbe4 | 260 | /* Load and store */ |
9a64fbe4 | 261 | #define MEMSUFFIX _raw |
76a66253 | 262 | #include "op_helper.h" |
9a64fbe4 | 263 | #include "op_mem.h" |
a541f297 | 264 | #if !defined(CONFIG_USER_ONLY) |
9a64fbe4 | 265 | #define MEMSUFFIX _user |
76a66253 | 266 | #include "op_helper.h" |
9a64fbe4 | 267 | #include "op_mem.h" |
9a64fbe4 | 268 | #define MEMSUFFIX _kernel |
76a66253 | 269 | #include "op_helper.h" |
9a64fbe4 | 270 | #include "op_mem.h" |
1e42b8f0 JM |
271 | #define MEMSUFFIX _hypv |
272 | #include "op_helper.h" | |
273 | #include "op_mem.h" | |
274 | #endif | |
9a64fbe4 | 275 | |
4b3686fa | 276 | /* Special op to check and maybe clear reservation */ |
d9bce9d9 | 277 | void OPPROTO op_check_reservation (void) |
4b3686fa | 278 | { |
fdabc366 | 279 | if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003)) |
a73666f6 | 280 | env->reserve = (target_ulong)-1ULL; |
4b3686fa FB |
281 | RETURN(); |
282 | } | |
283 | ||
d9bce9d9 JM |
284 | #if defined(TARGET_PPC64) |
285 | void OPPROTO op_check_reservation_64 (void) | |
286 | { | |
287 | if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003)) | |
6f2d8978 | 288 | env->reserve = (target_ulong)-1ULL; |
d9bce9d9 JM |
289 | RETURN(); |
290 | } | |
291 | #endif | |
292 | ||
be147d08 JM |
293 | void OPPROTO op_wait (void) |
294 | { | |
295 | env->halted = 1; | |
296 | RETURN(); | |
297 | } | |
298 | ||
9a64fbe4 | 299 | /* Return from interrupt */ |
76a66253 JM |
300 | #if !defined(CONFIG_USER_ONLY) |
301 | void OPPROTO op_rfi (void) | |
28b6751f | 302 | { |
fdabc366 | 303 | do_rfi(); |
fb0eaffc FB |
304 | RETURN(); |
305 | } | |
d9bce9d9 JM |
306 | |
307 | #if defined(TARGET_PPC64) | |
426613db JM |
308 | void OPPROTO op_rfid (void) |
309 | { | |
310 | do_rfid(); | |
311 | RETURN(); | |
312 | } | |
be147d08 | 313 | |
be147d08 JM |
314 | void OPPROTO op_hrfid (void) |
315 | { | |
316 | do_hrfid(); | |
317 | RETURN(); | |
318 | } | |
319 | #endif | |
6f5d427d JM |
320 | |
321 | /* Exception vectors */ | |
322 | void OPPROTO op_store_excp_prefix (void) | |
323 | { | |
324 | T0 &= env->ivpr_mask; | |
325 | env->excp_prefix = T0; | |
326 | RETURN(); | |
327 | } | |
328 | ||
329 | void OPPROTO op_store_excp_vector (void) | |
330 | { | |
331 | T0 &= env->ivor_mask; | |
332 | env->excp_vectors[PARAM1] = T0; | |
333 | RETURN(); | |
334 | } | |
76a66253 | 335 | #endif |
fb0eaffc | 336 | |
76a66253 | 337 | #if !defined(CONFIG_USER_ONLY) |
9a64fbe4 | 338 | /* tlbia */ |
36081602 | 339 | void OPPROTO op_tlbia (void) |
fb0eaffc | 340 | { |
daf4f96e | 341 | ppc_tlb_invalidate_all(env); |
9a64fbe4 FB |
342 | RETURN(); |
343 | } | |
344 | ||
345 | /* tlbie */ | |
d9bce9d9 | 346 | void OPPROTO op_tlbie (void) |
9a64fbe4 | 347 | { |
daf4f96e | 348 | ppc_tlb_invalidate_one(env, (uint32_t)T0); |
fb0eaffc | 349 | RETURN(); |
28b6751f | 350 | } |
d9bce9d9 JM |
351 | |
352 | #if defined(TARGET_PPC64) | |
353 | void OPPROTO op_tlbie_64 (void) | |
354 | { | |
daf4f96e | 355 | ppc_tlb_invalidate_one(env, T0); |
d9bce9d9 JM |
356 | RETURN(); |
357 | } | |
358 | #endif | |
359 | ||
360 | #if defined(TARGET_PPC64) | |
361 | void OPPROTO op_slbia (void) | |
362 | { | |
daf4f96e | 363 | ppc_slb_invalidate_all(env); |
d9bce9d9 JM |
364 | RETURN(); |
365 | } | |
366 | ||
367 | void OPPROTO op_slbie (void) | |
368 | { | |
daf4f96e JM |
369 | ppc_slb_invalidate_one(env, (uint32_t)T0); |
370 | RETURN(); | |
371 | } | |
372 | ||
373 | void OPPROTO op_slbie_64 (void) | |
374 | { | |
375 | ppc_slb_invalidate_one(env, T0); | |
d9bce9d9 JM |
376 | RETURN(); |
377 | } | |
378 | #endif | |
76a66253 | 379 | #endif |
3fc6c082 | 380 | |
76a66253 | 381 | /* 601 specific */ |
76a66253 JM |
382 | void OPPROTO op_load_601_rtcl (void) |
383 | { | |
384 | T0 = cpu_ppc601_load_rtcl(env); | |
385 | RETURN(); | |
386 | } | |
387 | ||
76a66253 JM |
388 | void OPPROTO op_load_601_rtcu (void) |
389 | { | |
390 | T0 = cpu_ppc601_load_rtcu(env); | |
391 | RETURN(); | |
392 | } | |
393 | ||
394 | #if !defined(CONFIG_USER_ONLY) | |
76a66253 JM |
395 | void OPPROTO op_store_601_rtcl (void) |
396 | { | |
397 | cpu_ppc601_store_rtcl(env, T0); | |
398 | RETURN(); | |
399 | } | |
400 | ||
76a66253 JM |
401 | void OPPROTO op_store_601_rtcu (void) |
402 | { | |
403 | cpu_ppc601_store_rtcu(env, T0); | |
404 | RETURN(); | |
405 | } | |
406 | ||
056401ea JM |
407 | void OPPROTO op_store_hid0_601 (void) |
408 | { | |
409 | do_store_hid0_601(); | |
410 | RETURN(); | |
411 | } | |
412 | ||
76a66253 JM |
413 | void OPPROTO op_load_601_bat (void) |
414 | { | |
415 | T0 = env->IBAT[PARAM1][PARAM2]; | |
416 | RETURN(); | |
417 | } | |
76a66253 | 418 | |
76a66253 JM |
419 | void OPPROTO op_store_601_batl (void) |
420 | { | |
056401ea | 421 | do_store_ibatl_601(env, PARAM1, T0); |
76a66253 JM |
422 | RETURN(); |
423 | } | |
424 | ||
425 | void OPPROTO op_store_601_batu (void) | |
426 | { | |
056401ea | 427 | do_store_ibatu_601(env, PARAM1, T0); |
76a66253 JM |
428 | RETURN(); |
429 | } | |
430 | #endif /* !defined(CONFIG_USER_ONLY) */ | |
431 | ||
432 | /* PowerPC 601 specific instructions (POWER bridge) */ | |
433 | /* XXX: those micro-ops need tests ! */ | |
434 | void OPPROTO op_POWER_abs (void) | |
435 | { | |
9c7e37e7 | 436 | if ((int32_t)T0 == INT32_MIN) |
76a66253 | 437 | T0 = INT32_MAX; |
9c7e37e7 | 438 | else if ((int32_t)T0 < 0) |
76a66253 JM |
439 | T0 = -T0; |
440 | RETURN(); | |
441 | } | |
442 | ||
443 | void OPPROTO op_POWER_abso (void) | |
444 | { | |
445 | do_POWER_abso(); | |
446 | RETURN(); | |
447 | } | |
448 | ||
449 | void OPPROTO op_POWER_clcs (void) | |
450 | { | |
451 | do_POWER_clcs(); | |
452 | RETURN(); | |
453 | } | |
454 | ||
455 | void OPPROTO op_POWER_div (void) | |
456 | { | |
457 | do_POWER_div(); | |
458 | RETURN(); | |
459 | } | |
460 | ||
461 | void OPPROTO op_POWER_divo (void) | |
462 | { | |
463 | do_POWER_divo(); | |
464 | RETURN(); | |
465 | } | |
466 | ||
467 | void OPPROTO op_POWER_divs (void) | |
468 | { | |
469 | do_POWER_divs(); | |
470 | RETURN(); | |
471 | } | |
472 | ||
473 | void OPPROTO op_POWER_divso (void) | |
474 | { | |
475 | do_POWER_divso(); | |
476 | RETURN(); | |
477 | } | |
478 | ||
479 | void OPPROTO op_POWER_doz (void) | |
480 | { | |
d9bce9d9 | 481 | if ((int32_t)T1 > (int32_t)T0) |
76a66253 JM |
482 | T0 = T1 - T0; |
483 | else | |
484 | T0 = 0; | |
485 | RETURN(); | |
486 | } | |
487 | ||
488 | void OPPROTO op_POWER_dozo (void) | |
489 | { | |
490 | do_POWER_dozo(); | |
491 | RETURN(); | |
492 | } | |
493 | ||
76a66253 JM |
494 | void OPPROTO op_POWER_maskg (void) |
495 | { | |
496 | do_POWER_maskg(); | |
497 | RETURN(); | |
498 | } | |
499 | ||
500 | void OPPROTO op_POWER_maskir (void) | |
501 | { | |
502 | T0 = (T0 & ~T2) | (T1 & T2); | |
503 | RETURN(); | |
504 | } | |
505 | ||
506 | void OPPROTO op_POWER_mul (void) | |
507 | { | |
508 | uint64_t tmp; | |
509 | ||
510 | tmp = (uint64_t)T0 * (uint64_t)T1; | |
511 | env->spr[SPR_MQ] = tmp >> 32; | |
512 | T0 = tmp; | |
513 | RETURN(); | |
514 | } | |
515 | ||
516 | void OPPROTO op_POWER_mulo (void) | |
517 | { | |
518 | do_POWER_mulo(); | |
519 | RETURN(); | |
520 | } | |
521 | ||
522 | void OPPROTO op_POWER_nabs (void) | |
523 | { | |
524 | if (T0 > 0) | |
525 | T0 = -T0; | |
526 | RETURN(); | |
527 | } | |
528 | ||
529 | void OPPROTO op_POWER_nabso (void) | |
530 | { | |
531 | /* nabs never overflows */ | |
532 | if (T0 > 0) | |
533 | T0 = -T0; | |
3d7b417e | 534 | env->xer &= ~(1 << XER_OV); |
76a66253 JM |
535 | RETURN(); |
536 | } | |
537 | ||
538 | /* XXX: factorise POWER rotates... */ | |
539 | void OPPROTO op_POWER_rlmi (void) | |
540 | { | |
541 | T0 = rotl32(T0, T2) & PARAM1; | |
2f401176 | 542 | T0 |= T1 & (uint32_t)PARAM2; |
76a66253 JM |
543 | RETURN(); |
544 | } | |
545 | ||
546 | void OPPROTO op_POWER_rrib (void) | |
547 | { | |
548 | T2 &= 0x1FUL; | |
549 | T0 = rotl32(T0 & INT32_MIN, T2); | |
550 | T0 |= T1 & ~rotl32(INT32_MIN, T2); | |
551 | RETURN(); | |
552 | } | |
553 | ||
554 | void OPPROTO op_POWER_sle (void) | |
555 | { | |
556 | T1 &= 0x1FUL; | |
557 | env->spr[SPR_MQ] = rotl32(T0, T1); | |
558 | T0 = T0 << T1; | |
559 | RETURN(); | |
560 | } | |
561 | ||
562 | void OPPROTO op_POWER_sleq (void) | |
563 | { | |
564 | uint32_t tmp = env->spr[SPR_MQ]; | |
565 | ||
566 | T1 &= 0x1FUL; | |
567 | env->spr[SPR_MQ] = rotl32(T0, T1); | |
568 | T0 = T0 << T1; | |
569 | T0 |= tmp >> (32 - T1); | |
570 | RETURN(); | |
571 | } | |
572 | ||
573 | void OPPROTO op_POWER_sllq (void) | |
574 | { | |
6f2d8978 | 575 | uint32_t msk = UINT32_MAX; |
76a66253 JM |
576 | |
577 | msk = msk << (T1 & 0x1FUL); | |
578 | if (T1 & 0x20UL) | |
579 | msk = ~msk; | |
580 | T1 &= 0x1FUL; | |
581 | T0 = (T0 << T1) & msk; | |
582 | T0 |= env->spr[SPR_MQ] & ~msk; | |
583 | RETURN(); | |
584 | } | |
585 | ||
586 | void OPPROTO op_POWER_slq (void) | |
587 | { | |
6f2d8978 | 588 | uint32_t msk = UINT32_MAX, tmp; |
76a66253 JM |
589 | |
590 | msk = msk << (T1 & 0x1FUL); | |
591 | if (T1 & 0x20UL) | |
592 | msk = ~msk; | |
593 | T1 &= 0x1FUL; | |
594 | tmp = rotl32(T0, T1); | |
595 | T0 = tmp & msk; | |
596 | env->spr[SPR_MQ] = tmp; | |
597 | RETURN(); | |
598 | } | |
599 | ||
600 | void OPPROTO op_POWER_sraq (void) | |
601 | { | |
602 | env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL)); | |
603 | if (T1 & 0x20UL) | |
6f2d8978 | 604 | T0 = UINT32_MAX; |
76a66253 | 605 | else |
d9bce9d9 | 606 | T0 = (int32_t)T0 >> T1; |
76a66253 JM |
607 | RETURN(); |
608 | } | |
609 | ||
610 | void OPPROTO op_POWER_sre (void) | |
611 | { | |
612 | T1 &= 0x1FUL; | |
613 | env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
d9bce9d9 | 614 | T0 = (int32_t)T0 >> T1; |
76a66253 JM |
615 | RETURN(); |
616 | } | |
617 | ||
618 | void OPPROTO op_POWER_srea (void) | |
619 | { | |
620 | T1 &= 0x1FUL; | |
621 | env->spr[SPR_MQ] = T0 >> T1; | |
d9bce9d9 | 622 | T0 = (int32_t)T0 >> T1; |
76a66253 JM |
623 | RETURN(); |
624 | } | |
625 | ||
626 | void OPPROTO op_POWER_sreq (void) | |
627 | { | |
628 | uint32_t tmp; | |
629 | int32_t msk; | |
630 | ||
631 | T1 &= 0x1FUL; | |
632 | msk = INT32_MIN >> T1; | |
633 | tmp = env->spr[SPR_MQ]; | |
634 | env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
635 | T0 = T0 >> T1; | |
636 | T0 |= tmp & msk; | |
637 | RETURN(); | |
638 | } | |
639 | ||
640 | void OPPROTO op_POWER_srlq (void) | |
641 | { | |
642 | uint32_t tmp; | |
643 | int32_t msk; | |
644 | ||
645 | msk = INT32_MIN >> (T1 & 0x1FUL); | |
646 | if (T1 & 0x20UL) | |
647 | msk = ~msk; | |
648 | T1 &= 0x1FUL; | |
649 | tmp = env->spr[SPR_MQ]; | |
650 | env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
651 | T0 = T0 >> T1; | |
652 | T0 &= msk; | |
653 | T0 |= tmp & ~msk; | |
654 | RETURN(); | |
655 | } | |
656 | ||
657 | void OPPROTO op_POWER_srq (void) | |
658 | { | |
659 | T1 &= 0x1FUL; | |
660 | env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
661 | T0 = T0 >> T1; | |
662 | RETURN(); | |
663 | } | |
664 | ||
665 | /* POWER instructions not implemented in PowerPC 601 */ | |
666 | #if !defined(CONFIG_USER_ONLY) | |
667 | void OPPROTO op_POWER_mfsri (void) | |
668 | { | |
669 | T1 = T0 >> 28; | |
670 | T0 = env->sr[T1]; | |
671 | RETURN(); | |
672 | } | |
673 | ||
674 | void OPPROTO op_POWER_rac (void) | |
675 | { | |
676 | do_POWER_rac(); | |
677 | RETURN(); | |
678 | } | |
679 | ||
680 | void OPPROTO op_POWER_rfsvc (void) | |
681 | { | |
682 | do_POWER_rfsvc(); | |
683 | RETURN(); | |
684 | } | |
685 | #endif | |
686 | ||
76a66253 | 687 | /* PowerPC 4xx specific micro-ops */ |
a42bd6cc | 688 | void OPPROTO op_load_dcr (void) |
76a66253 | 689 | { |
a42bd6cc | 690 | do_load_dcr(); |
76a66253 JM |
691 | RETURN(); |
692 | } | |
693 | ||
a42bd6cc | 694 | void OPPROTO op_store_dcr (void) |
76a66253 | 695 | { |
a42bd6cc | 696 | do_store_dcr(); |
76a66253 JM |
697 | RETURN(); |
698 | } | |
699 | ||
a750fc0b | 700 | #if !defined(CONFIG_USER_ONLY) |
76a66253 JM |
701 | /* Return from critical interrupt : |
702 | * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1 | |
703 | */ | |
a42bd6cc JM |
704 | void OPPROTO op_40x_rfci (void) |
705 | { | |
706 | do_40x_rfci(); | |
707 | RETURN(); | |
708 | } | |
709 | ||
710 | void OPPROTO op_rfci (void) | |
711 | { | |
712 | do_rfci(); | |
713 | RETURN(); | |
714 | } | |
715 | ||
716 | void OPPROTO op_rfdi (void) | |
717 | { | |
718 | do_rfdi(); | |
719 | RETURN(); | |
720 | } | |
721 | ||
722 | void OPPROTO op_rfmci (void) | |
76a66253 | 723 | { |
a42bd6cc | 724 | do_rfmci(); |
76a66253 JM |
725 | RETURN(); |
726 | } | |
727 | ||
a42bd6cc | 728 | void OPPROTO op_wrte (void) |
76a66253 | 729 | { |
0411a972 JM |
730 | /* We don't call do_store_msr here as we won't trigger |
731 | * any special case nor change hflags | |
732 | */ | |
733 | T0 &= 1 << MSR_EE; | |
734 | env->msr &= ~(1 << MSR_EE); | |
735 | env->msr |= T0; | |
76a66253 JM |
736 | RETURN(); |
737 | } | |
738 | ||
a4bb6c3e | 739 | void OPPROTO op_440_tlbre (void) |
5eb7995e | 740 | { |
a4bb6c3e | 741 | do_440_tlbre(PARAM1); |
5eb7995e JM |
742 | RETURN(); |
743 | } | |
744 | ||
a4bb6c3e | 745 | void OPPROTO op_440_tlbsx (void) |
5eb7995e | 746 | { |
daf4f96e | 747 | T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF); |
5eb7995e JM |
748 | RETURN(); |
749 | } | |
750 | ||
daf4f96e | 751 | void OPPROTO op_4xx_tlbsx_check (void) |
5eb7995e | 752 | { |
daf4f96e JM |
753 | int tmp; |
754 | ||
755 | tmp = xer_so; | |
6f2d8978 | 756 | if ((int)T0 != -1) |
daf4f96e JM |
757 | tmp |= 0x02; |
758 | env->crf[0] = tmp; | |
5eb7995e JM |
759 | RETURN(); |
760 | } | |
761 | ||
a4bb6c3e | 762 | void OPPROTO op_440_tlbwe (void) |
5eb7995e | 763 | { |
a4bb6c3e | 764 | do_440_tlbwe(PARAM1); |
5eb7995e JM |
765 | RETURN(); |
766 | } | |
767 | ||
76a66253 JM |
768 | void OPPROTO op_4xx_tlbre_lo (void) |
769 | { | |
770 | do_4xx_tlbre_lo(); | |
771 | RETURN(); | |
772 | } | |
773 | ||
774 | void OPPROTO op_4xx_tlbre_hi (void) | |
775 | { | |
776 | do_4xx_tlbre_hi(); | |
777 | RETURN(); | |
778 | } | |
779 | ||
780 | void OPPROTO op_4xx_tlbsx (void) | |
781 | { | |
daf4f96e | 782 | T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]); |
76a66253 JM |
783 | RETURN(); |
784 | } | |
785 | ||
786 | void OPPROTO op_4xx_tlbwe_lo (void) | |
787 | { | |
788 | do_4xx_tlbwe_lo(); | |
789 | RETURN(); | |
790 | } | |
791 | ||
792 | void OPPROTO op_4xx_tlbwe_hi (void) | |
793 | { | |
794 | do_4xx_tlbwe_hi(); | |
795 | RETURN(); | |
796 | } | |
797 | #endif | |
798 | ||
799 | /* SPR micro-ops */ | |
800 | /* 440 specific */ | |
801 | void OPPROTO op_440_dlmzb (void) | |
802 | { | |
803 | do_440_dlmzb(); | |
804 | RETURN(); | |
805 | } | |
806 | ||
807 | void OPPROTO op_440_dlmzb_update_Rc (void) | |
808 | { | |
809 | if (T0 == 8) | |
810 | T0 = 0x2; | |
811 | else if (T0 < 4) | |
812 | T0 = 0x4; | |
813 | else | |
814 | T0 = 0x8; | |
815 | RETURN(); | |
816 | } | |
817 | ||
818 | #if !defined(CONFIG_USER_ONLY) | |
819 | void OPPROTO op_store_pir (void) | |
3fc6c082 FB |
820 | { |
821 | env->spr[SPR_PIR] = T0 & 0x0000000FUL; | |
822 | RETURN(); | |
823 | } | |
76a66253 JM |
824 | |
825 | void OPPROTO op_load_403_pb (void) | |
826 | { | |
827 | do_load_403_pb(PARAM1); | |
828 | RETURN(); | |
829 | } | |
830 | ||
831 | void OPPROTO op_store_403_pb (void) | |
832 | { | |
833 | do_store_403_pb(PARAM1); | |
834 | RETURN(); | |
835 | } | |
836 | ||
76a66253 JM |
837 | void OPPROTO op_load_40x_pit (void) |
838 | { | |
839 | T0 = load_40x_pit(env); | |
840 | RETURN(); | |
841 | } | |
842 | ||
76a66253 JM |
843 | void OPPROTO op_store_40x_pit (void) |
844 | { | |
845 | store_40x_pit(env, T0); | |
846 | RETURN(); | |
847 | } | |
848 | ||
8ecc7913 JM |
849 | void OPPROTO op_store_40x_dbcr0 (void) |
850 | { | |
851 | store_40x_dbcr0(env, T0); | |
be147d08 | 852 | RETURN(); |
8ecc7913 JM |
853 | } |
854 | ||
c294fc58 JM |
855 | void OPPROTO op_store_40x_sler (void) |
856 | { | |
857 | store_40x_sler(env, T0); | |
858 | RETURN(); | |
859 | } | |
860 | ||
76a66253 JM |
861 | void OPPROTO op_store_booke_tcr (void) |
862 | { | |
863 | store_booke_tcr(env, T0); | |
864 | RETURN(); | |
865 | } | |
866 | ||
76a66253 JM |
867 | void OPPROTO op_store_booke_tsr (void) |
868 | { | |
869 | store_booke_tsr(env, T0); | |
870 | RETURN(); | |
871 | } | |
872 | #endif /* !defined(CONFIG_USER_ONLY) */ | |
0487d6a8 | 873 |