Revision 76a66253 target-ppc/op.c

b/target-ppc/op.c
1 1
/*
2 2
 *  PowerPC emulation micro-operations for qemu.
3 3
 * 
4
 *  Copyright (c) 2003-2005 Jocelyn Mayer
4
 *  Copyright (c) 2003-2007 Jocelyn Mayer
5 5
 *
6 6
 * This library is free software; you can redistribute it and/or
7 7
 * modify it under the terms of the GNU Lesser General Public
......
22 22

  
23 23
#include "config.h"
24 24
#include "exec.h"
25
#include "op_helper.h"
25 26

  
27
/* XXX: this is to be suppressed */
26 28
#define regs (env)
27 29
#define Ts0 (int32_t)T0
28 30
#define Ts1 (int32_t)T1
......
32 34
#define FT1 (env->ft1)
33 35
#define FT2 (env->ft2)
34 36

  
35
#define PPC_OP(name) void glue(op_, name)(void)
37
/* XXX: this is to be suppressed... */
38
#define PPC_OP(name) void OPPROTO glue(op_, name)(void)
36 39

  
37 40
#define REG 0
38 41
#include "op_template.h"
......
134 137
/* set_Rc0 */
135 138
PPC_OP(set_Rc0)
136 139
{
137
    uint32_t tmp;
138

  
139
    if (Ts0 < 0) {
140
        tmp = 0x08;
141
    } else if (Ts0 > 0) {
142
        tmp = 0x04;
143
    } else {
144
        tmp = 0x02;
145
    }
146
    tmp |= xer_ov;
147
    env->crf[0] = tmp;
148
    RETURN();
149
}
150

  
151
/* reset_Rc0 */
152
PPC_OP(reset_Rc0)
153
{
154
    env->crf[0] = 0x02 | xer_ov;
155
    RETURN();
156
}
157

  
158
/* set_Rc0_1 */
159
PPC_OP(set_Rc0_1)
160
{
161
    env->crf[0] = 0x04 | xer_ov;
140
    env->crf[0] = T0 | xer_ov;
162 141
    RETURN();
163 142
}
164 143

  
......
170 149
}
171 150

  
172 151
/* Constants load */
152
void OPPROTO op_reset_T0 (void)
153
{
154
    T0 = 0;
155
    RETURN();
156
}
157

  
173 158
PPC_OP(set_T0)
174 159
{
175 160
    T0 = PARAM(1);
......
182 167
    RETURN();
183 168
}
184 169

  
170
#if 0 // unused
185 171
PPC_OP(set_T2)
186 172
{
187 173
    T2 = PARAM(1);
188 174
    RETURN();
189 175
}
176
#endif
190 177

  
191
/* Generate exceptions */
192
PPC_OP(raise_exception_err)
178
void OPPROTO op_move_T1_T0 (void)
193 179
{
194
    do_raise_exception_err(PARAM(1), PARAM(2));
180
    T1 = T0;
181
    RETURN();
195 182
}
196 183

  
197
PPC_OP(raise_exception)
184
/* Generate exceptions */
185
PPC_OP(raise_exception_err)
198 186
{
199
    do_raise_exception(PARAM(1));
187
    do_raise_exception_err(PARAM(1), PARAM(2));
200 188
}
201 189

  
202 190
PPC_OP(update_nip)
203 191
{
204 192
    env->nip = PARAM(1);
193
    RETURN();
205 194
}
206 195

  
207 196
PPC_OP(debug)
......
209 198
    do_raise_exception(EXCP_DEBUG);
210 199
}
211 200

  
212
/* Segment registers load and store with immediate index */
213
PPC_OP(load_srin)
214
{
215
    T0 = regs->sr[T1 >> 28];
216
    RETURN();
217
}
218 201

  
219
PPC_OP(store_srin)
202
PPC_OP(exit_tb)
220 203
{
221
    do_store_sr(env, ((uint32_t)T1 >> 28), T0);
222
    RETURN();
204
    EXIT_TB();
223 205
}
224 206

  
225
PPC_OP(load_sdr1)
207
/* Load/store special registers */
208
PPC_OP(load_cr)
226 209
{
227
    T0 = regs->sdr1;
210
    do_load_cr();
228 211
    RETURN();
229 212
}
230 213

  
231
PPC_OP(store_sdr1)
214
PPC_OP(store_cr)
232 215
{
233
    do_store_sdr1(env, T0);
216
    do_store_cr(PARAM(1));
234 217
    RETURN();
235 218
}
236 219

  
237
PPC_OP(exit_tb)
220
void OPPROTO op_load_cro (void)
238 221
{
239
    EXIT_TB();
240
}
241

  
242
/* Load/store special registers */
243
PPC_OP(load_cr)
244
{
245
    T0 = do_load_cr(env);
222
    T0 = env->crf[PARAM1];
246 223
    RETURN();
247 224
}
248 225

  
249
PPC_OP(store_cr)
226
void OPPROTO op_store_cro (void)
250 227
{
251
    do_store_cr(env, T0, PARAM(1));
228
    env->crf[PARAM1] = T0;
252 229
    RETURN();
253 230
}
254 231

  
......
272 249
    RETURN();
