]> git.proxmox.com Git - qemu.git/blame - target-ppc/op.c
ppc: Convert ctr, lr moves to TCG
[qemu.git] / target-ppc / op.c
CommitLineData
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
6676f424
AJ
29void OPPROTO op_print_mem_EA (void)
30{
31 do_print_mem_EA(T0);
32 RETURN();
33}
34
3fc6c082 35/* PowerPC state maintenance operations */
79aceca5 36/* set_Rc0 */
36081602 37void OPPROTO op_set_Rc0 (void)
79aceca5 38{
966439a6 39 env->crf[0] = T0 | xer_so;
79aceca5
FB
40 RETURN();
41}
42
76a66253 43/* Generate exceptions */
36081602 44void OPPROTO op_raise_exception_err (void)
9a64fbe4 45{
36081602 46 do_raise_exception_err(PARAM1, PARAM2);
9a64fbe4
FB
47}
48
36081602 49void OPPROTO op_debug (void)
ea4e754f
FB
50{
51 do_raise_exception(EXCP_DEBUG);
52}
53
6676f424
AJ
54/* Load/store special registers */
55void OPPROTO op_load_cr (void)
56{
57 do_load_cr();
58 RETURN();
59}
60
61void OPPROTO op_store_cr (void)
62{
63 do_store_cr(PARAM1);
64 RETURN();
65}
66
36081602 67void OPPROTO op_load_xer_cr (void)
79aceca5
FB
68{
69 T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
70 RETURN();
71}
72
36081602 73void OPPROTO op_clear_xer_ov (void)
79aceca5
FB
74{
75 xer_so = 0;
76 xer_ov = 0;
e864cabd
JM
77 RETURN();
78}
79
36081602 80void OPPROTO op_clear_xer_ca (void)
e864cabd 81{
79aceca5
FB
82 xer_ca = 0;
83 RETURN();
84}
85
36081602 86void OPPROTO op_load_xer_bc (void)
79aceca5 87{
9a64fbe4 88 T1 = xer_bc;
79aceca5
FB
89 RETURN();
90}
91
76a66253
JM
92void OPPROTO op_store_xer_bc (void)
93{
94 xer_bc = T0;
95 RETURN();
96}
97
36081602 98void OPPROTO op_load_xer (void)
79aceca5 99{
0411a972 100 T0 = hreg_load_xer(env);
79aceca5
FB
101 RETURN();
102}
103
36081602 104void OPPROTO op_store_xer (void)
79aceca5 105{
0411a972 106 hreg_store_xer(env, T0);
76a66253
JM
107 RETURN();
108}
109
c80f84e3
JM
110#if defined(TARGET_PPC64)
111void OPPROTO op_store_pri (void)
112{
113 do_store_pri(PARAM1);
114 RETURN();
115}
116#endif
117
76a66253
JM
118#if !defined(CONFIG_USER_ONLY)
119/* Segment registers load and store */
36081602 120void OPPROTO op_load_sr (void)
76a66253 121{
36081602 122 T0 = env->sr[T1];
76a66253
JM
123 RETURN();
124}
125
36081602 126void OPPROTO op_store_sr (void)
76a66253
JM
127{
128 do_store_sr(env, T1, T0);
129 RETURN();
130}
131
12de9a39
JM
132#if defined(TARGET_PPC64)
133void OPPROTO op_load_slb (void)
134{
135 T0 = ppc_load_slb(env, T1);
136 RETURN();
137}
138
139void OPPROTO op_store_slb (void)
140{
141 ppc_store_slb(env, T1, T0);
142 RETURN();
143}
144#endif /* defined(TARGET_PPC64) */
145
36081602 146void OPPROTO op_load_sdr1 (void)
76a66253 147{
36081602 148 T0 = env->sdr1;
76a66253
JM
149 RETURN();
150}
151
36081602 152void OPPROTO op_store_sdr1 (void)
76a66253
JM
153{
154 do_store_sdr1(env, T0);
79aceca5
FB
155 RETURN();
156}
157
d9bce9d9
JM
158#if defined (TARGET_PPC64)
159void OPPROTO op_load_asr (void)
160{
161 T0 = env->asr;
162 RETURN();
163}
164
165void OPPROTO op_store_asr (void)
166{
167 ppc_store_asr(env, T0);
168 RETURN();
169}
170#endif
171
6676f424
AJ
172void OPPROTO op_load_msr (void)
173{
174 T0 = env->msr;
175 RETURN();
176}
177
178void OPPROTO op_store_msr (void)
179{
180 do_store_msr();
181 RETURN();
182}
183
184#if defined (TARGET_PPC64)
185void OPPROTO op_store_msr_32 (void)
186{
187 T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
188 do_store_msr();
189 RETURN();
190}
191#endif
192
0411a972 193void OPPROTO op_update_riee (void)
d9bce9d9 194{
0411a972
JM
195 /* We don't call do_store_msr here as we won't trigger
196 * any special case nor change hflags
197 */
198 T0 &= (1 << MSR_RI) | (1 << MSR_EE);
199 env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
200 env->msr |= T0;
d9bce9d9
JM
201 RETURN();
202}
203#endif
9a64fbe4
FB
204
205/* SPR */
a496775f
JM
206void OPPROTO op_load_spr (void)
207{
208 T0 = env->spr[PARAM1];
209 RETURN();
210}
211
212void OPPROTO op_store_spr (void)
213{
214 env->spr[PARAM1] = T0;
215 RETURN();
216}
217
218void OPPROTO op_load_dump_spr (void)
219{
220 T0 = ppc_load_dump_spr(PARAM1);
221 RETURN();
222}
223
224void OPPROTO op_store_dump_spr (void)
9a64fbe4 225{
a496775f 226 ppc_store_dump_spr(PARAM1, T0);
9a64fbe4
FB
227 RETURN();
228}
229
a496775f 230void OPPROTO op_mask_spr (void)
9a64fbe4 231{
a496775f 232 env->spr[PARAM1] &= ~T0;
79aceca5
FB
233 RETURN();
234}
235
36081602 236void OPPROTO op_load_tbl (void)
9a64fbe4 237{
36081602 238 T0 = cpu_ppc_load_tbl(env);
9a64fbe4
FB
239 RETURN();
240}
241
36081602 242void OPPROTO op_load_tbu (void)
9a64fbe4 243{
36081602 244 T0 = cpu_ppc_load_tbu(env);
9a64fbe4
FB
245 RETURN();
246}
247
a062e36c
JM
248void OPPROTO op_load_atbl (void)
249{
250 T0 = cpu_ppc_load_atbl(env);
251 RETURN();
252}
253
254void OPPROTO op_load_atbu (void)
255{
256 T0 = cpu_ppc_load_atbu(env);
257 RETURN();
258}
259
76a66253 260#if !defined(CONFIG_USER_ONLY)
36081602 261void OPPROTO op_store_tbl (void)
9a64fbe4 262{
36081602 263 cpu_ppc_store_tbl(env, T0);
79aceca5
FB
264 RETURN();
265}
266
36081602 267void OPPROTO op_store_tbu (void)
9a64fbe4 268{
36081602 269 cpu_ppc_store_tbu(env, T0);
9a64fbe4
FB
270 RETURN();
271}
272
a062e36c
JM
273void OPPROTO op_store_atbl (void)
274{
275 cpu_ppc_store_atbl(env, T0);
276 RETURN();
277}
278
279void OPPROTO op_store_atbu (void)
280{
281 cpu_ppc_store_atbu(env, T0);
282 RETURN();
283}
284
36081602 285void OPPROTO op_load_decr (void)
9a64fbe4 286{
36081602 287 T0 = cpu_ppc_load_decr(env);
76a66253
JM
288 RETURN();
289}
9fddaa0c 290
36081602 291void OPPROTO op_store_decr (void)
9fddaa0c 292{
36081602 293 cpu_ppc_store_decr(env, T0);
9a64fbe4
FB
294 RETURN();
295}
296
36081602 297void OPPROTO op_load_ibat (void)
9a64fbe4 298{
36081602 299 T0 = env->IBAT[PARAM1][PARAM2];
76a66253 300 RETURN();
9a64fbe4
FB
301}
302
76a66253 303void OPPROTO op_store_ibatu (void)
9a64fbe4 304{
3fc6c082
FB
305 do_store_ibatu(env, PARAM1, T0);
306 RETURN();
307}
308
76a66253 309void OPPROTO op_store_ibatl (void)
3fc6c082
FB
310{
311#if 1
312 env->IBAT[1][PARAM1] = T0;
313#else
314 do_store_ibatl(env, PARAM1, T0);
315#endif
316 RETURN();
9a64fbe4
FB
317}
318
36081602 319void OPPROTO op_load_dbat (void)
9a64fbe4 320{
36081602 321 T0 = env->DBAT[PARAM1][PARAM2];
76a66253 322 RETURN();
9a64fbe4
FB
323}
324
76a66253 325void OPPROTO op_store_dbatu (void)
3fc6c082
FB
326{
327 do_store_dbatu(env, PARAM1, T0);
328 RETURN();
329}
330
76a66253 331void OPPROTO op_store_dbatl (void)
9a64fbe4 332{
3fc6c082
FB
333#if 1
334 env->DBAT[1][PARAM1] = T0;
335#else
336 do_store_dbatl(env, PARAM1, T0);
337#endif
338 RETURN();
9a64fbe4 339}
76a66253 340#endif /* !defined(CONFIG_USER_ONLY) */
9a64fbe4 341
fb0eaffc 342/* FPSCR */
7c58044c
JM
343#ifdef CONFIG_SOFTFLOAT
344void OPPROTO op_reset_fpstatus (void)
fb0eaffc 345{
7c58044c 346 env->fp_status.float_exception_flags = 0;
fb0eaffc
FB
347 RETURN();
348}
7c58044c 349#endif
fb0eaffc 350
7c58044c 351void OPPROTO op_compute_fprf (void)
fb0eaffc 352{
7c58044c
JM
353 do_compute_fprf(PARAM1);
354 RETURN();
355}
356
357#ifdef CONFIG_SOFTFLOAT
358void OPPROTO op_float_check_status (void)
359{
360 do_float_check_status();
361 RETURN();
362}
363#else
364void OPPROTO op_float_check_status (void)
365{
366 if (env->exception_index == POWERPC_EXCP_PROGRAM &&
367 (env->error_code & POWERPC_EXCP_FP)) {
368 /* Differred floating-point exception after target FPR update */
369 if (msr_fe0 != 0 || msr_fe1 != 0)
370 do_raise_exception_err(env->exception_index, env->error_code);
371 }
fb0eaffc
FB
372 RETURN();
373}
7c58044c
JM
374#endif
375
7c58044c
JM
376void OPPROTO op_load_fpscr_FT0 (void)
377{
378 /* The 32 MSB of the target fpr are undefined.
379 * They'll be zero...
380 */
0ca9d380
AJ
381 CPU_DoubleU u;
382
383 u.l.upper = 0;
384 u.l.lower = env->fpscr;
7c58044c
JM
385 FT0 = u.d;
386 RETURN();
387}
388
7c58044c 389void OPPROTO op_load_fpscr_T0 (void)
fb0eaffc 390{
7c58044c
JM
391 T0 = (env->fpscr >> PARAM1) & 0xF;
392 RETURN();
393}
394
395void OPPROTO op_load_fpcc (void)
396{
397 T0 = fpscr_fpcc;
398 RETURN();
399}
400
401void OPPROTO op_fpscr_resetbit (void)
402{
403 env->fpscr &= PARAM1;
404 RETURN();
405}
406
407void OPPROTO op_fpscr_setbit (void)
408{
409 do_fpscr_setbit(PARAM1);
410 RETURN();
411}
412
413void OPPROTO op_store_fpscr (void)
414{
415 do_store_fpscr(PARAM1);
fb0eaffc
FB
416 RETURN();
417}
418
79aceca5 419/* Branch */
36081602 420void OPPROTO op_setlr (void)
e98a6e40 421{
36081602 422 env->lr = (uint32_t)PARAM1;
76a66253 423 RETURN();
e98a6e40
FB
424}
425
d9bce9d9
JM
426#if defined (TARGET_PPC64)
427void OPPROTO op_setlr_64 (void)
428{
36081602 429 env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
d9bce9d9
JM
430 RETURN();
431}
432#endif
433
36081602 434void OPPROTO op_jz_T0 (void)
e98a6e40 435{
c53be334
FB
436 if (!T0)
437 GOTO_LABEL_PARAM(1);
e98a6e40
FB
438 RETURN();
439}
440
d9bce9d9 441void OPPROTO op_btest_T1 (void)
e98a6e40
FB
442{
443 if (T0) {
36081602 444 env->nip = (uint32_t)(T1 & ~3);
e98a6e40 445 } else {
36081602 446 env->nip = (uint32_t)PARAM1;
e98a6e40
FB
447 }
448 RETURN();
449}
450
d9bce9d9
JM
451#if defined (TARGET_PPC64)
452void OPPROTO op_btest_T1_64 (void)
453{
454 if (T0) {
36081602 455 env->nip = (uint64_t)(T1 & ~3);
d9bce9d9 456 } else {
36081602 457 env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
d9bce9d9
JM
458 }
459 RETURN();
460}
461#endif
462
36081602 463void OPPROTO op_movl_T1_ctr (void)
e98a6e40 464{
36081602 465 T1 = env->ctr;
76a66253 466 RETURN();
e98a6e40
FB
467}
468
36081602 469void OPPROTO op_movl_T1_lr (void)
e98a6e40 470{
36081602 471 T1 = env->lr;
76a66253 472 RETURN();
e98a6e40
FB
473}
474
475/* tests with result in T0 */
d9bce9d9
JM
476void OPPROTO op_test_ctr (void)
477{
36081602 478 T0 = (uint32_t)env->ctr;
d9bce9d9
JM
479 RETURN();
480}
e98a6e40 481
d9bce9d9
JM
482#if defined(TARGET_PPC64)
483void OPPROTO op_test_ctr_64 (void)
e98a6e40 484{
36081602 485 T0 = (uint64_t)env->ctr;
d9bce9d9
JM
486 RETURN();
487}
488#endif
489
490void OPPROTO op_test_ctr_true (void)
491{
36081602 492 T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
76a66253 493 RETURN();
e98a6e40
FB
494}
495
d9bce9d9
JM
496#if defined(TARGET_PPC64)
497void OPPROTO op_test_ctr_true_64 (void)
e98a6e40 498{
36081602 499 T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
76a66253 500 RETURN();
e98a6e40 501}
d9bce9d9 502#endif
e98a6e40 503
d9bce9d9 504void OPPROTO op_test_ctr_false (void)
e98a6e40 505{
36081602 506 T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
76a66253 507 RETURN();
e98a6e40
FB
508}
509
d9bce9d9
JM
510#if defined(TARGET_PPC64)
511void OPPROTO op_test_ctr_false_64 (void)
e98a6e40 512{
36081602 513 T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
76a66253 514 RETURN();
e98a6e40 515}
d9bce9d9
JM
516#endif
517
518void OPPROTO op_test_ctrz (void)
519{
36081602 520 T0 = ((uint32_t)env->ctr == 0);
d9bce9d9
JM
521 RETURN();
522}
523
524#if defined(TARGET_PPC64)
525void OPPROTO op_test_ctrz_64 (void)
526{
36081602 527 T0 = ((uint64_t)env->ctr == 0);
d9bce9d9
JM
528 RETURN();
529}
530#endif
531
532void OPPROTO op_test_ctrz_true (void)
533{
36081602 534 T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
d9bce9d9
JM
535 RETURN();
536}
537
538#if defined(TARGET_PPC64)
539void OPPROTO op_test_ctrz_true_64 (void)
540{
36081602 541 T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
d9bce9d9
JM
542 RETURN();
543}
544#endif
e98a6e40 545
d9bce9d9 546void OPPROTO op_test_ctrz_false (void)
e98a6e40 547{
36081602 548 T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
76a66253 549 RETURN();
e98a6e40
FB
550}
551
d9bce9d9
JM
552#if defined(TARGET_PPC64)
553void OPPROTO op_test_ctrz_false_64 (void)
e98a6e40 554{
36081602 555 T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
76a66253 556 RETURN();
e98a6e40 557}
d9bce9d9 558#endif
e98a6e40 559
36081602 560void OPPROTO op_test_true (void)
e98a6e40 561{
36081602 562 T0 = (T0 & PARAM1);
76a66253 563 RETURN();
e98a6e40
FB
564}
565
36081602 566void OPPROTO op_test_false (void)
e98a6e40 567{
36081602 568 T0 = ((T0 & PARAM1) == 0);
76a66253 569 RETURN();
e98a6e40 570}
79aceca5
FB
571
572/* CTR maintenance */
36081602 573void OPPROTO op_dec_ctr (void)
79aceca5 574{
36081602 575 env->ctr--;
79aceca5
FB
576 RETURN();
577}
578
579/*** Integer arithmetic ***/
580/* add */
d9bce9d9 581void OPPROTO op_check_addo (void)
79aceca5 582{
c3e10c7b
JM
583 xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
584 ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
585 xer_so |= xer_ov;
e864cabd 586 RETURN();
79aceca5
FB
587}
588
d9bce9d9
JM
589#if defined(TARGET_PPC64)
590void OPPROTO op_check_addo_64 (void)
79aceca5 591{
c3e10c7b
JM
592 xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
593 ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
594 xer_so |= xer_ov;
e864cabd 595 RETURN();
d9bce9d9
JM
596}
597#endif
598
599/* add carrying */
600void OPPROTO op_check_addc (void)
601{
602 if (likely((uint32_t)T0 >= (uint32_t)T2)) {
79aceca5 603 xer_ca = 0;
d9bce9d9
JM
604 } else {
605 xer_ca = 1;
79aceca5
FB
606 }
607 RETURN();
608}
609
d9bce9d9
JM
610#if defined(TARGET_PPC64)
611void OPPROTO op_check_addc_64 (void)
79aceca5 612{
d9bce9d9
JM
613 if (likely((uint64_t)T0 >= (uint64_t)T2)) {
614 xer_ca = 0;
615 } else {
616 xer_ca = 1;
617 }
79aceca5
FB
618 RETURN();
619}
d9bce9d9 620#endif
79aceca5
FB
621
622/* add extended */
76a66253 623void OPPROTO op_adde (void)
79aceca5 624{
fdabc366 625 do_adde();
76a66253 626 RETURN();
79aceca5
FB
627}
628
d9bce9d9
JM
629#if defined(TARGET_PPC64)
630void OPPROTO op_adde_64 (void)
79aceca5 631{
d9bce9d9 632 do_adde_64();
79aceca5
FB
633 RETURN();
634}
d9bce9d9 635#endif
79aceca5 636
d9bce9d9
JM
637/* add to minus one extended */
638void OPPROTO op_add_me (void)
79aceca5 639{
d9bce9d9
JM
640 T0 += xer_ca + (-1);
641 if (likely((uint32_t)T1 != 0))
79aceca5 642 xer_ca = 1;
c3e10c7b
JM
643 else
644 xer_ca = 0;
79aceca5
FB
645 RETURN();
646}
647
d9bce9d9
JM
648#if defined(TARGET_PPC64)
649void OPPROTO op_add_me_64 (void)
79aceca5 650{
79aceca5 651 T0 += xer_ca + (-1);
d9bce9d9 652 if (likely((uint64_t)T1 != 0))
79aceca5 653 xer_ca = 1;
c3e10c7b
JM
654 else
655 xer_ca = 0;
79aceca5
FB
656 RETURN();
657}
d9bce9d9 658#endif
79aceca5 659
76a66253 660void OPPROTO op_addmeo (void)
79aceca5 661{
fdabc366 662 do_addmeo();
79aceca5
FB
663 RETURN();
664}
665
d9bce9d9
JM
666void OPPROTO op_addmeo_64 (void)
667{
668 do_addmeo();
669 RETURN();
670}
671
79aceca5 672/* add to zero extended */
d9bce9d9 673void OPPROTO op_add_ze (void)
79aceca5 674{
79aceca5 675 T0 += xer_ca;
79aceca5
FB
676 RETURN();
677}
678
d9bce9d9
JM
679/* divide word */
680void OPPROTO op_divw (void)
79aceca5 681{
6f2d8978 682 if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
d9bce9d9 683 (int32_t)T1 == 0)) {
6f2d8978 684 T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
d9bce9d9
JM
685 } else {
686 T0 = (int32_t)T0 / (int32_t)T1;
687 }
79aceca5
FB
688 RETURN();
689}
690
d9bce9d9
JM
691#if defined(TARGET_PPC64)
692void OPPROTO op_divd (void)
79aceca5 693{
6f2d8978 694 if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
d9bce9d9 695 (int64_t)T1 == 0)) {
6f2d8978 696 T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
79aceca5 697 } else {
d9bce9d9 698 T0 = (int64_t)T0 / (int64_t)T1;
79aceca5
FB
699 }
700 RETURN();
701}
d9bce9d9 702#endif
79aceca5 703
76a66253 704void OPPROTO op_divwo (void)
79aceca5 705{
fdabc366 706 do_divwo();
79aceca5
FB
707 RETURN();
708}
709
d9bce9d9
JM
710#if defined(TARGET_PPC64)
711void OPPROTO op_divdo (void)
712{
713 do_divdo();
714 RETURN();
715}
716#endif
717
79aceca5 718/* divide word unsigned */
d9bce9d9
JM
719void OPPROTO op_divwu (void)
720{
721 if (unlikely(T1 == 0)) {
722 T0 = 0;
723 } else {
724 T0 = (uint32_t)T0 / (uint32_t)T1;
725 }
726 RETURN();
727}
728
729#if defined(TARGET_PPC64)
730void OPPROTO op_divdu (void)
79aceca5 731{
d9bce9d9 732 if (unlikely(T1 == 0)) {
79aceca5
FB
733 T0 = 0;
734 } else {
735 T0 /= T1;
736 }
737 RETURN();
738}
d9bce9d9 739#endif
79aceca5 740
76a66253 741void OPPROTO op_divwuo (void)
79aceca5 742{
fdabc366 743 do_divwuo();
79aceca5
FB
744 RETURN();
745}
746
d9bce9d9
JM
747#if defined(TARGET_PPC64)
748void OPPROTO op_divduo (void)
749{
750 do_divduo();
751 RETURN();
752}
753#endif
754
79aceca5 755/* multiply high word */
d9bce9d9 756void OPPROTO op_mulhw (void)
79aceca5 757{
d9bce9d9 758 T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
79aceca5
FB
759 RETURN();
760}
761
d9bce9d9
JM
762#if defined(TARGET_PPC64)
763void OPPROTO op_mulhd (void)
764{
765 uint64_t tl, th;
766
9d901a20 767 muls64(&tl, &th, T0, T1);
d9bce9d9
JM
768 T0 = th;
769 RETURN();
770}
771#endif
772
79aceca5 773/* multiply high word unsigned */
d9bce9d9 774void OPPROTO op_mulhwu (void)
79aceca5 775{
d9bce9d9 776 T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
79aceca5
FB
777 RETURN();
778}
779
d9bce9d9
JM
780#if defined(TARGET_PPC64)
781void OPPROTO op_mulhdu (void)
782{
783 uint64_t tl, th;
784
9d901a20 785 mulu64(&tl, &th, T0, T1);
d9bce9d9
JM
786 T0 = th;
787 RETURN();
788}
789#endif
790
79aceca5 791/* multiply low immediate */
36081602 792void OPPROTO op_mulli (void)
79aceca5 793{
d9bce9d9 794 T0 = ((int32_t)T0 * (int32_t)PARAM1);
79aceca5
FB
795 RETURN();
796}
797
798/* multiply low word */
36081602 799void OPPROTO op_mullw (void)
d9bce9d9
JM
800{
801 T0 = (int32_t)(T0 * T1);
802 RETURN();
803}
804
805#if defined(TARGET_PPC64)
806void OPPROTO op_mulld (void)
79aceca5
FB
807{
808 T0 *= T1;
809 RETURN();
810}
d9bce9d9 811#endif
79aceca5 812
76a66253 813void OPPROTO op_mullwo (void)
79aceca5 814{
fdabc366 815 do_mullwo();
79aceca5
FB
816 RETURN();
817}
818
d9bce9d9
JM
819#if defined(TARGET_PPC64)
820void OPPROTO op_mulldo (void)
821{
822 do_mulldo();
823 RETURN();
824}
825#endif
826
79aceca5 827/* negate */
d9bce9d9 828void OPPROTO op_neg (void)
79aceca5 829{
d9bce9d9
JM
830 if (likely(T0 != INT32_MIN)) {
831 T0 = -(int32_t)T0;
79aceca5
FB
832 }
833 RETURN();
834}
835
d9bce9d9
JM
836#if defined(TARGET_PPC64)
837void OPPROTO op_neg_64 (void)
838{
839 if (likely(T0 != INT64_MIN)) {
840 T0 = -(int64_t)T0;
841 }
842 RETURN();
843}
844#endif
845
76a66253 846void OPPROTO op_nego (void)
79aceca5 847{
fdabc366 848 do_nego();
79aceca5
FB
849 RETURN();
850}
851
d9bce9d9
JM
852#if defined(TARGET_PPC64)
853void OPPROTO op_nego_64 (void)
854{
855 do_nego_64();
856 RETURN();
857}
858#endif
859
0cfec834 860/* subtract from carrying */
d9bce9d9 861void OPPROTO op_check_subfc (void)
79aceca5 862{
d9bce9d9 863 if (likely((uint32_t)T0 > (uint32_t)T1)) {
79aceca5 864 xer_ca = 0;
d9bce9d9
JM
865 } else {
866 xer_ca = 1;
79aceca5
FB
867 }
868 RETURN();
869}
870
d9bce9d9
JM
871#if defined(TARGET_PPC64)
872void OPPROTO op_check_subfc_64 (void)
79aceca5 873{
d9bce9d9
JM
874 if (likely((uint64_t)T0 > (uint64_t)T1)) {
875 xer_ca = 0;
876 } else {
877 xer_ca = 1;
878 }
79aceca5
FB
879 RETURN();
880}
d9bce9d9 881#endif
79aceca5 882
0cfec834 883/* subtract from extended */
76a66253 884void OPPROTO op_subfe (void)
79aceca5 885{
fdabc366 886 do_subfe();
79aceca5
FB
887 RETURN();
888}
889
d9bce9d9
JM
890#if defined(TARGET_PPC64)
891void OPPROTO op_subfe_64 (void)
79aceca5 892{
d9bce9d9 893 do_subfe_64();
79aceca5
FB
894 RETURN();
895}
d9bce9d9 896#endif
79aceca5 897
0cfec834 898/* subtract from immediate carrying */
d9bce9d9 899void OPPROTO op_subfic (void)
79aceca5 900{
b6e27ab8 901 T0 = (int32_t)PARAM1 + ~T0 + 1;
d9bce9d9 902 if ((uint32_t)T0 <= (uint32_t)PARAM1) {
79aceca5
FB
903 xer_ca = 1;
904 } else {
905 xer_ca = 0;
906 }
907 RETURN();
908}
909
d9bce9d9
JM
910#if defined(TARGET_PPC64)
911void OPPROTO op_subfic_64 (void)
912{
2f401176 913 T0 = (int64_t)PARAM1 + ~T0 + 1;
d9bce9d9
JM
914 if ((uint64_t)T0 <= (uint64_t)PARAM1) {
915 xer_ca = 1;
916 } else {
917 xer_ca = 0;
918 }
919 RETURN();
920}
921#endif
922
0cfec834 923/* subtract from minus one extended */
d9bce9d9 924void OPPROTO op_subfme (void)
79aceca5
FB
925{
926 T0 = ~T0 + xer_ca - 1;
c3e10c7b 927 if (likely((uint32_t)T0 != UINT32_MAX))
d9bce9d9 928 xer_ca = 1;
c3e10c7b
JM
929 else
930 xer_ca = 0;
d9bce9d9
JM
931 RETURN();
932}
79aceca5 933
d9bce9d9
JM
934#if defined(TARGET_PPC64)
935void OPPROTO op_subfme_64 (void)
936{
937 T0 = ~T0 + xer_ca - 1;
c3e10c7b 938 if (likely((uint64_t)T0 != UINT64_MAX))
79aceca5 939 xer_ca = 1;
c3e10c7b
JM
940 else
941 xer_ca = 0;
79aceca5
FB
942 RETURN();
943}
d9bce9d9 944#endif
79aceca5 945
76a66253 946void OPPROTO op_subfmeo (void)
79aceca5 947{
fdabc366 948 do_subfmeo();
79aceca5
FB
949 RETURN();
950}
951
d9bce9d9
JM
952#if defined(TARGET_PPC64)
953void OPPROTO op_subfmeo_64 (void)
954{
955 do_subfmeo_64();
956 RETURN();
957}
958#endif
959
0cfec834 960/* subtract from zero extended */
d9bce9d9 961void OPPROTO op_subfze (void)
79aceca5
FB
962{
963 T1 = ~T0;
964 T0 = T1 + xer_ca;
d9bce9d9 965 if ((uint32_t)T0 < (uint32_t)T1) {
79aceca5
FB
966 xer_ca = 1;
967 } else {
968 xer_ca = 0;
969 }
970 RETURN();
971}
972
d9bce9d9
JM
973#if defined(TARGET_PPC64)
974void OPPROTO op_subfze_64 (void)
975{
976 T1 = ~T0;
977 T0 = T1 + xer_ca;
978 if ((uint64_t)T0 < (uint64_t)T1) {
979 xer_ca = 1;
980 } else {
981 xer_ca = 0;
982 }
983 RETURN();
984}
985#endif
986
76a66253 987void OPPROTO op_subfzeo (void)
79aceca5 988{
fdabc366 989 do_subfzeo();
79aceca5
FB
990 RETURN();
991}
992
d9bce9d9
JM
993#if defined(TARGET_PPC64)
994void OPPROTO op_subfzeo_64 (void)
995{
996 do_subfzeo_64();
997 RETURN();
998}
999#endif
1000
79aceca5
FB
1001/*** Integer comparison ***/
1002/* compare */
d9bce9d9
JM
1003void OPPROTO op_cmp (void)
1004{
1005 if ((int32_t)T0 < (int32_t)T1) {
1006 T0 = 0x08;
1007 } else if ((int32_t)T0 > (int32_t)T1) {
1008 T0 = 0x04;
1009 } else {
1010 T0 = 0x02;
1011 }
966439a6 1012 T0 |= xer_so;
d9bce9d9
JM
1013 RETURN();
1014}
1015
1016#if defined(TARGET_PPC64)
1017void OPPROTO op_cmp_64 (void)
79aceca5 1018{
d9bce9d9 1019 if ((int64_t)T0 < (int64_t)T1) {
79aceca5 1020 T0 = 0x08;
d9bce9d9 1021 } else if ((int64_t)T0 > (int64_t)T1) {
79aceca5
FB
1022 T0 = 0x04;
1023 } else {
1024 T0 = 0x02;
1025 }
966439a6 1026 T0 |= xer_so;
79aceca5
FB
1027 RETURN();
1028}
d9bce9d9 1029#endif
79aceca5
FB
1030
1031/* compare immediate */
d9bce9d9 1032void OPPROTO op_cmpi (void)
79aceca5 1033{
d9bce9d9 1034 if ((int32_t)T0 < (int32_t)PARAM1) {
79aceca5 1035 T0 = 0x08;
d9bce9d9 1036 } else if ((int32_t)T0 > (int32_t)PARAM1) {
79aceca5
FB
1037 T0 = 0x04;
1038 } else {
1039 T0 = 0x02;
1040 }
966439a6 1041 T0 |= xer_so;
79aceca5
FB
1042 RETURN();
1043}
1044
d9bce9d9
JM
1045#if defined(TARGET_PPC64)
1046void OPPROTO op_cmpi_64 (void)
1047{
1048 if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1049 T0 = 0x08;
1050 } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1051 T0 = 0x04;
1052 } else {
1053 T0 = 0x02;
1054 }
966439a6 1055 T0 |= xer_so;
d9bce9d9
JM
1056 RETURN();
1057}
1058#endif
1059
79aceca5 1060/* compare logical */
d9bce9d9 1061void OPPROTO op_cmpl (void)
79aceca5 1062{
d9bce9d9 1063 if ((uint32_t)T0 < (uint32_t)T1) {
79aceca5 1064 T0 = 0x08;
d9bce9d9 1065 } else if ((uint32_t)T0 > (uint32_t)T1) {
79aceca5
FB
1066 T0 = 0x04;
1067 } else {
1068 T0 = 0x02;
1069 }
966439a6 1070 T0 |= xer_so;
79aceca5
FB
1071 RETURN();
1072}
1073
d9bce9d9
JM
1074#if defined(TARGET_PPC64)
1075void OPPROTO op_cmpl_64 (void)
1076{
1077 if ((uint64_t)T0 < (uint64_t)T1) {
1078 T0 = 0x08;
1079 } else if ((uint64_t)T0 > (uint64_t)T1) {
1080 T0 = 0x04;
1081 } else {
1082 T0 = 0x02;
1083 }
966439a6 1084 T0 |= xer_so;
d9bce9d9
JM
1085 RETURN();
1086}
1087#endif
1088
79aceca5 1089/* compare logical immediate */
d9bce9d9
JM
1090void OPPROTO op_cmpli (void)
1091{
1092 if ((uint32_t)T0 < (uint32_t)PARAM1) {
1093 T0 = 0x08;
1094 } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1095 T0 = 0x04;
1096 } else {
1097 T0 = 0x02;
1098 }
966439a6 1099 T0 |= xer_so;
d9bce9d9
JM
1100 RETURN();
1101}
1102
1103#if defined(TARGET_PPC64)
1104void OPPROTO op_cmpli_64 (void)
79aceca5 1105{
d9bce9d9 1106 if ((uint64_t)T0 < (uint64_t)PARAM1) {
79aceca5 1107 T0 = 0x08;
d9bce9d9 1108 } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
79aceca5
FB
1109 T0 = 0x04;
1110 } else {
1111 T0 = 0x02;
1112 }
966439a6 1113 T0 |= xer_so;
79aceca5
FB
1114 RETURN();
1115}
d9bce9d9
JM
1116#endif
1117
1118void OPPROTO op_isel (void)
1119{
1120 if (T0)
1121 T0 = T1;
1122 else
1123 T0 = T2;
1124 RETURN();
1125}
1126
6676f424
AJ
1127void OPPROTO op_popcntb (void)
1128{
1129 do_popcntb();
1130 RETURN();
1131}
1132
1133#if defined(TARGET_PPC64)
1134void OPPROTO op_popcntb_64 (void)
1135{
1136 do_popcntb_64();
1137 RETURN();
1138}
1139#endif
1140
79aceca5
FB
1141/*** Integer logical ***/
1142/* and */
36081602 1143void OPPROTO op_and (void)
79aceca5
FB
1144{
1145 T0 &= T1;
1146 RETURN();
1147}
1148
1149/* andc */
36081602 1150void OPPROTO op_andc (void)
79aceca5
FB
1151{
1152 T0 &= ~T1;
1153 RETURN();
1154}
1155
1156/* andi. */
76a66253 1157void OPPROTO op_andi_T0 (void)
79aceca5 1158{
2f401176 1159 T0 &= (uint32_t)PARAM1;
79aceca5
FB
1160 RETURN();
1161}
1162
76a66253
JM
1163void OPPROTO op_andi_T1 (void)
1164{
2f401176 1165 T1 &= (uint32_t)PARAM1;
76a66253
JM
1166 RETURN();
1167}
1168
40d0591e
JM
1169#if defined(TARGET_PPC64)
1170void OPPROTO op_andi_T0_64 (void)
1171{
2f401176 1172 T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
40d0591e
JM
1173 RETURN();
1174}
1175
1176void OPPROTO op_andi_T1_64 (void)
1177{
2f401176 1178 T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
40d0591e
JM
1179 RETURN();
1180}
1181#endif
1182
79aceca5 1183/* count leading zero */
76a66253 1184void OPPROTO op_cntlzw (void)
79aceca5 1185{
603fccce 1186 do_cntlzw();
79aceca5
FB
1187 RETURN();
1188}
1189
d9bce9d9
JM
1190#if defined(TARGET_PPC64)
1191void OPPROTO op_cntlzd (void)
1192{
603fccce 1193 do_cntlzd();
d9bce9d9
JM
1194 RETURN();
1195}
1196#endif
1197
79aceca5 1198/* eqv */
36081602 1199void OPPROTO op_eqv (void)
79aceca5
FB
1200{
1201 T0 = ~(T0 ^ T1);
1202 RETURN();
1203}
1204
1205/* extend sign byte */
d9bce9d9 1206void OPPROTO op_extsb (void)
79aceca5 1207{
d9bce9d9
JM
1208#if defined (TARGET_PPC64)
1209 T0 = (int64_t)((int8_t)T0);
1210#else
1211 T0 = (int32_t)((int8_t)T0);
1212#endif
79aceca5
FB
1213 RETURN();
1214}
1215
1216/* extend sign half word */
d9bce9d9 1217void OPPROTO op_extsh (void)
79aceca5 1218{
d9bce9d9
JM
1219#if defined (TARGET_PPC64)
1220 T0 = (int64_t)((int16_t)T0);
1221#else
1222 T0 = (int32_t)((int16_t)T0);
1223#endif
79aceca5
FB
1224 RETURN();
1225}
1226
d9bce9d9
JM
1227#if defined (TARGET_PPC64)
1228void OPPROTO op_extsw (void)
1229{
1230 T0 = (int64_t)((int32_t)T0);
1231 RETURN();
1232}
1233#endif
1234
79aceca5 1235/* nand */
36081602 1236void OPPROTO op_nand (void)
79aceca5
FB
1237{
1238 T0 = ~(T0 & T1);
1239 RETURN();
1240}
1241
1242/* nor */
36081602 1243void OPPROTO op_nor (void)
79aceca5
FB
1244{
1245 T0 = ~(T0 | T1);
1246 RETURN();
1247}
1248
1249/* or */
36081602 1250void OPPROTO op_or (void)
79aceca5
FB
1251{
1252 T0 |= T1;
1253 RETURN();
1254}
1255
1256/* orc */
36081602 1257void OPPROTO op_orc (void)
79aceca5
FB
1258{
1259 T0 |= ~T1;
1260 RETURN();
1261}
1262
1263/* ori */
36081602 1264void OPPROTO op_ori (void)
79aceca5 1265{
2f401176 1266 T0 |= (uint32_t)PARAM1;
79aceca5
FB
1267 RETURN();
1268}
1269
1270/* xor */
36081602 1271void OPPROTO op_xor (void)
79aceca5
FB
1272{
1273 T0 ^= T1;
1274 RETURN();
1275}
1276
1277/* xori */
36081602 1278void OPPROTO op_xori (void)
79aceca5 1279{
2f401176 1280 T0 ^= (uint32_t)PARAM1;
79aceca5
FB
1281 RETURN();
1282}
1283
1284/*** Integer rotate ***/
76a66253 1285void OPPROTO op_rotl32_T0_T1 (void)
79aceca5 1286{
76a66253 1287 T0 = rotl32(T0, T1 & 0x1F);
79aceca5
FB
1288 RETURN();
1289}
1290
76a66253 1291void OPPROTO op_rotli32_T0 (void)
79aceca5 1292{
76a66253 1293 T0 = rotl32(T0, PARAM1);
79aceca5
FB
1294 RETURN();
1295}
1296
51789c41
JM
1297#if defined(TARGET_PPC64)
1298void OPPROTO op_rotl64_T0_T1 (void)
1299{
1300 T0 = rotl64(T0, T1 & 0x3F);
1301 RETURN();
1302}
1303
1304void OPPROTO op_rotli64_T0 (void)
1305{
1306 T0 = rotl64(T0, PARAM1);
1307 RETURN();
1308}
1309#endif
1310
79aceca5
FB
1311/*** Integer shift ***/
1312/* shift left word */
d9bce9d9 1313void OPPROTO op_slw (void)
79aceca5
FB
1314{
1315 if (T1 & 0x20) {
1316 T0 = 0;
d9bce9d9
JM
1317 } else {
1318 T0 = (uint32_t)(T0 << T1);
1319 }
1320 RETURN();
1321}
1322
1323#if defined(TARGET_PPC64)
1324void OPPROTO op_sld (void)
1325{
1326 if (T1 & 0x40) {
1327 T0 = 0;
79aceca5
FB
1328 } else {
1329 T0 = T0 << T1;
1330 }
1331 RETURN();
1332}
d9bce9d9 1333#endif
79aceca5
FB
1334
1335/* shift right algebraic word */
76a66253 1336void OPPROTO op_sraw (void)
79aceca5 1337{
9a64fbe4 1338 do_sraw();
79aceca5
FB
1339 RETURN();
1340}
1341
d9bce9d9
JM
1342#if defined(TARGET_PPC64)
1343void OPPROTO op_srad (void)
1344{
1345 do_srad();
1346 RETURN();
1347}
1348#endif
1349
79aceca5 1350/* shift right algebraic word immediate */
d9bce9d9 1351void OPPROTO op_srawi (void)
79aceca5 1352{
d9bce9d9
JM
1353 uint32_t mask = (uint32_t)PARAM2;
1354
1355 T0 = (int32_t)T0 >> PARAM1;
1356 if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
79aceca5
FB
1357 xer_ca = 1;
1358 } else {
1359 xer_ca = 0;
1360 }
1361 RETURN();
1362}
1363
d9bce9d9
JM
1364#if defined(TARGET_PPC64)
1365void OPPROTO op_sradi (void)
1366{
1367 uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1368
1369 T0 = (int64_t)T0 >> PARAM1;
1370 if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1371 xer_ca = 1;
1372 } else {
1373 xer_ca = 0;
1374 }
1375 RETURN();
1376}
1377#endif
1378
79aceca5 1379/* shift right word */
d9bce9d9 1380void OPPROTO op_srw (void)
79aceca5
FB
1381{
1382 if (T1 & 0x20) {
1383 T0 = 0;
1384 } else {
d9bce9d9
JM
1385 T0 = (uint32_t)T0 >> T1;
1386 }
1387 RETURN();
1388}
1389
1390#if defined(TARGET_PPC64)
1391void OPPROTO op_srd (void)
1392{
1393 if (T1 & 0x40) {
1394 T0 = 0;
1395 } else {
1396 T0 = (uint64_t)T0 >> T1;
79aceca5
FB
1397 }
1398 RETURN();
1399}
d9bce9d9 1400#endif
79aceca5 1401
76a66253
JM
1402void OPPROTO op_sl_T0_T1 (void)
1403{
1404 T0 = T0 << T1;
1405 RETURN();
1406}
1407
1408void OPPROTO op_sli_T0 (void)
1409{
1410 T0 = T0 << PARAM1;
1411 RETURN();
1412}
1413
fc0d441e
JM
1414void OPPROTO op_sli_T1 (void)
1415{
1416 T1 = T1 << PARAM1;
1417 RETURN();
1418}
1419
76a66253
JM
1420void OPPROTO op_srl_T0_T1 (void)
1421{
d9bce9d9
JM
1422 T0 = (uint32_t)T0 >> T1;
1423 RETURN();
1424}
1425
1426#if defined(TARGET_PPC64)
1427void OPPROTO op_srl_T0_T1_64 (void)
1428{
1429 T0 = (uint32_t)T0 >> T1;
76a66253
JM
1430 RETURN();
1431}
d9bce9d9 1432#endif
76a66253
JM
1433
1434void OPPROTO op_srli_T0 (void)
1435{
d9bce9d9 1436 T0 = (uint32_t)T0 >> PARAM1;
76a66253
JM
1437 RETURN();
1438}
1439
d9bce9d9
JM
1440#if defined(TARGET_PPC64)
1441void OPPROTO op_srli_T0_64 (void)
1442{
1443 T0 = (uint64_t)T0 >> PARAM1;
1444 RETURN();
1445}
1446#endif
1447
76a66253
JM
1448void OPPROTO op_srli_T1 (void)
1449{
d9bce9d9 1450 T1 = (uint32_t)T1 >> PARAM1;
76a66253
JM
1451 RETURN();
1452}
1453
d9bce9d9
JM
1454#if defined(TARGET_PPC64)
1455void OPPROTO op_srli_T1_64 (void)
1456{
1457 T1 = (uint64_t)T1 >> PARAM1;
1458 RETURN();
1459}
1460#endif
1461
79aceca5 1462/*** Floating-Point arithmetic ***/
9a64fbe4 1463/* fadd - fadd. */
36081602 1464void OPPROTO op_fadd (void)
79aceca5 1465{
1cdb9c3d 1466#if USE_PRECISE_EMULATION
7c58044c
JM
1467 do_fadd();
1468#else
76a66253 1469 FT0 = float64_add(FT0, FT1, &env->fp_status);
7c58044c 1470#endif
79aceca5
FB
1471 RETURN();
1472}
1473
9a64fbe4 1474/* fsub - fsub. */
36081602 1475void OPPROTO op_fsub (void)
79aceca5 1476{
1cdb9c3d 1477#if USE_PRECISE_EMULATION
7c58044c
JM
1478 do_fsub();
1479#else
76a66253 1480 FT0 = float64_sub(FT0, FT1, &env->fp_status);
7c58044c 1481#endif
79aceca5
FB
1482 RETURN();
1483}
1484
9a64fbe4 1485/* fmul - fmul. */
36081602 1486void OPPROTO op_fmul (void)
79aceca5 1487{
1cdb9c3d 1488#if USE_PRECISE_EMULATION
7c58044c
JM
1489 do_fmul();
1490#else
76a66253 1491 FT0 = float64_mul(FT0, FT1, &env->fp_status);
7c58044c 1492#endif
79aceca5
FB
1493 RETURN();
1494}
1495
9a64fbe4 1496/* fdiv - fdiv. */
36081602 1497void OPPROTO op_fdiv (void)
79aceca5 1498{
1cdb9c3d 1499#if USE_PRECISE_EMULATION
7c58044c
JM
1500 do_fdiv();
1501#else
fdabc366 1502 FT0 = float64_div(FT0, FT1, &env->fp_status);
7c58044c 1503#endif
79aceca5
FB
1504 RETURN();
1505}
28b6751f 1506
9a64fbe4 1507/* fsqrt - fsqrt. */
36081602 1508void OPPROTO op_fsqrt (void)
28b6751f 1509{
9a64fbe4
FB
1510 do_fsqrt();
1511 RETURN();
28b6751f
FB
1512}
1513
d7e4b87e
JM
1514/* fre - fre. */
1515void OPPROTO op_fre (void)
1516{
1517 do_fre();
1518 RETURN();
1519}
1520
9a64fbe4 1521/* fres - fres. */
36081602 1522void OPPROTO op_fres (void)
28b6751f 1523{
9a64fbe4
FB
1524 do_fres();
1525 RETURN();
28b6751f
FB
1526}
1527
9a64fbe4 1528/* frsqrte - frsqrte. */
36081602 1529void OPPROTO op_frsqrte (void)
28b6751f 1530{
4ecc3190 1531 do_frsqrte();
9a64fbe4 1532 RETURN();
28b6751f
FB
1533}
1534
9a64fbe4 1535/* fsel - fsel. */
36081602 1536void OPPROTO op_fsel (void)
28b6751f 1537{
9a64fbe4
FB
1538 do_fsel();
1539 RETURN();
28b6751f
FB
1540}
1541
9a64fbe4
FB
1542/*** Floating-Point multiply-and-add ***/
1543/* fmadd - fmadd. */
36081602 1544void OPPROTO op_fmadd (void)
28b6751f 1545{
1cdb9c3d 1546#if USE_PRECISE_EMULATION
e864cabd
JM
1547 do_fmadd();
1548#else
76a66253
JM
1549 FT0 = float64_mul(FT0, FT1, &env->fp_status);
1550 FT0 = float64_add(FT0, FT2, &env->fp_status);
e864cabd 1551#endif
9a64fbe4 1552 RETURN();
28b6751f
FB
1553}
1554
9a64fbe4 1555/* fmsub - fmsub. */
36081602 1556void OPPROTO op_fmsub (void)
28b6751f 1557{
1cdb9c3d 1558#if USE_PRECISE_EMULATION
e864cabd
JM
1559 do_fmsub();
1560#else
76a66253
JM
1561 FT0 = float64_mul(FT0, FT1, &env->fp_status);
1562 FT0 = float64_sub(FT0, FT2, &env->fp_status);
e864cabd 1563#endif
9a64fbe4 1564 RETURN();
28b6751f
FB
1565}
1566
9a64fbe4 1567/* fnmadd - fnmadd. - fnmadds - fnmadds. */
36081602 1568void OPPROTO op_fnmadd (void)
28b6751f 1569{
4b3686fa 1570 do_fnmadd();
9a64fbe4 1571 RETURN();
28b6751f
FB
1572}
1573
9a64fbe4 1574/* fnmsub - fnmsub. */
36081602 1575void OPPROTO op_fnmsub (void)
28b6751f 1576{
4b3686fa 1577 do_fnmsub();
9a64fbe4 1578 RETURN();
28b6751f
FB
1579}
1580
9a64fbe4
FB
1581/*** Floating-Point round & convert ***/
1582/* frsp - frsp. */
36081602 1583void OPPROTO op_frsp (void)
28b6751f 1584{
1cdb9c3d 1585#if USE_PRECISE_EMULATION
7c58044c
JM
1586 do_frsp();
1587#else
76a66253 1588 FT0 = float64_to_float32(FT0, &env->fp_status);
7c58044c 1589#endif
9a64fbe4 1590 RETURN();
28b6751f
FB
1591}
1592
9a64fbe4 1593/* fctiw - fctiw. */
36081602 1594void OPPROTO op_fctiw (void)
28b6751f 1595{
9a64fbe4
FB
1596 do_fctiw();
1597 RETURN();
28b6751f
FB
1598}
1599
9a64fbe4 1600/* fctiwz - fctiwz. */
36081602 1601void OPPROTO op_fctiwz (void)
28b6751f 1602{
9a64fbe4
FB
1603 do_fctiwz();
1604 RETURN();
28b6751f
FB
1605}
1606
426613db
JM
1607#if defined(TARGET_PPC64)
1608/* fcfid - fcfid. */
36081602 1609void OPPROTO op_fcfid (void)
426613db
JM
1610{
1611 do_fcfid();
1612 RETURN();
1613}
1614
1615/* fctid - fctid. */
36081602 1616void OPPROTO op_fctid (void)
426613db
JM
1617{
1618 do_fctid();
1619 RETURN();
1620}
1621
1622/* fctidz - fctidz. */
36081602 1623void OPPROTO op_fctidz (void)
426613db
JM
1624{
1625 do_fctidz();
1626 RETURN();
1627}
1628#endif
1629
d7e4b87e
JM
1630void OPPROTO op_frin (void)
1631{
1632 do_frin();
1633 RETURN();
1634}
1635
1636void OPPROTO op_friz (void)
1637{
1638 do_friz();
1639 RETURN();
1640}
1641
1642void OPPROTO op_frip (void)
1643{
1644 do_frip();
1645 RETURN();
1646}
1647
1648void OPPROTO op_frim (void)
1649{
1650 do_frim();
1651 RETURN();
1652}
1653
9a64fbe4
FB
1654/*** Floating-Point compare ***/
1655/* fcmpu */
36081602 1656void OPPROTO op_fcmpu (void)
28b6751f 1657{
9a64fbe4
FB
1658 do_fcmpu();
1659 RETURN();
28b6751f
FB
1660}
1661
9a64fbe4 1662/* fcmpo */
36081602 1663void OPPROTO op_fcmpo (void)
fb0eaffc 1664{
9a64fbe4
FB
1665 do_fcmpo();
1666 RETURN();
fb0eaffc
FB
1667}
1668
9a64fbe4
FB
1669/*** Floating-point move ***/
1670/* fabs */
36081602 1671void OPPROTO op_fabs (void)
fb0eaffc 1672{
fdabc366 1673 FT0 = float64_abs(FT0);
fb0eaffc
FB
1674 RETURN();
1675}
1676
9a64fbe4 1677/* fnabs */
36081602 1678void OPPROTO op_fnabs (void)
fb0eaffc 1679{
fdabc366
FB
1680 FT0 = float64_abs(FT0);
1681 FT0 = float64_chs(FT0);
fb0eaffc
FB
1682 RETURN();
1683}
1684
9a64fbe4 1685/* fneg */
36081602 1686void OPPROTO op_fneg (void)
fb0eaffc 1687{
fdabc366 1688 FT0 = float64_chs(FT0);
fb0eaffc
FB
1689 RETURN();
1690}
1691
9a64fbe4 1692/* Load and store */
9a64fbe4 1693#define MEMSUFFIX _raw
76a66253 1694#include "op_helper.h"
9a64fbe4 1695#include "op_mem.h"
a541f297 1696#if !defined(CONFIG_USER_ONLY)
9a64fbe4 1697#define MEMSUFFIX _user
76a66253 1698#include "op_helper.h"
9a64fbe4 1699#include "op_mem.h"
9a64fbe4 1700#define MEMSUFFIX _kernel
76a66253 1701#include "op_helper.h"
9a64fbe4 1702#include "op_mem.h"
1e42b8f0
JM
1703#define MEMSUFFIX _hypv
1704#include "op_helper.h"
1705#include "op_mem.h"
1706#endif
9a64fbe4 1707
4b3686fa 1708/* Special op to check and maybe clear reservation */
d9bce9d9 1709void OPPROTO op_check_reservation (void)
4b3686fa 1710{
fdabc366 1711 if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
a73666f6 1712 env->reserve = (target_ulong)-1ULL;
4b3686fa
FB
1713 RETURN();
1714}
1715
d9bce9d9
JM
1716#if defined(TARGET_PPC64)
1717void OPPROTO op_check_reservation_64 (void)
1718{
1719 if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
6f2d8978 1720 env->reserve = (target_ulong)-1ULL;
d9bce9d9
JM
1721 RETURN();
1722}
1723#endif
1724
be147d08
JM
1725void OPPROTO op_wait (void)
1726{
1727 env->halted = 1;
1728 RETURN();
1729}
1730
9a64fbe4 1731/* Return from interrupt */
76a66253
JM
1732#if !defined(CONFIG_USER_ONLY)
1733void OPPROTO op_rfi (void)
28b6751f 1734{
fdabc366 1735 do_rfi();
fb0eaffc
FB
1736 RETURN();
1737}
d9bce9d9
JM
1738
1739#if defined(TARGET_PPC64)
426613db
JM
1740void OPPROTO op_rfid (void)
1741{
1742 do_rfid();
1743 RETURN();
1744}
be147d08 1745
be147d08
JM
1746void OPPROTO op_hrfid (void)
1747{
1748 do_hrfid();
1749 RETURN();
1750}
1751#endif
6f5d427d
JM
1752
1753/* Exception vectors */
1754void OPPROTO op_store_excp_prefix (void)
1755{
1756 T0 &= env->ivpr_mask;
1757 env->excp_prefix = T0;
1758 RETURN();
1759}
1760
1761void OPPROTO op_store_excp_vector (void)
1762{
1763 T0 &= env->ivor_mask;
1764 env->excp_vectors[PARAM1] = T0;
1765 RETURN();
1766}
76a66253 1767#endif
fb0eaffc 1768
9a64fbe4 1769/* Trap word */
76a66253 1770void OPPROTO op_tw (void)
fb0eaffc 1771{
76a66253 1772 do_tw(PARAM1);
fb0eaffc
FB
1773 RETURN();
1774}
1775
d9bce9d9
JM
1776#if defined(TARGET_PPC64)
1777void OPPROTO op_td (void)
1778{
1779 do_td(PARAM1);
1780 RETURN();
1781}
1782#endif
1783
76a66253 1784#if !defined(CONFIG_USER_ONLY)
9a64fbe4 1785/* tlbia */
36081602 1786void OPPROTO op_tlbia (void)
fb0eaffc 1787{
daf4f96e 1788 ppc_tlb_invalidate_all(env);
9a64fbe4
FB
1789 RETURN();
1790}
1791
1792/* tlbie */
d9bce9d9 1793void OPPROTO op_tlbie (void)
9a64fbe4 1794{
daf4f96e 1795 ppc_tlb_invalidate_one(env, (uint32_t)T0);
fb0eaffc 1796 RETURN();
28b6751f 1797}
d9bce9d9
JM
1798
1799#if defined(TARGET_PPC64)
1800void OPPROTO op_tlbie_64 (void)
1801{
daf4f96e 1802 ppc_tlb_invalidate_one(env, T0);
d9bce9d9
JM
1803 RETURN();
1804}
1805#endif
1806
1807#if defined(TARGET_PPC64)
1808void OPPROTO op_slbia (void)
1809{
daf4f96e 1810 ppc_slb_invalidate_all(env);
d9bce9d9
JM
1811 RETURN();
1812}
1813
1814void OPPROTO op_slbie (void)
1815{
daf4f96e
JM
1816 ppc_slb_invalidate_one(env, (uint32_t)T0);
1817 RETURN();
1818}
1819
1820void OPPROTO op_slbie_64 (void)
1821{
1822 ppc_slb_invalidate_one(env, T0);
d9bce9d9
JM
1823 RETURN();
1824}
1825#endif
76a66253 1826#endif
3fc6c082 1827
76a66253 1828#if !defined(CONFIG_USER_ONLY)
7dbe11ac 1829/* PowerPC 602/603/755 software TLB load instructions */
76a66253
JM
1830void OPPROTO op_6xx_tlbld (void)
1831{
1832 do_load_6xx_tlb(0);
1833 RETURN();
1834}
1835
1836void OPPROTO op_6xx_tlbli (void)
1837{
1838 do_load_6xx_tlb(1);
1839 RETURN();
1840}
7dbe11ac
JM
1841
1842/* PowerPC 74xx software TLB load instructions */
1843void OPPROTO op_74xx_tlbld (void)
1844{
1845 do_load_74xx_tlb(0);
1846 RETURN();
1847}
1848
1849void OPPROTO op_74xx_tlbli (void)
1850{
1851 do_load_74xx_tlb(1);
1852 RETURN();
1853}
76a66253
JM
1854#endif
1855
1856/* 601 specific */
76a66253
JM
1857void OPPROTO op_load_601_rtcl (void)
1858{
1859 T0 = cpu_ppc601_load_rtcl(env);
1860 RETURN();
1861}
1862
76a66253
JM
1863void OPPROTO op_load_601_rtcu (void)
1864{
1865 T0 = cpu_ppc601_load_rtcu(env);
1866 RETURN();
1867}
1868
1869#if !defined(CONFIG_USER_ONLY)
76a66253
JM
1870void OPPROTO op_store_601_rtcl (void)
1871{
1872 cpu_ppc601_store_rtcl(env, T0);
1873 RETURN();
1874}
1875
76a66253
JM
1876void OPPROTO op_store_601_rtcu (void)
1877{
1878 cpu_ppc601_store_rtcu(env, T0);
1879 RETURN();
1880}
1881
056401ea
JM
1882void OPPROTO op_store_hid0_601 (void)
1883{
1884 do_store_hid0_601();
1885 RETURN();
1886}
1887
76a66253
JM
1888void OPPROTO op_load_601_bat (void)
1889{
1890 T0 = env->IBAT[PARAM1][PARAM2];
1891 RETURN();
1892}
76a66253 1893
76a66253
JM
1894void OPPROTO op_store_601_batl (void)
1895{
056401ea 1896 do_store_ibatl_601(env, PARAM1, T0);
76a66253
JM
1897 RETURN();
1898}
1899
1900void OPPROTO op_store_601_batu (void)
1901{
056401ea 1902 do_store_ibatu_601(env, PARAM1, T0);
76a66253
JM
1903 RETURN();
1904}
1905#endif /* !defined(CONFIG_USER_ONLY) */
1906
1907/* PowerPC 601 specific instructions (POWER bridge) */
1908/* XXX: those micro-ops need tests ! */
1909void OPPROTO op_POWER_abs (void)
1910{
9c7e37e7 1911 if ((int32_t)T0 == INT32_MIN)
76a66253 1912 T0 = INT32_MAX;
9c7e37e7 1913 else if ((int32_t)T0 < 0)
76a66253
JM
1914 T0 = -T0;
1915 RETURN();
1916}
1917
1918void OPPROTO op_POWER_abso (void)
1919{
1920 do_POWER_abso();
1921 RETURN();
1922}
1923
1924void OPPROTO op_POWER_clcs (void)
1925{
1926 do_POWER_clcs();
1927 RETURN();
1928}
1929
1930void OPPROTO op_POWER_div (void)
1931{
1932 do_POWER_div();
1933 RETURN();
1934}
1935
1936void OPPROTO op_POWER_divo (void)
1937{
1938 do_POWER_divo();
1939 RETURN();
1940}
1941
1942void OPPROTO op_POWER_divs (void)
1943{
1944 do_POWER_divs();
1945 RETURN();
1946}
1947
1948void OPPROTO op_POWER_divso (void)
1949{
1950 do_POWER_divso();
1951 RETURN();
1952}
1953
1954void OPPROTO op_POWER_doz (void)
1955{
d9bce9d9 1956 if ((int32_t)T1 > (int32_t)T0)
76a66253
JM
1957 T0 = T1 - T0;
1958 else
1959 T0 = 0;
1960 RETURN();
1961}
1962
1963void OPPROTO op_POWER_dozo (void)
1964{
1965 do_POWER_dozo();
1966 RETURN();
1967}
1968
1969void OPPROTO op_load_xer_cmp (void)
1970{
1971 T2 = xer_cmp;
1972 RETURN();
1973}
1974
1975void OPPROTO op_POWER_maskg (void)
1976{
1977 do_POWER_maskg();
1978 RETURN();
1979}
1980
1981void OPPROTO op_POWER_maskir (void)
1982{
1983 T0 = (T0 & ~T2) | (T1 & T2);
1984 RETURN();
1985}
1986
1987void OPPROTO op_POWER_mul (void)
1988{
1989 uint64_t tmp;
1990
1991 tmp = (uint64_t)T0 * (uint64_t)T1;
1992 env->spr[SPR_MQ] = tmp >> 32;
1993 T0 = tmp;
1994 RETURN();
1995}
1996
1997void OPPROTO op_POWER_mulo (void)
1998{
1999 do_POWER_mulo();
2000 RETURN();
2001}
2002
2003void OPPROTO op_POWER_nabs (void)
2004{
2005 if (T0 > 0)
2006 T0 = -T0;
2007 RETURN();
2008}
2009
2010void OPPROTO op_POWER_nabso (void)
2011{
2012 /* nabs never overflows */
2013 if (T0 > 0)
2014 T0 = -T0;
2015 xer_ov = 0;
2016 RETURN();
2017}
2018
2019/* XXX: factorise POWER rotates... */
2020void OPPROTO op_POWER_rlmi (void)
2021{
2022 T0 = rotl32(T0, T2) & PARAM1;
2f401176 2023 T0 |= T1 & (uint32_t)PARAM2;
76a66253
JM
2024 RETURN();
2025}
2026
2027void OPPROTO op_POWER_rrib (void)
2028{
2029 T2 &= 0x1FUL;
2030 T0 = rotl32(T0 & INT32_MIN, T2);
2031 T0 |= T1 & ~rotl32(INT32_MIN, T2);
2032 RETURN();
2033}
2034
2035void OPPROTO op_POWER_sle (void)
2036{
2037 T1 &= 0x1FUL;
2038 env->spr[SPR_MQ] = rotl32(T0, T1);
2039 T0 = T0 << T1;
2040 RETURN();
2041}
2042
2043void OPPROTO op_POWER_sleq (void)
2044{
2045 uint32_t tmp = env->spr[SPR_MQ];
2046
2047 T1 &= 0x1FUL;
2048 env->spr[SPR_MQ] = rotl32(T0, T1);
2049 T0 = T0 << T1;
2050 T0 |= tmp >> (32 - T1);
2051 RETURN();
2052}
2053
2054void OPPROTO op_POWER_sllq (void)
2055{
6f2d8978 2056 uint32_t msk = UINT32_MAX;
76a66253
JM
2057
2058 msk = msk << (T1 & 0x1FUL);
2059 if (T1 & 0x20UL)
2060 msk = ~msk;
2061 T1 &= 0x1FUL;
2062 T0 = (T0 << T1) & msk;
2063 T0 |= env->spr[SPR_MQ] & ~msk;
2064 RETURN();
2065}
2066
2067void OPPROTO op_POWER_slq (void)
2068{
6f2d8978 2069 uint32_t msk = UINT32_MAX, tmp;
76a66253
JM
2070
2071 msk = msk << (T1 & 0x1FUL);
2072 if (T1 & 0x20UL)
2073 msk = ~msk;
2074 T1 &= 0x1FUL;
2075 tmp = rotl32(T0, T1);
2076 T0 = tmp & msk;
2077 env->spr[SPR_MQ] = tmp;
2078 RETURN();
2079}
2080
2081void OPPROTO op_POWER_sraq (void)
2082{
2083 env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2084 if (T1 & 0x20UL)
6f2d8978 2085 T0 = UINT32_MAX;
76a66253 2086 else
d9bce9d9 2087 T0 = (int32_t)T0 >> T1;
76a66253
JM
2088 RETURN();
2089}
2090
2091void OPPROTO op_POWER_sre (void)
2092{
2093 T1 &= 0x1FUL;
2094 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
d9bce9d9 2095 T0 = (int32_t)T0 >> T1;
76a66253
JM
2096 RETURN();
2097}
2098
2099void OPPROTO op_POWER_srea (void)
2100{
2101 T1 &= 0x1FUL;
2102 env->spr[SPR_MQ] = T0 >> T1;
d9bce9d9 2103 T0 = (int32_t)T0 >> T1;
76a66253
JM
2104 RETURN();
2105}
2106
2107void OPPROTO op_POWER_sreq (void)
2108{
2109 uint32_t tmp;
2110 int32_t msk;
2111
2112 T1 &= 0x1FUL;
2113 msk = INT32_MIN >> T1;
2114 tmp = env->spr[SPR_MQ];
2115 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2116 T0 = T0 >> T1;
2117 T0 |= tmp & msk;
2118 RETURN();
2119}
2120
2121void OPPROTO op_POWER_srlq (void)
2122{
2123 uint32_t tmp;
2124 int32_t msk;
2125
2126 msk = INT32_MIN >> (T1 & 0x1FUL);
2127 if (T1 & 0x20UL)
2128 msk = ~msk;
2129 T1 &= 0x1FUL;
2130 tmp = env->spr[SPR_MQ];
2131 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2132 T0 = T0 >> T1;
2133 T0 &= msk;
2134 T0 |= tmp & ~msk;
2135 RETURN();
2136}
2137
2138void OPPROTO op_POWER_srq (void)
2139{
2140 T1 &= 0x1FUL;
2141 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2142 T0 = T0 >> T1;
2143 RETURN();
2144}
2145
2146/* POWER instructions not implemented in PowerPC 601 */
2147#if !defined(CONFIG_USER_ONLY)
2148void OPPROTO op_POWER_mfsri (void)
2149{
2150 T1 = T0 >> 28;
2151 T0 = env->sr[T1];
2152 RETURN();
2153}
2154
2155void OPPROTO op_POWER_rac (void)
2156{
2157 do_POWER_rac();
2158 RETURN();
2159}
2160
2161void OPPROTO op_POWER_rfsvc (void)
2162{
2163 do_POWER_rfsvc();
2164 RETURN();
2165}
2166#endif
2167
2168/* PowerPC 602 specific instruction */
2169#if !defined(CONFIG_USER_ONLY)
2170void OPPROTO op_602_mfrom (void)
2171{
2172 do_op_602_mfrom();
2173 RETURN();
2174}
2175#endif
2176
2177/* PowerPC 4xx specific micro-ops */
2178void OPPROTO op_405_add_T0_T2 (void)
2179{
2180 T0 = (int32_t)T0 + (int32_t)T2;
2181 RETURN();
2182}
2183
2184void OPPROTO op_405_mulchw (void)
2185{
2186 T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2187 RETURN();
2188}
2189
2190void OPPROTO op_405_mulchwu (void)
2191{
2192 T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2193 RETURN();
2194}
2195
2196void OPPROTO op_405_mulhhw (void)
2197{
2198 T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2199 RETURN();
2200}
2201
2202void OPPROTO op_405_mulhhwu (void)
2203{
2204 T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2205 RETURN();
2206}
2207
2208void OPPROTO op_405_mullhw (void)
2209{
2210 T0 = ((int16_t)T0) * ((int16_t)T1);
2211 RETURN();
2212}
2213
2214void OPPROTO op_405_mullhwu (void)
2215{
2216 T0 = ((uint16_t)T0) * ((uint16_t)T1);
2217 RETURN();
2218}
2219
76a66253
JM
2220void OPPROTO op_405_check_sat (void)
2221{
2222 do_405_check_sat();
2223 RETURN();
2224}
2225
2226void OPPROTO op_405_check_ovu (void)
2227{
2228 if (likely(T0 >= T2)) {
2229 xer_ov = 0;
2230 } else {
2231 xer_ov = 1;
2232 xer_so = 1;
2233 }
2234 RETURN();
2235}
2236
2237void OPPROTO op_405_check_satu (void)
2238{
2239 if (unlikely(T0 < T2)) {
2240 /* Saturate result */
6f2d8978 2241 T0 = UINT32_MAX;
76a66253
JM
2242 }
2243 RETURN();
2244}
2245
a42bd6cc 2246void OPPROTO op_load_dcr (void)
76a66253 2247{
a42bd6cc 2248 do_load_dcr();
76a66253
JM
2249 RETURN();
2250}
2251
a42bd6cc 2252void OPPROTO op_store_dcr (void)
76a66253 2253{
a42bd6cc 2254 do_store_dcr();
76a66253
JM
2255 RETURN();
2256}
2257
a750fc0b 2258#if !defined(CONFIG_USER_ONLY)
76a66253
JM
2259/* Return from critical interrupt :
2260 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2261 */
a42bd6cc
JM
2262void OPPROTO op_40x_rfci (void)
2263{
2264 do_40x_rfci();
2265 RETURN();
2266}
2267
2268void OPPROTO op_rfci (void)
2269{
2270 do_rfci();
2271 RETURN();
2272}
2273
2274void OPPROTO op_rfdi (void)
2275{
2276 do_rfdi();
2277 RETURN();
2278}
2279
2280void OPPROTO op_rfmci (void)
76a66253 2281{
a42bd6cc 2282 do_rfmci();
76a66253
JM
2283 RETURN();
2284}
2285
a42bd6cc 2286void OPPROTO op_wrte (void)
76a66253 2287{
0411a972
JM
2288 /* We don't call do_store_msr here as we won't trigger
2289 * any special case nor change hflags
2290 */
2291 T0 &= 1 << MSR_EE;
2292 env->msr &= ~(1 << MSR_EE);
2293 env->msr |= T0;
76a66253
JM
2294 RETURN();
2295}
2296
a4bb6c3e 2297void OPPROTO op_440_tlbre (void)
5eb7995e 2298{
a4bb6c3e 2299 do_440_tlbre(PARAM1);
5eb7995e
JM
2300 RETURN();
2301}
2302
a4bb6c3e 2303void OPPROTO op_440_tlbsx (void)
5eb7995e 2304{
daf4f96e 2305 T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
5eb7995e
JM
2306 RETURN();
2307}
2308
daf4f96e 2309void OPPROTO op_4xx_tlbsx_check (void)
5eb7995e 2310{
daf4f96e
JM
2311 int tmp;
2312
2313 tmp = xer_so;
6f2d8978 2314 if ((int)T0 != -1)
daf4f96e
JM
2315 tmp |= 0x02;
2316 env->crf[0] = tmp;
5eb7995e
JM
2317 RETURN();
2318}
2319
a4bb6c3e 2320void OPPROTO op_440_tlbwe (void)
5eb7995e 2321{
a4bb6c3e 2322 do_440_tlbwe(PARAM1);
5eb7995e
JM
2323 RETURN();
2324}
2325
76a66253
JM
2326void OPPROTO op_4xx_tlbre_lo (void)
2327{
2328 do_4xx_tlbre_lo();
2329 RETURN();
2330}
2331
2332void OPPROTO op_4xx_tlbre_hi (void)
2333{
2334 do_4xx_tlbre_hi();
2335 RETURN();
2336}
2337
2338void OPPROTO op_4xx_tlbsx (void)
2339{
daf4f96e 2340 T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
76a66253
JM
2341 RETURN();
2342}
2343
2344void OPPROTO op_4xx_tlbwe_lo (void)
2345{
2346 do_4xx_tlbwe_lo();
2347 RETURN();
2348}
2349
2350void OPPROTO op_4xx_tlbwe_hi (void)
2351{
2352 do_4xx_tlbwe_hi();
2353 RETURN();
2354}
2355#endif
2356
2357/* SPR micro-ops */
2358/* 440 specific */
2359void OPPROTO op_440_dlmzb (void)
2360{
2361 do_440_dlmzb();
2362 RETURN();
2363}
2364
2365void OPPROTO op_440_dlmzb_update_Rc (void)
2366{
2367 if (T0 == 8)
2368 T0 = 0x2;
2369 else if (T0 < 4)
2370 T0 = 0x4;
2371 else
2372 T0 = 0x8;
2373 RETURN();
2374}
2375
2376#if !defined(CONFIG_USER_ONLY)
2377void OPPROTO op_store_pir (void)
3fc6c082
FB
2378{
2379 env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2380 RETURN();
2381}
76a66253
JM
2382
2383void OPPROTO op_load_403_pb (void)
2384{
2385 do_load_403_pb(PARAM1);
2386 RETURN();
2387}
2388
2389void OPPROTO op_store_403_pb (void)
2390{
2391 do_store_403_pb(PARAM1);
2392 RETURN();
2393}
2394
76a66253
JM
2395void OPPROTO op_load_40x_pit (void)
2396{
2397 T0 = load_40x_pit(env);
2398 RETURN();
2399}
2400
76a66253
JM
2401void OPPROTO op_store_40x_pit (void)
2402{
2403 store_40x_pit(env, T0);
2404 RETURN();
2405}
2406
8ecc7913
JM
2407void OPPROTO op_store_40x_dbcr0 (void)
2408{
2409 store_40x_dbcr0(env, T0);
be147d08 2410 RETURN();
8ecc7913
JM
2411}
2412
c294fc58
JM
2413void OPPROTO op_store_40x_sler (void)
2414{
2415 store_40x_sler(env, T0);
2416 RETURN();
2417}
2418
76a66253
JM
2419void OPPROTO op_store_booke_tcr (void)
2420{
2421 store_booke_tcr(env, T0);
2422 RETURN();
2423}
2424
76a66253
JM
2425void OPPROTO op_store_booke_tsr (void)
2426{
2427 store_booke_tsr(env, T0);
2428 RETURN();
2429}
2430#endif /* !defined(CONFIG_USER_ONLY) */
0487d6a8 2431
0487d6a8
JM
2432/* SPE extension */
2433void OPPROTO op_splatw_T1_64 (void)
2434{
2435 T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
e864cabd 2436 RETURN();
0487d6a8
JM
2437}
2438
2439void OPPROTO op_splatwi_T0_64 (void)
2440{
2441 uint64_t tmp = PARAM1;
2442
2443 T0_64 = (tmp << 32) | tmp;
e864cabd 2444 RETURN();
0487d6a8
JM
2445}
2446
2447void OPPROTO op_splatwi_T1_64 (void)
2448{
2449 uint64_t tmp = PARAM1;
2450
2451 T1_64 = (tmp << 32) | tmp;
e864cabd 2452 RETURN();
0487d6a8
JM
2453}
2454
2455void OPPROTO op_extsh_T1_64 (void)
2456{
2457 T1_64 = (int32_t)((int16_t)T1_64);
2458 RETURN();
2459}
2460
2461void OPPROTO op_sli16_T1_64 (void)
2462{
2463 T1_64 = T1_64 << 16;
2464 RETURN();
2465}
2466
2467void OPPROTO op_sli32_T1_64 (void)
2468{
2469 T1_64 = T1_64 << 32;
2470 RETURN();
2471}
2472
2473void OPPROTO op_srli32_T1_64 (void)
2474{
2475 T1_64 = T1_64 >> 32;
2476 RETURN();
2477}
2478
2479void OPPROTO op_evsel (void)
2480{
2481 do_evsel();
2482 RETURN();
2483}
2484
2485void OPPROTO op_evaddw (void)
2486{
2487 do_evaddw();
2488 RETURN();
2489}
2490
2491void OPPROTO op_evsubfw (void)
2492{
2493 do_evsubfw();
2494 RETURN();
2495}
2496
2497void OPPROTO op_evneg (void)
2498{
2499 do_evneg();
2500 RETURN();
2501}
2502
2503void OPPROTO op_evabs (void)
2504{
2505 do_evabs();
2506 RETURN();
2507}
2508
2509void OPPROTO op_evextsh (void)
2510{
2511 T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2512 (uint64_t)((int32_t)(int16_t)T0_64);
2513 RETURN();
2514}
2515
2516void OPPROTO op_evextsb (void)
2517{
2518 T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2519 (uint64_t)((int32_t)(int8_t)T0_64);
2520 RETURN();
2521}
2522
2523void OPPROTO op_evcntlzw (void)
2524{
2525 do_evcntlzw();
2526 RETURN();
2527}
2528
2529void OPPROTO op_evrndw (void)
2530{
2531 do_evrndw();
2532 RETURN();
2533}
2534
2535void OPPROTO op_brinc (void)
2536{
2537 do_brinc();
2538 RETURN();
2539}
2540
2541void OPPROTO op_evcntlsw (void)
2542{
2543 do_evcntlsw();
2544 RETURN();
2545}
2546
2547void OPPROTO op_evand (void)
2548{
2549 T0_64 &= T1_64;
2550 RETURN();
2551}
2552
2553void OPPROTO op_evandc (void)
2554{
2555 T0_64 &= ~T1_64;
2556 RETURN();
2557}
2558
2559void OPPROTO op_evor (void)
2560{
2561 T0_64 |= T1_64;
2562 RETURN();
2563}
2564
2565void OPPROTO op_evxor (void)
2566{
2567 T0_64 ^= T1_64;
2568 RETURN();
2569}
2570
2571void OPPROTO op_eveqv (void)
2572{
2573 T0_64 = ~(T0_64 ^ T1_64);
2574 RETURN();
2575}
2576
2577void OPPROTO op_evnor (void)
2578{
2579 T0_64 = ~(T0_64 | T1_64);
2580 RETURN();
2581}
2582
2583void OPPROTO op_evorc (void)
2584{
2585 T0_64 |= ~T1_64;
2586 RETURN();
2587}
2588
2589void OPPROTO op_evnand (void)
2590{
2591 T0_64 = ~(T0_64 & T1_64);
2592 RETURN();
2593}
2594
2595void OPPROTO op_evsrws (void)
2596{
2597 do_evsrws();
2598 RETURN();
2599}
2600
2601void OPPROTO op_evsrwu (void)
2602{
2603 do_evsrwu();
2604 RETURN();
2605}
2606
2607void OPPROTO op_evslw (void)
2608{
2609 do_evslw();
2610 RETURN();
2611}
2612
2613void OPPROTO op_evrlw (void)
2614{
2615 do_evrlw();
2616 RETURN();
2617}
2618
2619void OPPROTO op_evmergelo (void)
2620{
2621 T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2622 RETURN();
2623}
2624
2625void OPPROTO op_evmergehi (void)
2626{
2627 T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2628 RETURN();
2629}
2630
2631void OPPROTO op_evmergelohi (void)
2632{
2633 T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2634 RETURN();
2635}
2636
2637void OPPROTO op_evmergehilo (void)
2638{
2639 T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2640 RETURN();
2641}
2642
2643void OPPROTO op_evcmpgts (void)
2644{
2645 do_evcmpgts();
2646 RETURN();
2647}
2648
2649void OPPROTO op_evcmpgtu (void)
2650{
2651 do_evcmpgtu();
2652 RETURN();
2653}
2654
2655void OPPROTO op_evcmplts (void)
2656{
2657 do_evcmplts();
2658 RETURN();
2659}
2660
2661void OPPROTO op_evcmpltu (void)
2662{
2663 do_evcmpltu();
2664 RETURN();
2665}
2666
2667void OPPROTO op_evcmpeq (void)
2668{
2669 do_evcmpeq();
2670 RETURN();
2671}
2672
2673void OPPROTO op_evfssub (void)
2674{
2675 do_evfssub();
2676 RETURN();
2677}
2678
2679void OPPROTO op_evfsadd (void)
2680{
2681 do_evfsadd();
2682 RETURN();
2683}
2684
2685void OPPROTO op_evfsnabs (void)
2686{
2687 do_evfsnabs();
2688 RETURN();
2689}
2690
2691void OPPROTO op_evfsabs (void)
2692{
2693 do_evfsabs();
2694 RETURN();
2695}
2696
2697void OPPROTO op_evfsneg (void)
2698{
2699 do_evfsneg();
2700 RETURN();
2701}
2702
2703void OPPROTO op_evfsdiv (void)
2704{
2705 do_evfsdiv();
2706 RETURN();
2707}
2708
2709void OPPROTO op_evfsmul (void)
2710{
2711 do_evfsmul();
2712 RETURN();
2713}
2714
2715void OPPROTO op_evfscmplt (void)
2716{
2717 do_evfscmplt();
2718 RETURN();
2719}
2720
2721void OPPROTO op_evfscmpgt (void)
2722{
2723 do_evfscmpgt();
2724 RETURN();
2725}
2726
2727void OPPROTO op_evfscmpeq (void)
2728{
2729 do_evfscmpeq();
2730 RETURN();
2731}
2732
2733void OPPROTO op_evfscfsi (void)
2734{
2735 do_evfscfsi();
2736 RETURN();
2737}
2738
2739void OPPROTO op_evfscfui (void)
2740{
2741 do_evfscfui();
2742 RETURN();
2743}
2744
2745void OPPROTO op_evfscfsf (void)
2746{
2747 do_evfscfsf();
2748 RETURN();
2749}
2750
2751void OPPROTO op_evfscfuf (void)
2752{
2753 do_evfscfuf();
2754 RETURN();
2755}
2756
2757void OPPROTO op_evfsctsi (void)
2758{
2759 do_evfsctsi();
2760 RETURN();
2761}
2762
2763void OPPROTO op_evfsctui (void)
2764{
2765 do_evfsctui();
2766 RETURN();
2767}
2768
2769void OPPROTO op_evfsctsf (void)
2770{
2771 do_evfsctsf();
2772 RETURN();
2773}
2774
2775void OPPROTO op_evfsctuf (void)
2776{
2777 do_evfsctuf();
2778 RETURN();
2779}
2780
2781void OPPROTO op_evfsctuiz (void)
2782{
2783 do_evfsctuiz();
2784 RETURN();
2785}
2786
2787void OPPROTO op_evfsctsiz (void)
2788{
2789 do_evfsctsiz();
2790 RETURN();
2791}
2792
2793void OPPROTO op_evfststlt (void)
2794{
2795 do_evfststlt();
2796 RETURN();
2797}
2798
2799void OPPROTO op_evfststgt (void)
2800{
2801 do_evfststgt();
2802 RETURN();
2803}
2804
2805void OPPROTO op_evfststeq (void)
2806{
2807 do_evfststeq();
2808 RETURN();
2809}
2810
2811void OPPROTO op_efssub (void)
2812{
2813 T0_64 = _do_efssub(T0_64, T1_64);
2814 RETURN();
2815}
2816
2817void OPPROTO op_efsadd (void)
2818{
2819 T0_64 = _do_efsadd(T0_64, T1_64);
2820 RETURN();
2821}
2822
2823void OPPROTO op_efsnabs (void)
2824{
2825 T0_64 = _do_efsnabs(T0_64);
2826 RETURN();
2827}
2828
2829void OPPROTO op_efsabs (void)
2830{
2831 T0_64 = _do_efsabs(T0_64);
2832 RETURN();
2833}
2834
2835void OPPROTO op_efsneg (void)
2836{
2837 T0_64 = _do_efsneg(T0_64);
2838 RETURN();
2839}
2840
2841void OPPROTO op_efsdiv (void)
2842{
2843 T0_64 = _do_efsdiv(T0_64, T1_64);
2844 RETURN();
2845}
2846
2847void OPPROTO op_efsmul (void)
2848{
2849 T0_64 = _do_efsmul(T0_64, T1_64);
2850 RETURN();
2851}
2852
2853void OPPROTO op_efscmplt (void)
2854{
2855 do_efscmplt();
2856 RETURN();
2857}
2858
2859void OPPROTO op_efscmpgt (void)
2860{
2861 do_efscmpgt();
2862 RETURN();
2863}
2864
2865void OPPROTO op_efscfd (void)
2866{
2867 do_efscfd();
2868 RETURN();
2869}
2870
2871void OPPROTO op_efscmpeq (void)
2872{
2873 do_efscmpeq();
2874 RETURN();
2875}
2876
2877void OPPROTO op_efscfsi (void)
2878{
2879 do_efscfsi();
2880 RETURN();
2881}
2882
2883void OPPROTO op_efscfui (void)
2884{
2885 do_efscfui();
2886 RETURN();
2887}
2888
2889void OPPROTO op_efscfsf (void)
2890{
2891 do_efscfsf();
2892 RETURN();
2893}
2894
2895void OPPROTO op_efscfuf (void)
2896{
2897 do_efscfuf();
2898 RETURN();
2899}
2900
2901void OPPROTO op_efsctsi (void)
2902{
2903 do_efsctsi();
2904 RETURN();
2905}
2906
2907void OPPROTO op_efsctui (void)
2908{
2909 do_efsctui();
2910 RETURN();
2911}
2912
2913void OPPROTO op_efsctsf (void)
2914{
2915 do_efsctsf();
2916 RETURN();
2917}
2918
2919void OPPROTO op_efsctuf (void)
2920{
2921 do_efsctuf();
2922 RETURN();
2923}
2924
2925void OPPROTO op_efsctsiz (void)
2926{
2927 do_efsctsiz();
2928 RETURN();
2929}
2930
2931void OPPROTO op_efsctuiz (void)
2932{
2933 do_efsctuiz();
2934 RETURN();
2935}
2936
2937void OPPROTO op_efststlt (void)
2938{
2939 T0 = _do_efststlt(T0_64, T1_64);
2940 RETURN();
2941}
2942
2943void OPPROTO op_efststgt (void)
2944{
2945 T0 = _do_efststgt(T0_64, T1_64);
2946 RETURN();
2947}
2948
2949void OPPROTO op_efststeq (void)
2950{
2951 T0 = _do_efststeq(T0_64, T1_64);
2952 RETURN();
2953}
2954
2955void OPPROTO op_efdsub (void)
2956{
0ca9d380
AJ
2957 CPU_DoubleU u1, u2;
2958 u1.ll = T0_64;
2959 u2.ll = T1_64;
2960 u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
2961 T0_64 = u1.ll;
0487d6a8
JM
2962 RETURN();
2963}
2964
2965void OPPROTO op_efdadd (void)
2966{
0ca9d380
AJ
2967 CPU_DoubleU u1, u2;
2968 u1.ll = T0_64;
2969 u2.ll = T1_64;
2970 u1.d = float64_add(u1.d, u2.d, &env->spe_status);
2971 T0_64 = u1.ll;
0487d6a8
JM
2972 RETURN();
2973}
2974
2975void OPPROTO op_efdcfsid (void)
2976{
2977 do_efdcfsi();
2978 RETURN();
2979}
2980
2981void OPPROTO op_efdcfuid (void)
2982{
2983 do_efdcfui();
2984 RETURN();
2985}
2986
2987void OPPROTO op_efdnabs (void)
2988{
2989 T0_64 |= 0x8000000000000000ULL;
2990 RETURN();
2991}
2992
2993void OPPROTO op_efdabs (void)
2994{
2995 T0_64 &= ~0x8000000000000000ULL;
2996 RETURN();
2997}
2998
2999void OPPROTO op_efdneg (void)
3000{
3001 T0_64 ^= 0x8000000000000000ULL;
3002 RETURN();
3003}
3004
3005void OPPROTO op_efddiv (void)
3006{
0ca9d380
AJ
3007 CPU_DoubleU u1, u2;
3008 u1.ll = T0_64;
3009 u2.ll = T1_64;
3010 u1.d = float64_div(u1.d, u2.d, &env->spe_status);
3011 T0_64 = u1.ll;
0487d6a8
JM
3012 RETURN();
3013}
3014
3015void OPPROTO op_efdmul (void)
3016{
0ca9d380
AJ
3017 CPU_DoubleU u1, u2;
3018 u1.ll = T0_64;
3019 u2.ll = T1_64;
3020 u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3021 T0_64 = u1.ll;
0487d6a8
JM
3022 RETURN();
3023}
3024
3025void OPPROTO op_efdctsidz (void)
3026{
3027 do_efdctsiz();
3028 RETURN();
3029}
3030
3031void OPPROTO op_efdctuidz (void)
3032{
3033 do_efdctuiz();
3034 RETURN();
3035}
3036
3037void OPPROTO op_efdcmplt (void)
3038{
3039 do_efdcmplt();
3040 RETURN();
3041}
3042
3043void OPPROTO op_efdcmpgt (void)
3044{
3045 do_efdcmpgt();
3046 RETURN();
3047}
3048
3049void OPPROTO op_efdcfs (void)
3050{
3051 do_efdcfs();
3052 RETURN();
3053}
3054
3055void OPPROTO op_efdcmpeq (void)
3056{
3057 do_efdcmpeq();
3058 RETURN();
3059}
3060
3061void OPPROTO op_efdcfsi (void)
3062{
3063 do_efdcfsi();
3064 RETURN();
3065}
3066
3067void OPPROTO op_efdcfui (void)
3068{
3069 do_efdcfui();
3070 RETURN();
3071}
3072
3073void OPPROTO op_efdcfsf (void)
3074{
3075 do_efdcfsf();
3076 RETURN();
3077}
3078
3079void OPPROTO op_efdcfuf (void)
3080{
3081 do_efdcfuf();
3082 RETURN();
3083}
3084
3085void OPPROTO op_efdctsi (void)
3086{
3087 do_efdctsi();
3088 RETURN();
3089}
3090
3091void OPPROTO op_efdctui (void)
3092{
3093 do_efdctui();
3094 RETURN();
3095}
3096
3097void OPPROTO op_efdctsf (void)
3098{
3099 do_efdctsf();
3100 RETURN();
3101}
3102
3103void OPPROTO op_efdctuf (void)
3104{
3105 do_efdctuf();
3106 RETURN();
3107}
3108
3109void OPPROTO op_efdctuiz (void)
3110{
3111 do_efdctuiz();
3112 RETURN();
3113}
3114
3115void OPPROTO op_efdctsiz (void)
3116{
3117 do_efdctsiz();
3118 RETURN();
3119}
3120
3121void OPPROTO op_efdtstlt (void)
3122{
3123 T0 = _do_efdtstlt(T0_64, T1_64);
3124 RETURN();
3125}
3126
3127void OPPROTO op_efdtstgt (void)
3128{
3129 T0 = _do_efdtstgt(T0_64, T1_64);
3130 RETURN();
3131}
3132
3133void OPPROTO op_efdtsteq (void)
3134{
3135 T0 = _do_efdtsteq(T0_64, T1_64);
3136 RETURN();
3137}