]>
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 | |
9a64fbe4 | 337 | /* Trap word */ |
76a66253 | 338 | void OPPROTO op_tw (void) |
fb0eaffc | 339 | { |
76a66253 | 340 | do_tw(PARAM1); |
fb0eaffc FB |
341 | RETURN(); |
342 | } | |
343 | ||
d9bce9d9 JM |
344 | #if defined(TARGET_PPC64) |
345 | void OPPROTO op_td (void) | |
346 | { | |
347 | do_td(PARAM1); | |
348 | RETURN(); | |
349 | } | |
350 | #endif | |
351 | ||
76a66253 | 352 | #if !defined(CONFIG_USER_ONLY) |
9a64fbe4 | 353 | /* tlbia */ |
36081602 | 354 | void OPPROTO op_tlbia (void) |
fb0eaffc | 355 | { |
daf4f96e | 356 | ppc_tlb_invalidate_all(env); |
9a64fbe4 FB |
357 | RETURN(); |
358 | } | |
359 | ||
360 | /* tlbie */ | |
d9bce9d9 | 361 | void OPPROTO op_tlbie (void) |
9a64fbe4 | 362 | { |
daf4f96e | 363 | ppc_tlb_invalidate_one(env, (uint32_t)T0); |
fb0eaffc | 364 | RETURN(); |
28b6751f | 365 | } |
d9bce9d9 JM |
366 | |
367 | #if defined(TARGET_PPC64) | |
368 | void OPPROTO op_tlbie_64 (void) | |
369 | { | |
daf4f96e | 370 | ppc_tlb_invalidate_one(env, T0); |
d9bce9d9 JM |
371 | RETURN(); |
372 | } | |
373 | #endif | |
374 | ||
375 | #if defined(TARGET_PPC64) | |
376 | void OPPROTO op_slbia (void) | |
377 | { | |
daf4f96e | 378 | ppc_slb_invalidate_all(env); |
d9bce9d9 JM |
379 | RETURN(); |
380 | } | |
381 | ||
382 | void OPPROTO op_slbie (void) | |
383 | { | |
daf4f96e JM |
384 | ppc_slb_invalidate_one(env, (uint32_t)T0); |
385 | RETURN(); | |
386 | } | |
387 | ||
388 | void OPPROTO op_slbie_64 (void) | |
389 | { | |
390 | ppc_slb_invalidate_one(env, T0); | |
d9bce9d9 JM |
391 | RETURN(); |
392 | } | |
393 | #endif | |
76a66253 | 394 | #endif |
3fc6c082 | 395 | |
76a66253 | 396 | #if !defined(CONFIG_USER_ONLY) |
7dbe11ac | 397 | /* PowerPC 602/603/755 software TLB load instructions */ |
76a66253 JM |
398 | void OPPROTO op_6xx_tlbld (void) |
399 | { | |
400 | do_load_6xx_tlb(0); | |
401 | RETURN(); | |
402 | } | |
403 | ||
404 | void OPPROTO op_6xx_tlbli (void) | |
405 | { | |
406 | do_load_6xx_tlb(1); | |
407 | RETURN(); | |
408 | } | |
7dbe11ac JM |
409 | |
410 | /* PowerPC 74xx software TLB load instructions */ | |
411 | void OPPROTO op_74xx_tlbld (void) | |
412 | { | |
413 | do_load_74xx_tlb(0); | |
414 | RETURN(); | |
415 | } | |
416 | ||
417 | void OPPROTO op_74xx_tlbli (void) | |
418 | { | |
419 | do_load_74xx_tlb(1); | |
420 | RETURN(); | |
421 | } | |
76a66253 JM |
422 | #endif |
423 | ||
424 | /* 601 specific */ | |
76a66253 JM |
425 | void OPPROTO op_load_601_rtcl (void) |
426 | { | |
427 | T0 = cpu_ppc601_load_rtcl(env); | |
428 | RETURN(); | |
429 | } | |
430 | ||
76a66253 JM |
431 | void OPPROTO op_load_601_rtcu (void) |
432 | { | |
433 | T0 = cpu_ppc601_load_rtcu(env); | |
434 | RETURN(); | |
435 | } | |
436 | ||
437 | #if !defined(CONFIG_USER_ONLY) | |
76a66253 JM |
438 | void OPPROTO op_store_601_rtcl (void) |
439 | { | |
440 | cpu_ppc601_store_rtcl(env, T0); | |
441 | RETURN(); | |
442 | } | |
443 | ||
76a66253 JM |
444 | void OPPROTO op_store_601_rtcu (void) |
445 | { | |
446 | cpu_ppc601_store_rtcu(env, T0); | |
447 | RETURN(); | |
448 | } | |
449 | ||
056401ea JM |
450 | void OPPROTO op_store_hid0_601 (void) |
451 | { | |
452 | do_store_hid0_601(); | |
453 | RETURN(); | |
454 | } | |
455 | ||
76a66253 JM |
456 | void OPPROTO op_load_601_bat (void) |
457 | { | |
458 | T0 = env->IBAT[PARAM1][PARAM2]; | |
459 | RETURN(); | |
460 | } | |
76a66253 | 461 | |
76a66253 JM |
462 | void OPPROTO op_store_601_batl (void) |
463 | { | |
056401ea | 464 | do_store_ibatl_601(env, PARAM1, T0); |
76a66253 JM |
465 | RETURN(); |
466 | } | |
467 | ||
468 | void OPPROTO op_store_601_batu (void) | |
469 | { | |
056401ea | 470 | do_store_ibatu_601(env, PARAM1, T0); |
76a66253 JM |
471 | RETURN(); |
472 | } | |
473 | #endif /* !defined(CONFIG_USER_ONLY) */ | |
474 | ||
475 | /* PowerPC 601 specific instructions (POWER bridge) */ | |
476 | /* XXX: those micro-ops need tests ! */ | |
477 | void OPPROTO op_POWER_abs (void) | |
478 | { | |
9c7e37e7 | 479 | if ((int32_t)T0 == INT32_MIN) |
76a66253 | 480 | T0 = INT32_MAX; |
9c7e37e7 | 481 | else if ((int32_t)T0 < 0) |
76a66253 JM |
482 | T0 = -T0; |
483 | RETURN(); | |
484 | } | |
485 | ||
486 | void OPPROTO op_POWER_abso (void) | |
487 | { | |
488 | do_POWER_abso(); | |
489 | RETURN(); | |
490 | } | |
491 | ||
492 | void OPPROTO op_POWER_clcs (void) | |
493 | { | |
494 | do_POWER_clcs(); | |
495 | RETURN(); | |
496 | } | |
497 | ||
498 | void OPPROTO op_POWER_div (void) | |
499 | { | |
500 | do_POWER_div(); | |
501 | RETURN(); | |
502 | } | |
503 | ||
504 | void OPPROTO op_POWER_divo (void) | |
505 | { | |
506 | do_POWER_divo(); | |
507 | RETURN(); | |
508 | } | |
509 | ||
510 | void OPPROTO op_POWER_divs (void) | |
511 | { | |
512 | do_POWER_divs(); | |
513 | RETURN(); | |
514 | } | |
515 | ||
516 | void OPPROTO op_POWER_divso (void) | |
517 | { | |
518 | do_POWER_divso(); | |
519 | RETURN(); | |
520 | } | |
521 | ||
522 | void OPPROTO op_POWER_doz (void) | |
523 | { | |
d9bce9d9 | 524 | if ((int32_t)T1 > (int32_t)T0) |
76a66253 JM |
525 | T0 = T1 - T0; |
526 | else | |
527 | T0 = 0; | |
528 | RETURN(); | |
529 | } | |
530 | ||
531 | void OPPROTO op_POWER_dozo (void) | |
532 | { | |
533 | do_POWER_dozo(); | |
534 | RETURN(); | |
535 | } | |
536 | ||
537 | void OPPROTO op_load_xer_cmp (void) | |
538 | { | |
539 | T2 = xer_cmp; | |
540 | RETURN(); | |
541 | } | |
542 | ||
543 | void OPPROTO op_POWER_maskg (void) | |
544 | { | |
545 | do_POWER_maskg(); | |
546 | RETURN(); | |
547 | } | |
548 | ||
549 | void OPPROTO op_POWER_maskir (void) | |
550 | { | |
551 | T0 = (T0 & ~T2) | (T1 & T2); | |
552 | RETURN(); | |
553 | } | |
554 | ||
555 | void OPPROTO op_POWER_mul (void) | |
556 | { | |
557 | uint64_t tmp; | |
558 | ||
559 | tmp = (uint64_t)T0 * (uint64_t)T1; | |
560 | env->spr[SPR_MQ] = tmp >> 32; | |
561 | T0 = tmp; | |
562 | RETURN(); | |
563 | } | |
564 | ||
565 | void OPPROTO op_POWER_mulo (void) | |
566 | { | |
567 | do_POWER_mulo(); | |
568 | RETURN(); | |
569 | } | |
570 | ||
571 | void OPPROTO op_POWER_nabs (void) | |
572 | { | |
573 | if (T0 > 0) | |
574 | T0 = -T0; | |
575 | RETURN(); | |
576 | } | |
577 | ||
578 | void OPPROTO op_POWER_nabso (void) | |
579 | { | |
580 | /* nabs never overflows */ | |
581 | if (T0 > 0) | |
582 | T0 = -T0; | |
3d7b417e | 583 | env->xer &= ~(1 << XER_OV); |
76a66253 JM |
584 | RETURN(); |
585 | } | |
586 | ||
587 | /* XXX: factorise POWER rotates... */ | |
588 | void OPPROTO op_POWER_rlmi (void) | |
589 | { | |
590 | T0 = rotl32(T0, T2) & PARAM1; | |
2f401176 | 591 | T0 |= T1 & (uint32_t)PARAM2; |
76a66253 JM |
592 | RETURN(); |
593 | } | |
594 | ||
595 | void OPPROTO op_POWER_rrib (void) | |
596 | { | |
597 | T2 &= 0x1FUL; | |
598 | T0 = rotl32(T0 & INT32_MIN, T2); | |
599 | T0 |= T1 & ~rotl32(INT32_MIN, T2); | |
600 | RETURN(); | |
601 | } | |
602 | ||
603 | void OPPROTO op_POWER_sle (void) | |
604 | { | |
605 | T1 &= 0x1FUL; | |
606 | env->spr[SPR_MQ] = rotl32(T0, T1); | |
607 | T0 = T0 << T1; | |
608 | RETURN(); | |
609 | } | |
610 | ||
611 | void OPPROTO op_POWER_sleq (void) | |
612 | { | |
613 | uint32_t tmp = env->spr[SPR_MQ]; | |
614 | ||
615 | T1 &= 0x1FUL; | |
616 | env->spr[SPR_MQ] = rotl32(T0, T1); | |
617 | T0 = T0 << T1; | |
618 | T0 |= tmp >> (32 - T1); | |
619 | RETURN(); | |
620 | } | |
621 | ||
622 | void OPPROTO op_POWER_sllq (void) | |
623 | { | |
6f2d8978 | 624 | uint32_t msk = UINT32_MAX; |
76a66253 JM |
625 | |
626 | msk = msk << (T1 & 0x1FUL); | |
627 | if (T1 & 0x20UL) | |
628 | msk = ~msk; | |
629 | T1 &= 0x1FUL; | |
630 | T0 = (T0 << T1) & msk; | |
631 | T0 |= env->spr[SPR_MQ] & ~msk; | |
632 | RETURN(); | |
633 | } | |
634 | ||
635 | void OPPROTO op_POWER_slq (void) | |
636 | { | |
6f2d8978 | 637 | uint32_t msk = UINT32_MAX, tmp; |
76a66253 JM |
638 | |
639 | msk = msk << (T1 & 0x1FUL); | |
640 | if (T1 & 0x20UL) | |
641 | msk = ~msk; | |
642 | T1 &= 0x1FUL; | |
643 | tmp = rotl32(T0, T1); | |
644 | T0 = tmp & msk; | |
645 | env->spr[SPR_MQ] = tmp; | |
646 | RETURN(); | |
647 | } | |
648 | ||
649 | void OPPROTO op_POWER_sraq (void) | |
650 | { | |
651 | env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL)); | |
652 | if (T1 & 0x20UL) | |
6f2d8978 | 653 | T0 = UINT32_MAX; |
76a66253 | 654 | else |
d9bce9d9 | 655 | T0 = (int32_t)T0 >> T1; |
76a66253 JM |
656 | RETURN(); |
657 | } | |
658 | ||
659 | void OPPROTO op_POWER_sre (void) | |
660 | { | |
661 | T1 &= 0x1FUL; | |
662 | env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
d9bce9d9 | 663 | T0 = (int32_t)T0 >> T1; |
76a66253 JM |
664 | RETURN(); |
665 | } | |
666 | ||
667 | void OPPROTO op_POWER_srea (void) | |
668 | { | |
669 | T1 &= 0x1FUL; | |
670 | env->spr[SPR_MQ] = T0 >> T1; | |
d9bce9d9 | 671 | T0 = (int32_t)T0 >> T1; |
76a66253 JM |
672 | RETURN(); |
673 | } | |
674 | ||
675 | void OPPROTO op_POWER_sreq (void) | |
676 | { | |
677 | uint32_t tmp; | |
678 | int32_t msk; | |
679 | ||
680 | T1 &= 0x1FUL; | |
681 | msk = INT32_MIN >> T1; | |
682 | tmp = env->spr[SPR_MQ]; | |
683 | env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
684 | T0 = T0 >> T1; | |
685 | T0 |= tmp & msk; | |
686 | RETURN(); | |
687 | } | |
688 | ||
689 | void OPPROTO op_POWER_srlq (void) | |
690 | { | |
691 | uint32_t tmp; | |
692 | int32_t msk; | |
693 | ||
694 | msk = INT32_MIN >> (T1 & 0x1FUL); | |
695 | if (T1 & 0x20UL) | |
696 | msk = ~msk; | |
697 | T1 &= 0x1FUL; | |
698 | tmp = env->spr[SPR_MQ]; | |
699 | env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
700 | T0 = T0 >> T1; | |
701 | T0 &= msk; | |
702 | T0 |= tmp & ~msk; | |
703 | RETURN(); | |
704 | } | |
705 | ||
706 | void OPPROTO op_POWER_srq (void) | |
707 | { | |
708 | T1 &= 0x1FUL; | |
709 | env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
710 | T0 = T0 >> T1; | |
711 | RETURN(); | |
712 | } | |
713 | ||
714 | /* POWER instructions not implemented in PowerPC 601 */ | |
715 | #if !defined(CONFIG_USER_ONLY) | |
716 | void OPPROTO op_POWER_mfsri (void) | |
717 | { | |
718 | T1 = T0 >> 28; | |
719 | T0 = env->sr[T1]; | |
720 | RETURN(); | |
721 | } | |
722 | ||
723 | void OPPROTO op_POWER_rac (void) | |
724 | { | |
725 | do_POWER_rac(); | |
726 | RETURN(); | |
727 | } | |
728 | ||
729 | void OPPROTO op_POWER_rfsvc (void) | |
730 | { | |
731 | do_POWER_rfsvc(); | |
732 | RETURN(); | |
733 | } | |
734 | #endif | |
735 | ||
736 | /* PowerPC 602 specific instruction */ | |
737 | #if !defined(CONFIG_USER_ONLY) | |
738 | void OPPROTO op_602_mfrom (void) | |
739 | { | |
740 | do_op_602_mfrom(); | |
741 | RETURN(); | |
742 | } | |
743 | #endif | |
744 | ||
745 | /* PowerPC 4xx specific micro-ops */ | |
a42bd6cc | 746 | void OPPROTO op_load_dcr (void) |
76a66253 | 747 | { |
a42bd6cc | 748 | do_load_dcr(); |
76a66253 JM |
749 | RETURN(); |
750 | } | |
751 | ||
a42bd6cc | 752 | void OPPROTO op_store_dcr (void) |
76a66253 | 753 | { |
a42bd6cc | 754 | do_store_dcr(); |
76a66253 JM |
755 | RETURN(); |
756 | } | |
757 | ||
a750fc0b | 758 | #if !defined(CONFIG_USER_ONLY) |
76a66253 JM |
759 | /* Return from critical interrupt : |
760 | * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1 | |
761 | */ | |
a42bd6cc JM |
762 | void OPPROTO op_40x_rfci (void) |
763 | { | |
764 | do_40x_rfci(); | |
765 | RETURN(); | |
766 | } | |
767 | ||
768 | void OPPROTO op_rfci (void) | |
769 | { | |
770 | do_rfci(); | |
771 | RETURN(); | |
772 | } | |
773 | ||
774 | void OPPROTO op_rfdi (void) | |
775 | { | |
776 | do_rfdi(); | |
777 | RETURN(); | |
778 | } | |
779 | ||
780 | void OPPROTO op_rfmci (void) | |
76a66253 | 781 | { |
a42bd6cc | 782 | do_rfmci(); |
76a66253 JM |
783 | RETURN(); |
784 | } | |
785 | ||
a42bd6cc | 786 | void OPPROTO op_wrte (void) |
76a66253 | 787 | { |
0411a972 JM |
788 | /* We don't call do_store_msr here as we won't trigger |
789 | * any special case nor change hflags | |
790 | */ | |
791 | T0 &= 1 << MSR_EE; | |
792 | env->msr &= ~(1 << MSR_EE); | |
793 | env->msr |= T0; | |
76a66253 JM |
794 | RETURN(); |
795 | } | |
796 | ||
a4bb6c3e | 797 | void OPPROTO op_440_tlbre (void) |
5eb7995e | 798 | { |
a4bb6c3e | 799 | do_440_tlbre(PARAM1); |
5eb7995e JM |
800 | RETURN(); |
801 | } | |
802 | ||
a4bb6c3e | 803 | void OPPROTO op_440_tlbsx (void) |
5eb7995e | 804 | { |
daf4f96e | 805 | T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF); |
5eb7995e JM |
806 | RETURN(); |
807 | } | |
808 | ||
daf4f96e | 809 | void OPPROTO op_4xx_tlbsx_check (void) |
5eb7995e | 810 | { |
daf4f96e JM |
811 | int tmp; |
812 | ||
813 | tmp = xer_so; | |
6f2d8978 | 814 | if ((int)T0 != -1) |
daf4f96e JM |
815 | tmp |= 0x02; |
816 | env->crf[0] = tmp; | |
5eb7995e JM |
817 | RETURN(); |
818 | } | |
819 | ||
a4bb6c3e | 820 | void OPPROTO op_440_tlbwe (void) |
5eb7995e | 821 | { |
a4bb6c3e | 822 | do_440_tlbwe(PARAM1); |
5eb7995e JM |
823 | RETURN(); |
824 | } | |
825 | ||
76a66253 JM |
826 | void OPPROTO op_4xx_tlbre_lo (void) |
827 | { | |
828 | do_4xx_tlbre_lo(); | |
829 | RETURN(); | |
830 | } | |
831 | ||
832 | void OPPROTO op_4xx_tlbre_hi (void) | |
833 | { | |
834 | do_4xx_tlbre_hi(); | |
835 | RETURN(); | |
836 | } | |
837 | ||
838 | void OPPROTO op_4xx_tlbsx (void) | |
839 | { | |
daf4f96e | 840 | T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]); |
76a66253 JM |
841 | RETURN(); |
842 | } | |
843 | ||
844 | void OPPROTO op_4xx_tlbwe_lo (void) | |
845 | { | |
846 | do_4xx_tlbwe_lo(); | |
847 | RETURN(); | |
848 | } | |
849 | ||
850 | void OPPROTO op_4xx_tlbwe_hi (void) | |
851 | { | |
852 | do_4xx_tlbwe_hi(); | |
853 | RETURN(); | |
854 | } | |
855 | #endif | |
856 | ||
857 | /* SPR micro-ops */ | |
858 | /* 440 specific */ | |
859 | void OPPROTO op_440_dlmzb (void) | |
860 | { | |
861 | do_440_dlmzb(); | |
862 | RETURN(); | |
863 | } | |
864 | ||
865 | void OPPROTO op_440_dlmzb_update_Rc (void) | |
866 | { | |
867 | if (T0 == 8) | |
868 | T0 = 0x2; | |
869 | else if (T0 < 4) | |
870 | T0 = 0x4; | |
871 | else | |
872 | T0 = 0x8; | |
873 | RETURN(); | |
874 | } | |
875 | ||
876 | #if !defined(CONFIG_USER_ONLY) | |
877 | void OPPROTO op_store_pir (void) | |
3fc6c082 FB |
878 | { |
879 | env->spr[SPR_PIR] = T0 & 0x0000000FUL; | |
880 | RETURN(); | |
881 | } | |
76a66253 JM |
882 | |
883 | void OPPROTO op_load_403_pb (void) | |
884 | { | |
885 | do_load_403_pb(PARAM1); | |
886 | RETURN(); | |
887 | } | |
888 | ||
889 | void OPPROTO op_store_403_pb (void) | |
890 | { | |
891 | do_store_403_pb(PARAM1); | |
892 | RETURN(); | |
893 | } | |
894 | ||
76a66253 JM |
895 | void OPPROTO op_load_40x_pit (void) |
896 | { | |
897 | T0 = load_40x_pit(env); | |
898 | RETURN(); | |
899 | } | |
900 | ||
76a66253 JM |
901 | void OPPROTO op_store_40x_pit (void) |
902 | { | |
903 | store_40x_pit(env, T0); | |
904 | RETURN(); | |
905 | } | |
906 | ||
8ecc7913 JM |
907 | void OPPROTO op_store_40x_dbcr0 (void) |
908 | { | |
909 | store_40x_dbcr0(env, T0); | |
be147d08 | 910 | RETURN(); |
8ecc7913 JM |
911 | } |
912 | ||
c294fc58 JM |
913 | void OPPROTO op_store_40x_sler (void) |
914 | { | |
915 | store_40x_sler(env, T0); | |
916 | RETURN(); | |
917 | } | |
918 | ||
76a66253 JM |
919 | void OPPROTO op_store_booke_tcr (void) |
920 | { | |
921 | store_booke_tcr(env, T0); | |
922 | RETURN(); | |
923 | } | |
924 | ||
76a66253 JM |
925 | void OPPROTO op_store_booke_tsr (void) |
926 | { | |
927 | store_booke_tsr(env, T0); | |
928 | RETURN(); | |
929 | } | |
930 | #endif /* !defined(CONFIG_USER_ONLY) */ | |
0487d6a8 | 931 | |
0487d6a8 JM |
932 | /* SPE extension */ |
933 | void OPPROTO op_splatw_T1_64 (void) | |
934 | { | |
935 | T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL); | |
e864cabd | 936 | RETURN(); |
0487d6a8 JM |
937 | } |
938 | ||
0487d6a8 JM |
939 | void OPPROTO op_extsh_T1_64 (void) |
940 | { | |
941 | T1_64 = (int32_t)((int16_t)T1_64); | |
942 | RETURN(); | |
943 | } | |
944 | ||
945 | void OPPROTO op_sli16_T1_64 (void) | |
946 | { | |
947 | T1_64 = T1_64 << 16; | |
948 | RETURN(); | |
949 | } | |
950 | ||
951 | void OPPROTO op_sli32_T1_64 (void) | |
952 | { | |
953 | T1_64 = T1_64 << 32; | |
954 | RETURN(); | |
955 | } | |
956 | ||
957 | void OPPROTO op_srli32_T1_64 (void) | |
958 | { | |
959 | T1_64 = T1_64 >> 32; | |
960 | RETURN(); | |
961 | } | |
962 | ||
0487d6a8 | 963 |