273 250
}
274 251

  
252
void OPPROTO op_store_xer_bc (void)
253
{
254
    xer_bc = T0;
255
    RETURN();
256
}
257

  
275 258
PPC_OP(load_xer)
276 259
{
277
    T0 = do_load_xer(env);
260
    do_load_xer();
278 261
    RETURN();
279 262
}
280 263

  
281 264
PPC_OP(store_xer)
282 265
{
283
    do_store_xer(env, T0);
266
    do_store_xer();
267
    RETURN();
268
}
269

  
270
#if !defined(CONFIG_USER_ONLY)
271
/* Segment registers load and store */
272
PPC_OP(load_sr)
273
{
274
    T0 = regs->sr[T1];
275
    RETURN();
276
}
277

  
278
PPC_OP(store_sr)
279
{
280
    do_store_sr(env, T1, T0);
281
    RETURN();
282
}
283

  
284
PPC_OP(load_sdr1)
285
{
286
    T0 = regs->sdr1;
287
    RETURN();
288
}
289

  
290
PPC_OP(store_sdr1)
291
{
292
    do_store_sdr1(env, T0);
284 293
    RETURN();
285 294
}
286 295

  
......
295 304
    do_store_msr(env, T0);
296 305
    RETURN();
297 306
}
307
#endif
298 308

  
299 309
/* SPR */
300 310
PPC_OP(load_spr)
......
345 355
    RETURN();
346 356
}
347 357

  
358
#if !defined(CONFIG_USER_ONLY)
348 359
PPC_OP(store_tbl)
349 360
{
350 361
    cpu_ppc_store_tbl(regs, T0);
......
360 371
PPC_OP(load_decr)
361 372
{
362 373
    T0 = cpu_ppc_load_decr(regs);
363
    }
374
    RETURN();
375
}
364 376

  
365 377
PPC_OP(store_decr)
366 378
{
......
371 383
PPC_OP(load_ibat)
372 384
{
373 385
    T0 = regs->IBAT[PARAM(1)][PARAM(2)];
386
    RETURN();
374 387
}
375 388

  
376
void op_store_ibatu (void)
389
void OPPROTO op_store_ibatu (void)
377 390
{
378 391
    do_store_ibatu(env, PARAM1, T0);
379 392
    RETURN();
380 393
}
381 394

  
382
void op_store_ibatl (void)
395
void OPPROTO op_store_ibatl (void)
383 396
{
384 397
#if 1
385 398
    env->IBAT[1][PARAM1] = T0;
......
392 405
PPC_OP(load_dbat)
393 406
{
394 407
    T0 = regs->DBAT[PARAM(1)][PARAM(2)];
408
    RETURN();
395 409
}
396 410

  
397
void op_store_dbatu (void)
411
void OPPROTO op_store_dbatu (void)
398 412
{
399 413
    do_store_dbatu(env, PARAM1, T0);
400 414
    RETURN();
401 415
}
402 416

  
403
void op_store_dbatl (void)
417
void OPPROTO op_store_dbatl (void)
404 418
{
405 419
#if 1
406 420
    env->DBAT[1][PARAM1] = T0;
......
409 423
#endif
410 424
    RETURN();
411 425
}
426
#endif /* !defined(CONFIG_USER_ONLY) */
412 427

  
413 428
/* FPSCR */
414 429
PPC_OP(load_fpscr)
415 430
{
416
    FT0 = do_load_fpscr(env);
431
    do_load_fpscr();
417 432
    RETURN();
418 433
}
419 434

  
420 435
PPC_OP(store_fpscr)
421 436
{
422
    do_store_fpscr(env, FT0, PARAM1);
437
    do_store_fpscr(PARAM1);
423 438
    RETURN();
424 439
}
425 440

  
......
454 469
PPC_OP(setlr)
455 470
{
456 471
    regs->lr = PARAM1;
472
    RETURN();
457 473
}
458 474

  
459 475
PPC_OP(goto_tb0)
......
469 485
PPC_OP(b_T1)
470 486
{
471 487
    regs->nip = T1 & ~3;
488
    RETURN();
472 489
}
473 490

  
474 491
PPC_OP(jz_T0)
......
491 508
PPC_OP(movl_T1_ctr)
492 509
{
493 510
    T1 = regs->ctr;
511
    RETURN();
494 512
}
495 513

  
496 514
PPC_OP(movl_T1_lr)
497 515
{
498 516
    T1 = regs->lr;
517
    RETURN();
499 518
}
500 519

  
501 520
/* tests with result in T0 */
......
503 522
PPC_OP(test_ctr)
504 523
{
505 524
    T0 = regs->ctr;
525
    RETURN();
506 526
}
507 527

  
508 528
PPC_OP(test_ctr_true)
509 529
{
510 530
    T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0);
531
    RETURN();
511 532
}
512 533

  
513 534
PPC_OP(test_ctr_false)
514 535
{
515 536
    T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0);
537
    RETURN();
516 538
}
517 539

  
518 540
PPC_OP(test_ctrz)
519 541
{
520 542
    T0 = (regs->ctr == 0);
543
    RETURN();
521 544
}
522 545

  
523 546
PPC_OP(test_ctrz_true)
524 547
{
525 548
    T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0);
