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