549
    RETURN();
526 550
}
527 551

  
528 552
PPC_OP(test_ctrz_false)
529 553
{
530 554
    T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0);
555
    RETURN();
531 556
}
532 557

  
533 558
PPC_OP(test_true)
534 559
{
535 560
    T0 = (T0 & PARAM(1));
561
    RETURN();
536 562
}
537 563

  
538 564
PPC_OP(test_false)
539 565
{
540 566
    T0 = ((T0 & PARAM(1)) == 0);
567
    RETURN();
541 568
}
542 569

  
543 570
/* CTR maintenance */
......
555 582
    RETURN();
556 583
}
557 584

  
558
void do_addo (void);
559
void op_addo (void)
585
void OPPROTO op_addo (void)
560 586
{
561 587
    do_addo();
562 588
    RETURN();
......
575 601
    RETURN();
576 602
}
577 603

  
578
void do_addco (void);
579
void op_addco (void)
604
void OPPROTO op_addco (void)
580 605
{
581 606
    do_addco();
582 607
    RETURN();
583 608
}
584 609

  
585 610
/* add extended */
586
void do_adde (void);
587
void op_adde (void)
611
void OPPROTO op_adde (void)
588 612
{
589 613
    do_adde();
614
    RETURN();
590 615
}
591 616

  
592
void do_addeo (void);
593 617
PPC_OP(addeo)
594 618
{
595 619
    do_addeo();
......
626 650
    RETURN();
627 651
}
628 652

  
629
void do_addmeo (void);
630
void op_addmeo (void)
653
void OPPROTO op_addmeo (void)
631 654
{
632 655
    do_addmeo();
633 656
    RETURN();
......
646 669
    RETURN();
647 670
}
648 671

  
649
void do_addzeo (void);
650
void op_addzeo (void)
672
void OPPROTO op_addzeo (void)
651 673
{
652 674
    do_addzeo();
653 675
    RETURN();
......
664 686
    RETURN();
665 687
}
666 688

  
667
void do_divwo (void);
668
void op_divwo (void)
689
void OPPROTO op_divwo (void)
669 690
{
670 691
    do_divwo();
671 692
    RETURN();
......
682 703
    RETURN();
683 704
}
684 705

  
685
void do_divwuo (void);
686
void op_divwuo (void)
706
void OPPROTO op_divwuo (void)
687 707
{
688 708
    do_divwuo();
689 709
    RETURN();
......
717 737
    RETURN();
718 738
}
719 739

  
720
void do_mullwo (void);
721
void op_mullwo (void)
740
void OPPROTO op_mullwo (void)
722 741
{
723 742
    do_mullwo();
724 743
    RETURN();
......
733 752
    RETURN();
734 753
}
735 754

  
736
void do_nego (void);
737
void op_nego (void)
755
void OPPROTO op_nego (void)
738 756
{
739 757
    do_nego();
740 758
    RETURN();
......
747 765
    RETURN();
748 766
}
749 767

  
750
void do_subfo (void);
751
void op_subfo (void)
768
void OPPROTO op_subfo (void)
752 769
{
753 770
    do_subfo();
754 771
    RETURN();
......
766 783
    RETURN();
767 784
}
768 785

  
769
void do_subfco (void);
770
void op_subfco (void)
786
void OPPROTO op_subfco (void)
771 787
{
772 788
    do_subfco();
773 789
    RETURN();
774 790
}
775 791

  
776 792
/* substract from extended */
777
void do_subfe (void);
778
void op_subfe (void)
793
void OPPROTO op_subfe (void)
779 794
{
780 795
    do_subfe();
781 796
    RETURN();
782 797
}
783 798

  
784
void do_subfeo (void);
785 799
PPC_OP(subfeo)
786 800
{
787 801
    do_subfeo();
......
810 824
    RETURN();
811 825
}
812 826

  
813
void do_subfmeo (void);
814
void op_subfmeo (void)
827
void OPPROTO op_subfmeo (void)
815 828
{
816 829
    do_subfmeo();
817 830
    RETURN();
......
830 843
    RETURN();
831 844
}
832 845

  
833
void do_subfzeo (void);
834
void op_subfzeo (void)
846
void OPPROTO op_subfzeo (void)
835 847
{
836 848
    do_subfzeo();
837 849
    RETURN();
......
906 918
}
907 919

  
908 920
/* andi. */
909
PPC_OP(andi_)
921
void OPPROTO op_andi_T0 (void)
910 922
{
911 923
    T0 &= PARAM(1);
912 924
    RETURN();
913 925
}
914 926

  
927
void OPPROTO op_andi_T1 (void)
928
{
929
    T1 &= PARAM1;
930
    RETURN();
931
}
932

  
915 933
/* count leading zero */
916
PPC_OP(cntlzw)
934
void OPPROTO op_cntlzw (void)
917 935
{
918
    T1 = T0;
919
    for (T0 = 32; T1 > 0; T0--)
920
        T1 = T1 >> 1;
936
    int cnt;
937

  
938
    cnt = 0;
939
    if (!(T0 & 0xFFFF0000UL)) {
940
        cnt += 16;
941
        T0 <<= 16;
942
    }
943
    if (!(T0 & 0xFF000000UL)) {
944
        cnt += 8;
945
        T0 <<= 8;
946
    }
947
    if (!(T0 & 0xF0000000UL)) {
948
        cnt += 4;
949
        T0 <<= 4;
950
    }
951
    if (!(T0 & 0xC0000000UL)) {
952
        cnt += 2;
953
        T0 <<= 2;
954
    }
955
    if (!(T0 & 0x80000000UL)) {
956
        cnt++;
957
        T0 <<= 1;
958
    }
959
    if (!(T0 & 0x80000000UL)) {
960
        cnt++;
961
    }
962
    T0 = cnt;
921 963
    RETURN();
922 964
}
923 965

  
......
992 1034
}
993 1035

  
994 1036
/***                             Integer rotate                            ***/
995
/* rotate left word immediate then mask insert */
996
PPC_OP(rlwimi)
997
{
998
    T0 = (rotl(T0, PARAM(1)) & PARAM(2)) | (T1 & PARAM(3));
999
    RETURN();
1000
}
1001

  
1002
/* rotate left immediate then and with mask insert */
1003
PPC_OP(rotlwi)
1004
{
1005
    T0 = rotl(T0, PARAM(1));
1006
    RETURN();
1007
}
1008

  
1009
PPC_OP(slwi)
1010
{
1011
    T0 = T0 << PARAM(1);
1012
    RETURN();
1013
}
1014

  
1015
PPC_OP(srwi)
1037
void OPPROTO op_rotl32_T0_T1 (void)
1016 1038
{
1017
    T0 = T0 >> PARAM(1);
1039
    T0 = rotl32(T0, T1 & 0x1F);
1018 1040
    RETURN();
1019 1041
}
1020 1042

  
1021
/* rotate left word then and with mask insert */
1022
PPC_OP(rlwinm)
1043
void OPPROTO op_rotli32_T0 (void)
1023 1044
{
1024
    T0 = rotl(T0, PARAM(1)) & PARAM(2);
1025
    RETURN();
1026
}
1027

  
1028
PPC_OP(rotl)
1029
{
1030
    T0 = rotl(T0, T1);
1031
    RETURN();
1032
}
1033

  
1034
PPC_OP(rlwnm)
1035
{
1036
    T0 = rotl(T0, T1) & PARAM(1);
1045
    T0 = rotl32(T0, PARAM1);
1037 1046
    RETURN();
1038 1047
}
1039 1048

  
......
1050 1059
}
1051 1060

  
1052 1061
/* shift right algebraic word */
1053
void op_sraw (void)
1062
void OPPROTO op_sraw (void)
1054 1063
{
1055 1064
    do_sraw();
1056 1065
    RETURN();
......
1080 1089
    RETURN();
1081 1090
}
1082 1091

  
1092
void OPPROTO op_sl_T0_T1 (void)
1093
{
1094
    T0 = T0 << T1;
1095
    RETURN();
1096
}
1097

  
1098
void OPPROTO op_sli_T0 (void)
1099
{
1100
    T0 = T0 << PARAM1;
1101
    RETURN();
1102
}
1103

  
1104
void OPPROTO op_srl_T0_T1 (void)
1105
{
1106
    T0 = T0 >> T1;
1107
    RETURN();
1108
}
1109

  
1110
void OPPROTO op_srli_T0 (void)
1111
{
1112
    T0 = T0 >> PARAM1;
1113
    RETURN();
1114
}
1115

  
1116
void OPPROTO op_srli_T1 (void)
1117
{
1118
    T1 = T1 >> PARAM1;
1119
    RETURN();
1120
}
1121

  
1083 1122
/***                       Floating-Point arithmetic                       ***/
1084 1123
/* fadd - fadd. */
1085 1124
PPC_OP(fadd)
1086 1125
{
1087
    FT0 += FT1;
1126
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1088 1127
    RETURN();
1089 1128
}
1090 1129

  
1091 1130
/* fsub - fsub. */
1092 1131
PPC_OP(fsub)
1093 1132
{
1094
    FT0 -= FT1;
1133
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1095 1134
    RETURN();
1096 1135
}
1097 1136

  
1098 1137
/* fmul - fmul. */
1099 1138
PPC_OP(fmul)
1100 1139
{
1101
    FT0 *= FT1;
1140
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1102 1141
    RETURN();
1103 1142
}
1104 1143

  
......
1141 1180
/* fmadd - fmadd. */
1142 1181
PPC_OP(fmadd)
1143 1182
{
1144
    FT0 = (FT0 * FT1) + FT2;
1183
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1184
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1145 1185
    RETURN();
1146 1186
}
1147 1187

  
1148 1188
/* fmsub - fmsub. */
1149 1189
PPC_OP(fmsub)
1150 1190
{
1151
    FT0 = (FT0 * FT1) - FT2;
1191
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1192
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1152 1193
    RETURN();
1153 1194
}
1154 1195

  
......
1170 1211
/* frsp - frsp. */
1171 1212
PPC_OP(frsp)
1172 1213
{
1173
    FT0 = (float)FT0;
1214
    FT0 = float64_to_float32(FT0, &env->fp_status);
1174 1215
    RETURN();
1175 1216
}
1176 1217

  
......
1188 1229
    RETURN();
1189 1230
}
1190 1231

  
1191

  
1192 1232
/***                         Floating-Point compare                        ***/
1193 1233
/* fcmpu */
1194 1234
PPC_OP(fcmpu)
......
1229 1269

  
1230 1270
/* Load and store */
1231 1271
#define MEMSUFFIX _raw
1272
#include "op_helper.h"
1232 1273
#include "op_mem.h"
1233 1274
#if !defined(CONFIG_USER_ONLY)
1234 1275
#define MEMSUFFIX _user
1276
#include "op_helper.h"
1235 1277
#include "op_mem.h"
1236

  
1237 1278
#define MEMSUFFIX _kernel
1279
#include "op_helper.h"
1238 1280
#include "op_mem.h"
1239 1281
#endif
1240 1282

  
......
1247 1289
}
1248 1290

  
1249 1291
/* Return from interrupt */
1250
void do_rfi (void);
1251
void op_rfi (void)
1292
#if !defined(CONFIG_USER_ONLY)
1293
void OPPROTO op_rfi (void)
1252 1294
{
1253 1295
    do_rfi();
1254 1296
    RETURN();
1255 1297
}
1298
#endif
1256 1299

  
1257 1300
/* Trap word */
1258
void do_tw (uint32_t cmp, int flags);
1259
void op_tw (void)
1260
{
1261
    do_tw(T1, PARAM(1));
1262
    RETURN();
1263
}
1264

  
1265
void op_twi (void)
1301
void OPPROTO op_tw (void)
1266 1302
{
1267
    do_tw(PARAM(1), PARAM(2));
1303
    do_tw(PARAM1);
1268 1304
    RETURN();
1269 1305
}
1270 1306

  
......
1275 1311
    RETURN();
1276 1312
}
1277 1313

  
1314
#if !defined(CONFIG_USER_ONLY)
1278 1315
/* tlbia */
1279 1316
PPC_OP(tlbia)
1280 1317
{
......
1288 1325
    do_tlbie();
1289 1326
    RETURN();
1290 1327
}
1328
#endif
1291 1329

  
1292
void op_store_pir (void)
1330
/* PowerPC 602/603/755 software TLB load instructions */
1331
#if !defined(CONFIG_USER_ONLY)
1332
void OPPROTO op_6xx_tlbld (void)
1333
{
1334
    do_load_6xx_tlb(0);
1335
    RETURN();
1336
}
1337

  
1338
void OPPROTO op_6xx_tlbli (void)
1339
{
1340
    do_load_6xx_tlb(1);
1341
    RETURN();
1342
}
1343
#endif
1344

  
1345
/* 601 specific */
1346
uint32_t cpu_ppc601_load_rtcl (CPUState *env);
1347
void OPPROTO op_load_601_rtcl (void)
1348
{
1349
    T0 = cpu_ppc601_load_rtcl(env);
1350
    RETURN();
1351
}
1352

  
1353
uint32_t cpu_ppc601_load_rtcu (CPUState *env);
1354
void OPPROTO op_load_601_rtcu (void)
1355
{
1356
    T0 = cpu_ppc601_load_rtcu(env);
1357
    RETURN();
1358
}
1359

  
1360
#if !defined(CONFIG_USER_ONLY)
1361
void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value);
1362
void OPPROTO op_store_601_rtcl (void)
1363
{
1364
    cpu_ppc601_store_rtcl(env, T0);
1365
    RETURN();
1366
}
1367

  
1368
void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value);
1369
void OPPROTO op_store_601_rtcu (void)
1370
{
1371
    cpu_ppc601_store_rtcu(env, T0);
1372
    RETURN();
1373
}
1374

  
1375
void OPPROTO op_load_601_bat (void)
1376
{
1377
    T0 = env->IBAT[PARAM1][PARAM2];
1378
    RETURN();
1379
}
1380
#endif /* !defined(CONFIG_USER_ONLY) */
1381

  
1382
/* 601 unified BATs store.
1383
 * To avoid using specific MMU code for 601, we store BATs in
1384
 * IBAT and DBAT simultaneously, then emulate unified BATs.
1385
 */
1386
#if !defined(CONFIG_USER_ONLY)
1387
void OPPROTO op_store_601_batl (void)
1388
{
1389
    int nr = PARAM1;
1390

  
1391
    env->IBAT[1][nr] = T0;
1392
    env->DBAT[1][nr] = T0;
1393
    RETURN();
1394
}
1395

  
1396
void OPPROTO op_store_601_batu (void)
1397
{
1398
    do_store_601_batu(PARAM1);
1399
    RETURN();
1400
}
1401
#endif /* !defined(CONFIG_USER_ONLY) */
1402

  
1403
/* PowerPC 601 specific instructions (POWER bridge) */
1404
/* XXX: those micro-ops need tests ! */
1405
void OPPROTO op_POWER_abs (void)
1406
{
1407
    if (T0 == INT32_MIN)
1408
        T0 = INT32_MAX;
1409
    else if (T0 < 0)
1410
        T0 = -T0;
1411
    RETURN();
1412
}
1413

  
1414
void OPPROTO op_POWER_abso (void)
1415
{
1416
    do_POWER_abso();
1417
    RETURN();
1418
}
1419

  
1420
void OPPROTO op_POWER_clcs (void)
1421
{
1422
    do_POWER_clcs();
1423
    RETURN();
1424
}
1425

  
1426
void OPPROTO op_POWER_div (void)
1427
{
1428
    do_POWER_div();
1429
    RETURN();
1430
}
1431

  
1432
void OPPROTO op_POWER_divo (void)
1433
{
1434
    do_POWER_divo();
1435
    RETURN();
1436
}
1437

  
1438
void OPPROTO op_POWER_divs (void)
1439
{
1440
    do_POWER_divs();
1441
    RETURN();
1442
}
1443

  
1444
void OPPROTO op_POWER_divso (void)
1445
{
1446
    do_POWER_divso();
1447
    RETURN();
1448
}
1449

  
1450
void OPPROTO op_POWER_doz (void)
1451
{
1452
    if (Ts1 > Ts0)
1453
        T0 = T1 - T0;
1454
    else
1455
        T0 = 0;
1456
    RETURN();
1457
}
1458

  
1459
void OPPROTO op_POWER_dozo (void)
1460
{
1461
    do_POWER_dozo();
1462
    RETURN();
1463
}
1464

  
1465
void OPPROTO op_load_xer_cmp (void)
1466
{
1467
    T2 = xer_cmp;
1468
    RETURN();
1469
}
1470

  
1471
void OPPROTO op_POWER_maskg (void)
1472
{
1473
    do_POWER_maskg();
1474
    RETURN();
1475
}
1476

  
1477
void OPPROTO op_POWER_maskir (void)
1478
{
1479
    T0 = (T0 & ~T2) | (T1 & T2);
1480
    RETURN();
1481
}
1482

  
1483
void OPPROTO op_POWER_mul (void)
1484
{
1485
    uint64_t tmp;
1486

  
1487
    tmp = (uint64_t)T0 * (uint64_t)T1;
1488
    env->spr[SPR_MQ] = tmp >> 32;
1489
    T0 = tmp;
1490
    RETURN();
1491
}
1492

  
1493
void OPPROTO op_POWER_mulo (void)
1494
{
1495
    do_POWER_mulo();
1496
    RETURN();
1497
}
1498

  
1499
void OPPROTO op_POWER_nabs (void)
1500
{
1501
    if (T0 > 0)
1502
        T0 = -T0;
1503
    RETURN();
1504
}
1505

  
1506
void OPPROTO op_POWER_nabso (void)
1507
{
1508
    /* nabs never overflows */
1509
    if (T0 > 0)
1510
        T0 = -T0;
1511
    xer_ov = 0;
1512
    RETURN();
1513
}
1514

  
1515
/* XXX: factorise POWER rotates... */
1516
void OPPROTO op_POWER_rlmi (void)
1517
{
1518
    T0 = rotl32(T0, T2) & PARAM1;
1519
    T0 |= T1 & PARAM2;
1520
    RETURN();
1521
}
1522

  
1523
void OPPROTO op_POWER_rrib (void)
1524
{
1525
    T2 &= 0x1FUL;
1526
    T0 = rotl32(T0 & INT32_MIN, T2);
1527
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
1528
    RETURN();
1529
}
1530

  
1531
void OPPROTO op_POWER_sle (void)
1532
{
1533
    T1 &= 0x1FUL;
1534
    env->spr[SPR_MQ] = rotl32(T0, T1);
1535
    T0 = T0 << T1;
1536
    RETURN();
1537
}
1538

  
1539
void OPPROTO op_POWER_sleq (void)
1540
{
1541
    uint32_t tmp = env->spr[SPR_MQ];
1542

  
1543
    T1 &= 0x1FUL;
1544
    env->spr[SPR_MQ] = rotl32(T0, T1);
1545
    T0 = T0 << T1;
1546
    T0 |= tmp >> (32 - T1);
1547
    RETURN();
1548
}
1549

  
1550
void OPPROTO op_POWER_sllq (void)
1551
{
1552
    uint32_t msk = -1;
1553

  
1554
    msk = msk << (T1 & 0x1FUL);
1555
    if (T1 & 0x20UL)
1556
        msk = ~msk;
1557
    T1 &= 0x1FUL;
1558
    T0 = (T0 << T1) & msk;
1559
    T0 |= env->spr[SPR_MQ] & ~msk;
1560
    RETURN();
1561
}
1562

  
1563
void OPPROTO op_POWER_slq (void)
1564
{
1565
    uint32_t msk = -1, tmp;
1566

  
1567
    msk = msk << (T1 & 0x1FUL);
1568
    if (T1 & 0x20UL)
1569
        msk = ~msk;
1570
    T1 &= 0x1FUL;
1571
    tmp = rotl32(T0, T1);
1572
    T0 = tmp & msk;
1573
    env->spr[SPR_MQ] = tmp;
1574
    RETURN();
1575
}
1576

  
1577
void OPPROTO op_POWER_sraq (void)
1578
{
1579
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
1580
    if (T1 & 0x20UL)
1581
        T0 = -1L;
1582
    else
1583
        T0 = Ts0 >> T1;
1584
    RETURN();
1585
}
1586

  
1587
void OPPROTO op_POWER_sre (void)
1588
{
1589
    T1 &= 0x1FUL;
1590
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
1591
    T0 = Ts0 >> T1;
1592
    RETURN();
1593
}
1594

  
1595
void OPPROTO op_POWER_srea (void)
1596
{
1597
    T1 &= 0x1FUL;
1598
    env->spr[SPR_MQ] = T0 >> T1;
1599
    T0 = Ts0 >> T1;
1600
    RETURN();
1601
}
1602

  
1603
void OPPROTO op_POWER_sreq (void)
1604
{
1605
    uint32_t tmp;
1606
    int32_t msk;
1607

  
1608
    T1 &= 0x1FUL;
1609
    msk = INT32_MIN >> T1;
1610
    tmp = env->spr[SPR_MQ];
1611
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
1612
    T0 = T0 >> T1;
1613
    T0 |= tmp & msk;
1614
    RETURN();
1615
}
1616

  
1617
void OPPROTO op_POWER_srlq (void)
1618
{
1619
    uint32_t tmp;
1620
    int32_t msk;
1621

  
1622
    msk = INT32_MIN >> (T1 & 0x1FUL);
1623
    if (T1 & 0x20UL)
1624
        msk = ~msk;
1625
    T1 &= 0x1FUL;
1626
    tmp = env->spr[SPR_MQ];
1627
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
1628
    T0 = T0 >> T1;
1629
    T0 &= msk;
1630
    T0 |= tmp & ~msk;
1631
    RETURN();
1632
}
1633

  
1634
void OPPROTO op_POWER_srq (void)
1635
{
1636
    T1 &= 0x1FUL;
1637
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
1638
    T0 = T0 >> T1;
1639
    RETURN();
1640
}
1641

  
1642
/* POWER instructions not implemented in PowerPC 601 */
1643
#if !defined(CONFIG_USER_ONLY)
1644
void OPPROTO op_POWER_mfsri (void)
1645
{
1646
    T1 = T0 >> 28;
1647
    T0 = env->sr[T1];
1648
    RETURN();
1649
}
1650

  
1651
void OPPROTO op_POWER_rac (void)
1652
{
1653
    do_POWER_rac();
1654
    RETURN();
1655
}
1656

  
1657
void OPPROTO op_POWER_rfsvc (void)
1658
{
1659
    do_POWER_rfsvc();
1660
    RETURN();
1661
}
1662
#endif
1663

  
1664
/* PowerPC 602 specific instruction */
1665
#if !defined(CONFIG_USER_ONLY)
1666
void OPPROTO op_602_mfrom (void)
1667
{
1668
    do_op_602_mfrom();
1669
    RETURN();
1670
}
1671
#endif
1672

  
1673
/* PowerPC 4xx specific micro-ops */
1674
void OPPROTO op_405_add_T0_T2 (void)
1675
{
1676
    T0 = (int32_t)T0 + (int32_t)T2;
1677
    RETURN();
1678
}
1679

  
1680
void OPPROTO op_405_mulchw (void)
1681
{
1682
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
1683
    RETURN();
1684
}
1685

  
1686
void OPPROTO op_405_mulchwu (void)
1687
{
1688
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
1689
    RETURN();
1690
}
1691

  
1692
void OPPROTO op_405_mulhhw (void)
1693
{
1694
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
1695
    RETURN();
1696
}
1697

  
1698
void OPPROTO op_405_mulhhwu (void)
1699
{
1700
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
1701
    RETURN();
1702
}
1703

  
1704
void OPPROTO op_405_mullhw (void)
1705
{
1706
    T0 = ((int16_t)T0) * ((int16_t)T1);
1707
    RETURN();
1708
}
1709

  
1710
void OPPROTO op_405_mullhwu (void)
1711
{
1712
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
1713
    RETURN();
1714
}
1715

  
1716
void OPPROTO op_405_check_ov (void)
1717
{
1718
    do_405_check_ov();
1719
    RETURN();
1720
}
1721

  
1722
void OPPROTO op_405_check_sat (void)
1723
{
1724
    do_405_check_sat();
1725
    RETURN();
1726
}
1727

  
1728
void OPPROTO op_405_check_ovu (void)
1729
{
1730
    if (likely(T0 >= T2)) {
1731
        xer_ov = 0;
1732
    } else {
1733
        xer_ov = 1;
1734
        xer_so = 1;
1735
    }
1736
    RETURN();
1737
}
1738

  
1739
void OPPROTO op_405_check_satu (void)
1740
{
1741
    if (unlikely(T0 < T2)) {
1742
        /* Saturate result */
1743
        T0 = -1;
1744
    }
1745
    RETURN();
1746
}
1747

  
1748
#if !defined(CONFIG_USER_ONLY)
1749
void OPPROTO op_4xx_load_dcr (void)
1750
{
1751
    do_4xx_load_dcr(PARAM1);
1752
    RETURN();
1753
}
1754

  
1755
void OPPROTO op_4xx_store_dcr (void)
1756
{
1757
    do_4xx_store_dcr(PARAM1);
1758
    RETURN();
1759
}
1760

  
1761
/* Return from critical interrupt :
1762
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
1763
 */
1764
void OPPROTO op_4xx_rfci (void)
1765
{
1766
    do_4xx_rfci();
1767
    RETURN();
1768
}
1769

  
1770
void OPPROTO op_4xx_wrte (void)
1771
{
1772
    msr_ee = T0 >> 16;
1773
    RETURN();
1774
}
1775

  
1776
void OPPROTO op_4xx_tlbre_lo (void)
1777
{
1778
    do_4xx_tlbre_lo();
1779
    RETURN();
1780
}
1781

  
1782
void OPPROTO op_4xx_tlbre_hi (void)
1783
{
1784
    do_4xx_tlbre_hi();
1785
    RETURN();
1786
}
1787

  
1788
void OPPROTO op_4xx_tlbsx (void)
1789
{
1790
    do_4xx_tlbsx();
1791
    RETURN();
1792
}
1793

  
1794
void OPPROTO op_4xx_tlbsx_ (void)
1795
{
1796
    do_4xx_tlbsx_();
1797
    RETURN();
1798
}
1799

  
1800
void OPPROTO op_4xx_tlbwe_lo (void)
1801
{
1802
    do_4xx_tlbwe_lo();
1803
    RETURN();
1804
}
1805

  
1806
void OPPROTO op_4xx_tlbwe_hi (void)
1807
{
1808
    do_4xx_tlbwe_hi();
1809
    RETURN();
1810
}
1811
#endif
1812

  
1813
/* SPR micro-ops */
1814
/* 440 specific */
1815
void OPPROTO op_440_dlmzb (void)
1816
{
1817
    do_440_dlmzb();
1818
    RETURN();
1819
}
1820

  
1821
void OPPROTO op_440_dlmzb_update_Rc (void)
1822
{
1823
    if (T0 == 8)
1824
        T0 = 0x2;
1825
    else if (T0 < 4)
1826
        T0 = 0x4;
1827
    else
1828
        T0 = 0x8;
1829
    RETURN();
1830
}
1831

  
1832
#if !defined(CONFIG_USER_ONLY)
1833
void OPPROTO op_store_pir (void)
1293 1834
{
1294 1835
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
1295 1836
    RETURN();
1296 1837
}
1838

  
1839
void OPPROTO op_load_403_pb (void)
1840
{
1841
    do_load_403_pb(PARAM1);
1842
    RETURN();
1843
}
1844

  
1845
void OPPROTO op_store_403_pb (void)
1846
{
1847
    do_store_403_pb(PARAM1);
1848
    RETURN();
1849
}
1850

  
1851
target_ulong load_40x_pit (CPUState *env);
1852
void OPPROTO op_load_40x_pit (void)
1853
{
1854
    T0 = load_40x_pit(env);
1855
    RETURN();
1856
}
1857

  
1858
void store_40x_pit (CPUState *env, target_ulong val);
1859
void OPPROTO op_store_40x_pit (void)
1860
{
1861
    store_40x_pit(env, T0);
1862
    RETURN();
1863
}
1864

  
1865
void store_booke_tcr (CPUState *env, target_ulong val);
1866
void OPPROTO op_store_booke_tcr (void)
1867
{
1868
    store_booke_tcr(env, T0);
1869
    RETURN();
1870
}
1871

  
1872
void store_booke_tsr (CPUState *env, target_ulong val);
1873
void OPPROTO op_store_booke_tsr (void)
1874
{
1875
    store_booke_tsr(env, T0);
1876
    RETURN();
1877
}
1878
#endif /* !defined(CONFIG_USER_ONLY) */

Also available in: Unified diff