Commit d9bce9d99f4656ae0b0127f7472db9067b8f84ab

Authored by j_mayer
1 parent 5fd46862

Make it safe to use 64 bits GPR and/or 64 bits host registers.

For "symetry", add 64 bits versions of all modified functions.
As a side effect, add a lot of code provision for PowerPC 64 support.
Move overflow and carry checks in common routines for simple cases.
Add isel and popcntb instructions from PowerPC 2.03 specification.
Remove remaining micro-operations helpers prototypes from op.c.
Fix XER_BC field to be 7 bits long.
Add power management support for PowerPC 603 & 604.
Fix compilation warnings.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2482 c046a42c-6fe2-441c-8c8c-71466251a162

Too many changes to show.

To preserve performance only 8 of 9 files are displayed.

target-ppc/cpu.h
@@ -365,6 +365,8 @@ enum { @@ -365,6 +365,8 @@ enum {
365 PPC_E500_VECTOR = 0x20000000, 365 PPC_E500_VECTOR = 0x20000000,
366 /* PowerPC 4xx dedicated instructions */ 366 /* PowerPC 4xx dedicated instructions */
367 PPC_4xx_COMMON = 0x40000000, 367 PPC_4xx_COMMON = 0x40000000,
  368 + /* PowerPC 2.03 specification extensions */
  369 + PPC_203 = 0x80000000,
368 }; 370 };
369 371
370 /* CPU run-time flags (MMU and exception model) */ 372 /* CPU run-time flags (MMU and exception model) */
@@ -385,6 +387,8 @@ enum { @@ -385,6 +387,8 @@ enum {
385 PPC_FLAGS_MMU_403 = 0x00000005, 387 PPC_FLAGS_MMU_403 = 0x00000005,
386 /* Freescale e500 MMU model */ 388 /* Freescale e500 MMU model */
387 PPC_FLAGS_MMU_e500 = 0x00000006, 389 PPC_FLAGS_MMU_e500 = 0x00000006,
  390 + /* BookE MMU model */
  391 + PPC_FLAGS_MMU_BOOKE = 0x00000007,
388 /* Exception model */ 392 /* Exception model */
389 PPC_FLAGS_EXCP_MASK = 0x000000F0, 393 PPC_FLAGS_EXCP_MASK = 0x000000F0,
390 /* Standard PowerPC exception model */ 394 /* Standard PowerPC exception model */
@@ -407,6 +411,8 @@ enum { @@ -407,6 +411,8 @@ enum {
407 PPC_FLAGS_EXCP_74xx = 0x00000080, 411 PPC_FLAGS_EXCP_74xx = 0x00000080,
408 /* PowerPC 970 exception model */ 412 /* PowerPC 970 exception model */
409 PPC_FLAGS_EXCP_970 = 0x00000090, 413 PPC_FLAGS_EXCP_970 = 0x00000090,
  414 + /* BookE exception model */
  415 + PPC_FLAGS_EXCP_BOOKE = 0x000000A0,
410 }; 416 };
411 417
412 #define PPC_MMU(env) (env->flags & PPC_FLAGS_MMU_MASK) 418 #define PPC_MMU(env) (env->flags & PPC_FLAGS_MMU_MASK)
@@ -437,11 +443,11 @@ enum { @@ -437,11 +443,11 @@ enum {
437 /* PowerPC 440 */ 443 /* PowerPC 440 */
438 #define PPC_INSNS_440 (PPC_INSNS_EMB | PPC_CACHE_OPT | PPC_BOOKE | \ 444 #define PPC_INSNS_440 (PPC_INSNS_EMB | PPC_CACHE_OPT | PPC_BOOKE | \
439 PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC) 445 PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC)
440 -#define PPC_FLAGS_440 (PPC_FLAGS_TODO) 446 +#define PPC_FLAGS_440 (PPC_FLAGS_MMU_BOOKE | PPC_FLAGS_EXCP_BOOKE)
441 /* Generic BookE PowerPC */ 447 /* Generic BookE PowerPC */
442 #define PPC_INSNS_BOOKE (PPC_INSNS_EMB | PPC_BOOKE | PPC_MEM_EIEIO | \ 448 #define PPC_INSNS_BOOKE (PPC_INSNS_EMB | PPC_BOOKE | PPC_MEM_EIEIO | \
443 PPC_FLOAT | PPC_FLOAT_OPT | PPC_CACHE_OPT) 449 PPC_FLOAT | PPC_FLOAT_OPT | PPC_CACHE_OPT)
444 -#define PPC_FLAGS_BOOKE (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x) 450 +#define PPC_FLAGS_BOOKE (PPC_FLAGS_MMU_BOOKE | PPC_FLAGS_EXCP_BOOKE)
445 /* e500 core */ 451 /* e500 core */
446 #define PPC_INSNS_E500 (PPC_INSNS_EMB | PPC_BOOKE | PPC_MEM_EIEIO | \ 452 #define PPC_INSNS_E500 (PPC_INSNS_EMB | PPC_BOOKE | PPC_MEM_EIEIO | \
447 PPC_CACHE_OPT | PPC_E500_VECTOR) 453 PPC_CACHE_OPT | PPC_E500_VECTOR)
@@ -502,7 +508,6 @@ typedef struct ppc_dcr_t ppc_dcr_t; @@ -502,7 +508,6 @@ typedef struct ppc_dcr_t ppc_dcr_t;
502 typedef struct ppc_avr_t ppc_avr_t; 508 typedef struct ppc_avr_t ppc_avr_t;
503 typedef struct ppc_tlb_t ppc_tlb_t; 509 typedef struct ppc_tlb_t ppc_tlb_t;
504 510
505 -  
506 /* SPR access micro-ops generations callbacks */ 511 /* SPR access micro-ops generations callbacks */
507 struct ppc_spr_t { 512 struct ppc_spr_t {
508 void (*uea_read)(void *opaque, int spr_num); 513 void (*uea_read)(void *opaque, int spr_num);
@@ -619,6 +624,8 @@ struct CPUPPCState { @@ -619,6 +624,8 @@ struct CPUPPCState {
619 */ 624 */
620 target_ulong t0, t1, t2; 625 target_ulong t0, t1, t2;
621 #endif 626 #endif
  627 + ppc_avr_t t0_avr, t1_avr, t2_avr;
  628 +
622 /* general purpose registers */ 629 /* general purpose registers */
623 ppc_gpr_t gpr[32]; 630 ppc_gpr_t gpr[32];
624 /* LR */ 631 /* LR */
@@ -674,6 +681,9 @@ struct CPUPPCState { @@ -674,6 +681,9 @@ struct CPUPPCState {
674 /* Altivec registers */ 681 /* Altivec registers */
675 ppc_avr_t avr[32]; 682 ppc_avr_t avr[32];
676 uint32_t vscr; 683 uint32_t vscr;
  684 + /* SPE registers */
  685 + ppc_gpr_t spe_acc;
  686 + uint32_t spe_fscr;
677 687
678 /* Internal devices resources */ 688 /* Internal devices resources */
679 /* Time base and decrementer */ 689 /* Time base and decrementer */
@@ -762,8 +772,10 @@ void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value); @@ -762,8 +772,10 @@ void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value);
762 void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value); 772 void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value);
763 target_ulong do_load_sdr1 (CPUPPCState *env); 773 target_ulong do_load_sdr1 (CPUPPCState *env);
764 void do_store_sdr1 (CPUPPCState *env, target_ulong value); 774 void do_store_sdr1 (CPUPPCState *env, target_ulong value);
765 -target_ulong do_load_asr (CPUPPCState *env);  
766 -void do_store_asr (CPUPPCState *env, target_ulong value); 775 +#if defined(TARGET_PPC64)
  776 +target_ulong ppc_load_asr (CPUPPCState *env);
  777 +void ppc_store_asr (CPUPPCState *env, target_ulong value);
  778 +#endif
767 target_ulong do_load_sr (CPUPPCState *env, int srnum); 779 target_ulong do_load_sr (CPUPPCState *env, int srnum);
768 void do_store_sr (CPUPPCState *env, int srnum, target_ulong value); 780 void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
769 #endif 781 #endif
@@ -771,6 +783,7 @@ uint32_t ppc_load_xer (CPUPPCState *env); @@ -771,6 +783,7 @@ uint32_t ppc_load_xer (CPUPPCState *env);
771 void ppc_store_xer (CPUPPCState *env, uint32_t value); 783 void ppc_store_xer (CPUPPCState *env, uint32_t value);
772 target_ulong do_load_msr (CPUPPCState *env); 784 target_ulong do_load_msr (CPUPPCState *env);
773 void do_store_msr (CPUPPCState *env, target_ulong value); 785 void do_store_msr (CPUPPCState *env, target_ulong value);
  786 +void ppc_store_msr32 (CPUPPCState *env, uint32_t value);
774 787
775 void do_compute_hflags (CPUPPCState *env); 788 void do_compute_hflags (CPUPPCState *env);
776 789
@@ -787,6 +800,16 @@ void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value); @@ -787,6 +800,16 @@ void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value);
787 void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value); 800 void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value);
788 uint32_t cpu_ppc_load_decr (CPUPPCState *env); 801 uint32_t cpu_ppc_load_decr (CPUPPCState *env);
789 void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value); 802 void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
  803 +uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env);
  804 +uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env);
  805 +#if !defined(CONFIG_USER_ONLY)
  806 +void cpu_ppc601_store_rtcl (CPUPPCState *env, uint32_t value);
  807 +void cpu_ppc601_store_rtcu (CPUPPCState *env, uint32_t value);
  808 +target_ulong load_40x_pit (CPUPPCState *env);
  809 +void store_40x_pit (CPUPPCState *env, target_ulong val);
  810 +void store_booke_tcr (CPUPPCState *env, target_ulong val);
  811 +void store_booke_tsr (CPUPPCState *env, target_ulong val);
  812 +#endif
790 #endif 813 #endif
791 814
792 #define TARGET_PAGE_BITS 12 815 #define TARGET_PAGE_BITS 12
target-ppc/exec.h
@@ -34,19 +34,25 @@ register struct CPUPPCState *env asm(AREG0); @@ -34,19 +34,25 @@ register struct CPUPPCState *env asm(AREG0);
34 #define T1 (env->t1) 34 #define T1 (env->t1)
35 #define T2 (env->t2) 35 #define T2 (env->t2)
36 #else 36 #else
37 -/* This may be more efficient if HOST_LONG_BITS > TARGET_LONG_BITS  
38 - * To be set to one when we'll be sure it does not cause bugs....  
39 - */  
40 -#if 0  
41 register unsigned long T0 asm(AREG1); 37 register unsigned long T0 asm(AREG1);
42 register unsigned long T1 asm(AREG2); 38 register unsigned long T1 asm(AREG2);
43 register unsigned long T2 asm(AREG3); 39 register unsigned long T2 asm(AREG3);
44 -#else  
45 -register target_ulong T0 asm(AREG1);  
46 -register target_ulong T1 asm(AREG2);  
47 -register target_ulong T2 asm(AREG3);  
48 #endif 40 #endif
  41 +/* We may, sometime, need 64 bits registers on 32 bits target */
  42 +#if defined(TARGET_PPC64) || (HOST_LONG_BITS == 64)
  43 +#define T0_64 T0
  44 +#define T1_64 T0
  45 +#define T2_64 T0
  46 +#else
  47 +/* no registers can be used */
  48 +#define T0_64 (env->t0)
  49 +#define T1_64 (env->t1)
  50 +#define T2_64 (env->t2)
49 #endif 51 #endif
  52 +/* Provision for Altivec */
  53 +#define T0_avr (env->t0_avr)
  54 +#define T1_avr (env->t1_avr)
  55 +#define T2_avr (env->t2_avr)
50 56
51 /* XXX: to clean: remove this mess */ 57 /* XXX: to clean: remove this mess */
52 #define PARAM(n) ((uint32_t)PARAM##n) 58 #define PARAM(n) ((uint32_t)PARAM##n)
target-ppc/helper.c
@@ -37,12 +37,12 @@ @@ -37,12 +37,12 @@
37 /*****************************************************************************/ 37 /*****************************************************************************/
38 /* PowerPC MMU emulation */ 38 /* PowerPC MMU emulation */
39 39
40 -#if defined(CONFIG_USER_ONLY) 40 +#if defined(CONFIG_USER_ONLY)
41 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, 41 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
42 int is_user, int is_softmmu) 42 int is_user, int is_softmmu)
43 { 43 {
44 int exception, error_code; 44 int exception, error_code;
45 - 45 +
46 if (rw == 2) { 46 if (rw == 2) {
47 exception = EXCP_ISI; 47 exception = EXCP_ISI;
48 error_code = 0; 48 error_code = 0;
@@ -277,7 +277,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, @@ -277,7 +277,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
277 ppc_tlb_t *tlb; 277 ppc_tlb_t *tlb;
278 int nr, best, way; 278 int nr, best, way;
279 int ret; 279 int ret;
280 - 280 +
281 best = -1; 281 best = -1;
282 ret = -1; /* No TLB found */ 282 ret = -1; /* No TLB found */
283 for (way = 0; way < env->nb_ways; way++) { 283 for (way = 0; way < env->nb_ways; way++) {
@@ -672,7 +672,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, @@ -672,7 +672,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
672 if (loglevel > 0) { 672 if (loglevel > 0) {
673 fprintf(logfile, "%s\n", __func__); 673 fprintf(logfile, "%s\n", __func__);
674 } 674 }
675 -#endif 675 +#endif
676 if ((access_type == ACCESS_CODE && msr_ir == 0) || 676 if ((access_type == ACCESS_CODE && msr_ir == 0) ||
677 (access_type != ACCESS_CODE && msr_dr == 0)) { 677 (access_type != ACCESS_CODE && msr_dr == 0)) {
678 /* No address translation */ 678 /* No address translation */
@@ -693,7 +693,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, @@ -693,7 +693,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
693 __func__, eaddr, ctx->raddr); 693 __func__, eaddr, ctx->raddr);
694 } 694 }
695 #endif 695 #endif
696 - 696 +
697 return ret; 697 return ret;
698 } 698 }
699 699
@@ -715,7 +715,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -715,7 +715,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
715 int exception = 0, error_code = 0; 715 int exception = 0, error_code = 0;
716 int access_type; 716 int access_type;
717 int ret = 0; 717 int ret = 0;
718 - 718 +
719 if (rw == 2) { 719 if (rw == 2) {
720 /* code access */ 720 /* code access */
721 rw = 0; 721 rw = 0;
@@ -975,6 +975,21 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value) @@ -975,6 +975,21 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
975 975
976 /*****************************************************************************/ 976 /*****************************************************************************/
977 /* Special registers manipulation */ 977 /* Special registers manipulation */
  978 +#if defined(TARGET_PPC64)
  979 +target_ulong ppc_load_asr (CPUPPCState *env)
  980 +{
  981 + return env->asr;
  982 +}
  983 +
  984 +void ppc_store_asr (CPUPPCState *env, target_ulong value)
  985 +{
  986 + if (env->asr != value) {
  987 + env->asr = value;
  988 + tlb_flush(env, 1);
  989 + }
  990 +}
  991 +#endif
  992 +
978 target_ulong do_load_sdr1 (CPUPPCState *env) 993 target_ulong do_load_sdr1 (CPUPPCState *env)
979 { 994 {
980 return env->sdr1; 995 return env->sdr1;
@@ -1039,7 +1054,7 @@ void ppc_store_xer (CPUPPCState *env, uint32_t value) @@ -1039,7 +1054,7 @@ void ppc_store_xer (CPUPPCState *env, uint32_t value)
1039 xer_ov = (value >> XER_OV) & 0x01; 1054 xer_ov = (value >> XER_OV) & 0x01;
1040 xer_ca = (value >> XER_CA) & 0x01; 1055 xer_ca = (value >> XER_CA) & 0x01;
1041 xer_cmp = (value >> XER_CMP) & 0xFF; 1056 xer_cmp = (value >> XER_CMP) & 0xFF;
1042 - xer_bc = (value >> XER_BC) & 0x3F; 1057 + xer_bc = (value >> XER_BC) & 0x7F;
1043 } 1058 }
1044 1059
1045 /* Swap temporary saved registers with GPRs */ 1060 /* Swap temporary saved registers with GPRs */
@@ -1066,34 +1081,34 @@ target_ulong do_load_msr (CPUPPCState *env) @@ -1066,34 +1081,34 @@ target_ulong do_load_msr (CPUPPCState *env)
1066 { 1081 {
1067 return 1082 return
1068 #if defined (TARGET_PPC64) 1083 #if defined (TARGET_PPC64)
1069 - (msr_sf << MSR_SF) |  
1070 - (msr_isf << MSR_ISF) |  
1071 - (msr_hv << MSR_HV) | 1084 + ((target_ulong)msr_sf << MSR_SF) |
  1085 + ((target_ulong)msr_isf << MSR_ISF) |
  1086 + ((target_ulong)msr_hv << MSR_HV) |
1072 #endif 1087 #endif
1073 - (msr_ucle << MSR_UCLE) |  
1074 - (msr_vr << MSR_VR) | /* VR / SPE */  
1075 - (msr_ap << MSR_AP) |  
1076 - (msr_sa << MSR_SA) |  
1077 - (msr_key << MSR_KEY) |  
1078 - (msr_pow << MSR_POW) | /* POW / WE */  
1079 - (msr_tlb << MSR_TLB) | /* TLB / TGPE / CE */  
1080 - (msr_ile << MSR_ILE) |  
1081 - (msr_ee << MSR_EE) |  
1082 - (msr_pr << MSR_PR) |  
1083 - (msr_fp << MSR_FP) |  
1084 - (msr_me << MSR_ME) |  
1085 - (msr_fe0 << MSR_FE0) |  
1086 - (msr_se << MSR_SE) | /* SE / DWE / UBLE */  
1087 - (msr_be << MSR_BE) | /* BE / DE */  
1088 - (msr_fe1 << MSR_FE1) |  
1089 - (msr_al << MSR_AL) |  
1090 - (msr_ip << MSR_IP) |  
1091 - (msr_ir << MSR_IR) | /* IR / IS */  
1092 - (msr_dr << MSR_DR) | /* DR / DS */  
1093 - (msr_pe << MSR_PE) | /* PE / EP */  
1094 - (msr_px << MSR_PX) | /* PX / PMM */  
1095 - (msr_ri << MSR_RI) |  
1096 - (msr_le << MSR_LE); 1088 + ((target_ulong)msr_ucle << MSR_UCLE) |
  1089 + ((target_ulong)msr_vr << MSR_VR) | /* VR / SPE */
  1090 + ((target_ulong)msr_ap << MSR_AP) |
  1091 + ((target_ulong)msr_sa << MSR_SA) |
  1092 + ((target_ulong)msr_key << MSR_KEY) |
  1093 + ((target_ulong)msr_pow << MSR_POW) | /* POW / WE */
  1094 + ((target_ulong)msr_tlb << MSR_TLB) | /* TLB / TGPE / CE */
  1095 + ((target_ulong)msr_ile << MSR_ILE) |
  1096 + ((target_ulong)msr_ee << MSR_EE) |
  1097 + ((target_ulong)msr_pr << MSR_PR) |
  1098 + ((target_ulong)msr_fp << MSR_FP) |
  1099 + ((target_ulong)msr_me << MSR_ME) |
  1100 + ((target_ulong)msr_fe0 << MSR_FE0) |
  1101 + ((target_ulong)msr_se << MSR_SE) | /* SE / DWE / UBLE */
  1102 + ((target_ulong)msr_be << MSR_BE) | /* BE / DE */
  1103 + ((target_ulong)msr_fe1 << MSR_FE1) |
  1104 + ((target_ulong)msr_al << MSR_AL) |
  1105 + ((target_ulong)msr_ip << MSR_IP) |
  1106 + ((target_ulong)msr_ir << MSR_IR) | /* IR / IS */
  1107 + ((target_ulong)msr_dr << MSR_DR) | /* DR / DS */
  1108 + ((target_ulong)msr_pe << MSR_PE) | /* PE / EP */
  1109 + ((target_ulong)msr_px << MSR_PX) | /* PX / PMM */
  1110 + ((target_ulong)msr_ri << MSR_RI) |
  1111 + ((target_ulong)msr_le << MSR_LE);
1097 } 1112 }
1098 1113
1099 void do_store_msr (CPUPPCState *env, target_ulong value) 1114 void do_store_msr (CPUPPCState *env, target_ulong value)
@@ -1156,6 +1171,17 @@ void do_store_msr (CPUPPCState *env, target_ulong value) @@ -1156,6 +1171,17 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
1156 1171
1157 enter_pm = 0; 1172 enter_pm = 0;
1158 switch (PPC_EXCP(env)) { 1173 switch (PPC_EXCP(env)) {
  1174 + case PPC_FLAGS_EXCP_603:
  1175 + /* Don't handle SLEEP mode: we should disable all clocks...
  1176 + * No dynamic power-management.
  1177 + */
  1178 + if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00C00000) != 0)
  1179 + enter_pm = 1;
  1180 + break;
  1181 + case PPC_FLAGS_EXCP_604:
  1182 + if (msr_pow == 1)
  1183 + enter_pm = 1;
  1184 + break;
1159 case PPC_FLAGS_EXCP_7x0: 1185 case PPC_FLAGS_EXCP_7x0:
1160 if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0) 1186 if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0)
1161 enter_pm = 1; 1187 enter_pm = 1;
@@ -1171,15 +1197,22 @@ void do_store_msr (CPUPPCState *env, target_ulong value) @@ -1171,15 +1197,22 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
1171 } 1197 }
1172 } 1198 }
1173 1199
  1200 +#if defined(TARGET_PPC64)
  1201 +void ppc_store_msr_32 (CPUPPCState *env, target_ulong value)
  1202 +{
  1203 + do_store_msr(env, (uint32_t)value);
  1204 +}
  1205 +#endif
  1206 +
1174 void do_compute_hflags (CPUPPCState *env) 1207 void do_compute_hflags (CPUPPCState *env)
1175 { 1208 {
1176 /* Compute current hflags */ 1209 /* Compute current hflags */
1177 env->hflags = (msr_pr << MSR_PR) | (msr_le << MSR_LE) | 1210 env->hflags = (msr_pr << MSR_PR) | (msr_le << MSR_LE) |
1178 (msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_fe1 << MSR_FE1) | 1211 (msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_fe1 << MSR_FE1) |
1179 - (msr_vr << MSR_VR) | (msr_ap << MSR_AP) | (msr_sa << MSR_SA) | 1212 + (msr_vr << MSR_VR) | (msr_ap << MSR_AP) | (msr_sa << MSR_SA) |
1180 (msr_se << MSR_SE) | (msr_be << MSR_BE); 1213 (msr_se << MSR_SE) | (msr_be << MSR_BE);
1181 #if defined (TARGET_PPC64) 1214 #if defined (TARGET_PPC64)
1182 - env->hflags |= (msr_sf << MSR_SF) | (msr_hv << MSR_HV); 1215 + env->hflags |= (msr_sf << (MSR_SF - 32)) | (msr_hv << (MSR_HV - 32));
1183 #endif 1216 #endif
1184 } 1217 }
1185 1218
@@ -1193,8 +1226,8 @@ void do_interrupt (CPUState *env) @@ -1193,8 +1226,8 @@ void do_interrupt (CPUState *env)
1193 #else /* defined (CONFIG_USER_ONLY) */ 1226 #else /* defined (CONFIG_USER_ONLY) */
1194 static void dump_syscall(CPUState *env) 1227 static void dump_syscall(CPUState *env)
1195 { 1228 {
1196 - fprintf(logfile, "syscall r0=0x%08x r3=0x%08x r4=0x%08x "  
1197 - "r5=0x%08x r6=0x%08x nip=0x%08x\n", 1229 + fprintf(logfile, "syscall r0=0x" REGX " r3=0x" REGX " r4=0x" REGX
  1230 + " r5=0x" REGX " r6=0x" REGX " nip=0x" REGX "\n",
1198 env->gpr[0], env->gpr[3], env->gpr[4], 1231 env->gpr[0], env->gpr[3], env->gpr[4],
1199 env->gpr[5], env->gpr[6], env->nip); 1232 env->gpr[5], env->gpr[6], env->nip);
1200 } 1233 }
target-ppc/op.c
@@ -26,9 +26,6 @@ @@ -26,9 +26,6 @@
26 26
27 /* XXX: this is to be suppressed */ 27 /* XXX: this is to be suppressed */
28 #define regs (env) 28 #define regs (env)
29 -#define Ts0 (int32_t)T0  
30 -#define Ts1 (int32_t)T1  
31 -#define Ts2 (int32_t)T2  
32 29
33 #define FT0 (env->ft0) 30 #define FT0 (env->ft0)
34 #define FT1 (env->ft1) 31 #define FT1 (env->ft1)
@@ -157,15 +154,31 @@ void OPPROTO op_reset_T0 (void) @@ -157,15 +154,31 @@ void OPPROTO op_reset_T0 (void)
157 154
158 PPC_OP(set_T0) 155 PPC_OP(set_T0)
159 { 156 {
160 - T0 = PARAM(1); 157 + T0 = (uint32_t)PARAM1;
161 RETURN(); 158 RETURN();
162 } 159 }
163 160
  161 +#if defined(TARGET_PPC64)
  162 +void OPPROTO op_set_T0_64 (void)
  163 +{
  164 + T0 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
  165 + RETURN();
  166 +}
  167 +#endif
  168 +
164 PPC_OP(set_T1) 169 PPC_OP(set_T1)
165 { 170 {
166 - T1 = PARAM(1); 171 + T1 = (uint32_t)PARAM1;
  172 + RETURN();
  173 +}
  174 +
  175 +#if defined(TARGET_PPC64)
  176 +void OPPROTO op_set_T1_64 (void)
  177 +{
  178 + T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
167 RETURN(); 179 RETURN();
168 } 180 }
  181 +#endif
169 182
170 #if 0 // unused 183 #if 0 // unused
171 PPC_OP(set_T2) 184 PPC_OP(set_T2)
@@ -181,6 +194,12 @@ void OPPROTO op_move_T1_T0 (void) @@ -181,6 +194,12 @@ void OPPROTO op_move_T1_T0 (void)
181 RETURN(); 194 RETURN();
182 } 195 }
183 196
  197 +void OPPROTO op_move_T2_T0 (void)
  198 +{
  199 + T2 = T0;
  200 + RETURN();
  201 +}
  202 +
184 /* Generate exceptions */ 203 /* Generate exceptions */
185 PPC_OP(raise_exception_err) 204 PPC_OP(raise_exception_err)
186 { 205 {
@@ -189,16 +208,23 @@ PPC_OP(raise_exception_err) @@ -189,16 +208,23 @@ PPC_OP(raise_exception_err)
189 208
190 PPC_OP(update_nip) 209 PPC_OP(update_nip)
191 { 210 {
192 - env->nip = PARAM(1); 211 + env->nip = (uint32_t)PARAM1;
193 RETURN(); 212 RETURN();
194 } 213 }
195 214
  215 +#if defined(TARGET_PPC64)
  216 +void OPPROTO op_update_nip_64 (void)
  217 +{
  218 + env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
  219 + RETURN();
  220 +}
  221 +#endif
  222 +
196 PPC_OP(debug) 223 PPC_OP(debug)
197 { 224 {
198 do_raise_exception(EXCP_DEBUG); 225 do_raise_exception(EXCP_DEBUG);
199 } 226 }
200 227
201 -  
202 PPC_OP(exit_tb) 228 PPC_OP(exit_tb)
203 { 229 {
204 EXIT_TB(); 230 EXIT_TB();
@@ -293,6 +319,20 @@ PPC_OP(store_sdr1) @@ -293,6 +319,20 @@ PPC_OP(store_sdr1)
293 RETURN(); 319 RETURN();
294 } 320 }
295 321
  322 +#if defined (TARGET_PPC64)
  323 +void OPPROTO op_load_asr (void)
  324 +{
  325 + T0 = env->asr;
  326 + RETURN();
  327 +}
  328 +
  329 +void OPPROTO op_store_asr (void)
  330 +{
  331 + ppc_store_asr(env, T0);
  332 + RETURN();
  333 +}
  334 +#endif
  335 +
296 PPC_OP(load_msr) 336 PPC_OP(load_msr)
297 { 337 {
298 T0 = do_load_msr(env); 338 T0 = do_load_msr(env);
@@ -304,6 +344,14 @@ PPC_OP(store_msr) @@ -304,6 +344,14 @@ PPC_OP(store_msr)
304 do_store_msr(env, T0); 344 do_store_msr(env, T0);
305 RETURN(); 345 RETURN();
306 } 346 }
  347 +
  348 +#if defined (TARGET_PPC64)
  349 +void OPPROTO op_store_msr_32 (void)
  350 +{
  351 + ppc_store_msr_32(env, T0);
  352 + RETURN();
  353 +}
  354 +#endif
307 #endif 355 #endif
308 356
309 /* SPR */ 357 /* SPR */
@@ -459,7 +507,7 @@ PPC_OP(getbit_T1) @@ -459,7 +507,7 @@ PPC_OP(getbit_T1)
459 507
460 PPC_OP(setcrfbit) 508 PPC_OP(setcrfbit)
461 { 509 {
462 - T1 = (T1 & PARAM(1)) | (T0 << PARAM(2)); 510 + T1 = (T1 & PARAM(1)) | (T0 << PARAM(2));
463 RETURN(); 511 RETURN();
464 } 512 }
465 513
@@ -468,10 +516,18 @@ PPC_OP(setcrfbit) @@ -468,10 +516,18 @@ PPC_OP(setcrfbit)
468 516
469 PPC_OP(setlr) 517 PPC_OP(setlr)
470 { 518 {
471 - regs->lr = PARAM1; 519 + regs->lr = (uint32_t)PARAM1;
472 RETURN(); 520 RETURN();
473 } 521 }
474 522
  523 +#if defined (TARGET_PPC64)
  524 +void OPPROTO op_setlr_64 (void)
  525 +{
  526 + regs->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
  527 + RETURN();
  528 +}
  529 +#endif
  530 +
475 PPC_OP(goto_tb0) 531 PPC_OP(goto_tb0)
476 { 532 {
477 GOTO_TB(op_goto_tb0, PARAM1, 0); 533 GOTO_TB(op_goto_tb0, PARAM1, 0);
@@ -482,12 +538,20 @@ PPC_OP(goto_tb1) @@ -482,12 +538,20 @@ PPC_OP(goto_tb1)
482 GOTO_TB(op_goto_tb1, PARAM1, 1); 538 GOTO_TB(op_goto_tb1, PARAM1, 1);
483 } 539 }
484 540
485 -PPC_OP(b_T1) 541 +void OPPROTO op_b_T1 (void)
486 { 542 {
487 - regs->nip = T1 & ~3; 543 + regs->nip = (uint32_t)(T1 & ~3);
488 RETURN(); 544 RETURN();
489 } 545 }
490 546
  547 +#if defined (TARGET_PPC64)
  548 +void OPPROTO op_b_T1_64 (void)
  549 +{
  550 + regs->nip = (uint64_t)(T1 & ~3);
  551 + RETURN();
  552 +}
  553 +#endif
  554 +
491 PPC_OP(jz_T0) 555 PPC_OP(jz_T0)
492 { 556 {
493 if (!T0) 557 if (!T0)
@@ -495,16 +559,28 @@ PPC_OP(jz_T0) @@ -495,16 +559,28 @@ PPC_OP(jz_T0)
495 RETURN(); 559 RETURN();
496 } 560 }
497 561
498 -PPC_OP(btest_T1) 562 +void OPPROTO op_btest_T1 (void)
499 { 563 {
500 if (T0) { 564 if (T0) {
501 - regs->nip = T1 & ~3; 565 + regs->nip = (uint32_t)(T1 & ~3);
502 } else { 566 } else {
503 - regs->nip = PARAM1; 567 + regs->nip = (uint32_t)PARAM1;
504 } 568 }
505 RETURN(); 569 RETURN();
506 } 570 }
507 571
  572 +#if defined (TARGET_PPC64)
  573 +void OPPROTO op_btest_T1_64 (void)
  574 +{
  575 + if (T0) {
  576 + regs->nip = (uint64_t)(T1 & ~3);
  577 + } else {
  578 + regs->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
  579 + }
  580 + RETURN();
  581 +}
  582 +#endif
  583 +
508 PPC_OP(movl_T1_ctr) 584 PPC_OP(movl_T1_ctr)
509 { 585 {
510 T1 = regs->ctr; 586 T1 = regs->ctr;
@@ -518,42 +594,89 @@ PPC_OP(movl_T1_lr) @@ -518,42 +594,89 @@ PPC_OP(movl_T1_lr)
518 } 594 }
519 595
520 /* tests with result in T0 */ 596 /* tests with result in T0 */
  597 +void OPPROTO op_test_ctr (void)
  598 +{
  599 + T0 = (uint32_t)regs->ctr;
  600 + RETURN();
  601 +}
521 602
522 -PPC_OP(test_ctr) 603 +#if defined(TARGET_PPC64)
  604 +void OPPROTO op_test_ctr_64 (void)
523 { 605 {
524 - T0 = regs->ctr; 606 + T0 = (uint64_t)regs->ctr;
  607 + RETURN();
  608 +}
  609 +#endif
  610 +
  611 +void OPPROTO op_test_ctr_true (void)
  612 +{
  613 + T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
525 RETURN(); 614 RETURN();
526 } 615 }
527 616
528 -PPC_OP(test_ctr_true) 617 +#if defined(TARGET_PPC64)
  618 +void OPPROTO op_test_ctr_true_64 (void)
529 { 619 {
530 - T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0); 620 + T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
531 RETURN(); 621 RETURN();
532 } 622 }
  623 +#endif
533 624
534 -PPC_OP(test_ctr_false) 625 +void OPPROTO op_test_ctr_false (void)
535 { 626 {
536 - T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0); 627 + T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
537 RETURN(); 628 RETURN();
538 } 629 }
539 630
540 -PPC_OP(test_ctrz) 631 +#if defined(TARGET_PPC64)
  632 +void OPPROTO op_test_ctr_false_64 (void)
541 { 633 {
542 - T0 = (regs->ctr == 0); 634 + T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
543 RETURN(); 635 RETURN();
544 } 636 }
  637 +#endif
  638 +
  639 +void OPPROTO op_test_ctrz (void)
  640 +{
  641 + T0 = ((uint32_t)regs->ctr == 0);
  642 + RETURN();
  643 +}
  644 +
  645 +#if defined(TARGET_PPC64)
  646 +void OPPROTO op_test_ctrz_64 (void)
  647 +{
  648 + T0 = ((uint64_t)regs->ctr == 0);
  649 + RETURN();
  650 +}
  651 +#endif
  652 +
  653 +void OPPROTO op_test_ctrz_true (void)
  654 +{
  655 + T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
  656 + RETURN();
  657 +}
  658 +
  659 +#if defined(TARGET_PPC64)
  660 +void OPPROTO op_test_ctrz_true_64 (void)
  661 +{
  662 + T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
  663 + RETURN();
  664 +}
  665 +#endif
545 666
546 -PPC_OP(test_ctrz_true) 667 +void OPPROTO op_test_ctrz_false (void)
547 { 668 {
548 - T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0); 669 + T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
549 RETURN(); 670 RETURN();
550 } 671 }
551 672
552 -PPC_OP(test_ctrz_false) 673 +#if defined(TARGET_PPC64)
  674 +void OPPROTO op_test_ctrz_false_64 (void)
553 { 675 {
554 - T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0); 676 + T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
555 RETURN(); 677 RETURN();
556 } 678 }
  679 +#endif
557 680
558 PPC_OP(test_true) 681 PPC_OP(test_true)
559 { 682 {
@@ -582,30 +705,52 @@ PPC_OP(add) @@ -582,30 +705,52 @@ PPC_OP(add)
582 RETURN(); 705 RETURN();
583 } 706 }
584 707
585 -void OPPROTO op_addo (void) 708 +void OPPROTO op_check_addo (void)
586 { 709 {
587 - do_addo();  
588 - RETURN(); 710 + if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
  711 + ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
  712 + xer_ov = 0;
  713 + } else {
  714 + xer_so = 1;
  715 + xer_ov = 1;
  716 + }
589 } 717 }
590 718
591 -/* add carrying */  
592 -PPC_OP(addc) 719 +#if defined(TARGET_PPC64)
  720 +void OPPROTO op_check_addo_64 (void)
593 { 721 {
594 - T2 = T0;  
595 - T0 += T1;  
596 - if (T0 < T2) {  
597 - xer_ca = 1; 722 + if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
  723 + ((uint64_t)T2 ^ (uint64_t)T0) & (1UL << 63)))) {
  724 + xer_ov = 0;
598 } else { 725 } else {
  726 + xer_so = 1;
  727 + xer_ov = 1;
  728 + }
  729 +}
  730 +#endif
  731 +
  732 +/* add carrying */
  733 +void OPPROTO op_check_addc (void)
  734 +{
  735 + if (likely((uint32_t)T0 >= (uint32_t)T2)) {
599 xer_ca = 0; 736 xer_ca = 0;
  737 + } else {
  738 + xer_ca = 1;
600 } 739 }
601 RETURN(); 740 RETURN();
602 } 741 }
603 742
604 -void OPPROTO op_addco (void) 743 +#if defined(TARGET_PPC64)
  744 +void OPPROTO op_check_addc_64 (void)
605 { 745 {
606 - do_addco(); 746 + if (likely((uint64_t)T0 >= (uint64_t)T2)) {
  747 + xer_ca = 0;
  748 + } else {
  749 + xer_ca = 1;
  750 + }
607 RETURN(); 751 RETURN();
608 } 752 }
  753 +#endif
609 754
610 /* add extended */ 755 /* add extended */
611 void OPPROTO op_adde (void) 756 void OPPROTO op_adde (void)
@@ -614,11 +759,13 @@ void OPPROTO op_adde (void) @@ -614,11 +759,13 @@ void OPPROTO op_adde (void)
614 RETURN(); 759 RETURN();
615 } 760 }
616 761
617 -PPC_OP(addeo) 762 +#if defined(TARGET_PPC64)
  763 +void OPPROTO op_adde_64 (void)
618 { 764 {
619 - do_addeo(); 765 + do_adde_64();
620 RETURN(); 766 RETURN();
621 } 767 }
  768 +#endif
622 769
623 /* add immediate */ 770 /* add immediate */
624 PPC_OP(addi) 771 PPC_OP(addi)
@@ -627,28 +774,24 @@ PPC_OP(addi) @@ -627,28 +774,24 @@ PPC_OP(addi)
627 RETURN(); 774 RETURN();
628 } 775 }
629 776
630 -/* add immediate carrying */  
631 -PPC_OP(addic) 777 +/* add to minus one extended */
  778 +void OPPROTO op_add_me (void)
632 { 779 {
633 - T1 = T0;  
634 - T0 += PARAM(1);  
635 - if (T0 < T1) { 780 + T0 += xer_ca + (-1);
  781 + if (likely((uint32_t)T1 != 0))
636 xer_ca = 1; 782 xer_ca = 1;
637 - } else {  
638 - xer_ca = 0;  
639 - }  
640 RETURN(); 783 RETURN();
641 } 784 }
642 785
643 -/* add to minus one extended */  
644 -PPC_OP(addme) 786 +#if defined(TARGET_PPC64)
  787 +void OPPROTO op_add_me_64 (void)
645 { 788 {
646 - T1 = T0;  
647 T0 += xer_ca + (-1); 789 T0 += xer_ca + (-1);
648 - if (T1 != 0) 790 + if (likely((uint64_t)T1 != 0))
649 xer_ca = 1; 791 xer_ca = 1;
650 RETURN(); 792 RETURN();
651 } 793 }
  794 +#endif
652 795
653 void OPPROTO op_addmeo (void) 796 void OPPROTO op_addmeo (void)
654 { 797 {
@@ -656,35 +799,43 @@ void OPPROTO op_addmeo (void) @@ -656,35 +799,43 @@ void OPPROTO op_addmeo (void)
656 RETURN(); 799 RETURN();
657 } 800 }
658 801
  802 +void OPPROTO op_addmeo_64 (void)
  803 +{
  804 + do_addmeo();
  805 + RETURN();
  806 +}
  807 +
659 /* add to zero extended */ 808 /* add to zero extended */
660 -PPC_OP(addze) 809 +void OPPROTO op_add_ze (void)
661 { 810 {
662 - T1 = T0;  
663 T0 += xer_ca; 811 T0 += xer_ca;
664 - if (T0 < T1) {  
665 - xer_ca = 1;  
666 - } else {  
667 - xer_ca = 0;  
668 - }  
669 RETURN(); 812 RETURN();
670 } 813 }
671 814
672 -void OPPROTO op_addzeo (void) 815 +/* divide word */
  816 +void OPPROTO op_divw (void)
673 { 817 {
674 - do_addzeo(); 818 + if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
  819 + (int32_t)T1 == 0)) {
  820 + T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
  821 + } else {
  822 + T0 = (int32_t)T0 / (int32_t)T1;
  823 + }
675 RETURN(); 824 RETURN();
676 } 825 }
677 826
678 -/* divide word */  
679 -PPC_OP(divw) 827 +#if defined(TARGET_PPC64)
  828 +void OPPROTO op_divd (void)
680 { 829 {
681 - if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {  
682 - T0 = (int32_t)((-1) * (T0 >> 31)); 830 + if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
  831 + (int64_t)T1 == 0)) {
  832 + T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
683 } else { 833 } else {
684 - T0 = (Ts0 / Ts1); 834 + T0 = (int64_t)T0 / (int64_t)T1;
685 } 835 }
686 RETURN(); 836 RETURN();
687 } 837 }
  838 +#endif
688 839
689 void OPPROTO op_divwo (void) 840 void OPPROTO op_divwo (void)
690 { 841 {
@@ -692,16 +843,36 @@ void OPPROTO op_divwo (void) @@ -692,16 +843,36 @@ void OPPROTO op_divwo (void)
692 RETURN(); 843 RETURN();
693 } 844 }
694 845
  846 +#if defined(TARGET_PPC64)
  847 +void OPPROTO op_divdo (void)
  848 +{
  849 + do_divdo();
  850 + RETURN();
  851 +}
  852 +#endif
  853 +
695 /* divide word unsigned */ 854 /* divide word unsigned */
696 -PPC_OP(divwu) 855 +void OPPROTO op_divwu (void)
  856 +{
  857 + if (unlikely(T1 == 0)) {
  858 + T0 = 0;
  859 + } else {
  860 + T0 = (uint32_t)T0 / (uint32_t)T1;
  861 + }
  862 + RETURN();
  863 +}
  864 +
  865 +#if defined(TARGET_PPC64)
  866 +void OPPROTO op_divdu (void)
697 { 867 {
698 - if (T1 == 0) { 868 + if (unlikely(T1 == 0)) {
699 T0 = 0; 869 T0 = 0;
700 } else { 870 } else {
701 T0 /= T1; 871 T0 /= T1;
702 } 872 }
703 RETURN(); 873 RETURN();
704 } 874 }
  875 +#endif
705 876
706 void OPPROTO op_divwuo (void) 877 void OPPROTO op_divwuo (void)
707 { 878 {
@@ -709,33 +880,71 @@ void OPPROTO op_divwuo (void) @@ -709,33 +880,71 @@ void OPPROTO op_divwuo (void)
709 RETURN(); 880 RETURN();
710 } 881 }
711 882
  883 +#if defined(TARGET_PPC64)
  884 +void OPPROTO op_divduo (void)
  885 +{
  886 + do_divduo();
  887 + RETURN();
  888 +}
  889 +#endif
  890 +
712 /* multiply high word */ 891 /* multiply high word */
713 -PPC_OP(mulhw) 892 +void OPPROTO op_mulhw (void)
714 { 893 {
715 - T0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32; 894 + T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
716 RETURN(); 895 RETURN();
717 } 896 }
718 897
  898 +#if defined(TARGET_PPC64)
  899 +void OPPROTO op_mulhd (void)
  900 +{
  901 + uint64_t tl, th;
  902 +
  903 + do_imul64(&tl, &th);
  904 + T0 = th;
  905 + RETURN();
  906 +}
  907 +#endif
  908 +
719 /* multiply high word unsigned */ 909 /* multiply high word unsigned */
720 -PPC_OP(mulhwu) 910 +void OPPROTO op_mulhwu (void)
721 { 911 {
722 - T0 = ((uint64_t)T0 * (uint64_t)T1) >> 32; 912 + T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
723 RETURN(); 913 RETURN();
724 } 914 }
725 915
  916 +#if defined(TARGET_PPC64)
  917 +void OPPROTO op_mulhdu (void)
  918 +{
  919 + uint64_t tl, th;
  920 +
  921 + do_mul64(&tl, &th);
  922 + T0 = th;
  923 + RETURN();
  924 +}
  925 +#endif
  926 +
726 /* multiply low immediate */ 927 /* multiply low immediate */
727 PPC_OP(mulli) 928 PPC_OP(mulli)
728 { 929 {
729 - T0 = (Ts0 * SPARAM(1)); 930 + T0 = ((int32_t)T0 * (int32_t)PARAM1);
730 RETURN(); 931 RETURN();
731 } 932 }
732 933
733 /* multiply low word */ 934 /* multiply low word */
734 PPC_OP(mullw) 935 PPC_OP(mullw)
735 { 936 {
  937 + T0 = (int32_t)(T0 * T1);
  938 + RETURN();
  939 +}
  940 +
  941 +#if defined(TARGET_PPC64)
  942 +void OPPROTO op_mulld (void)
  943 +{
736 T0 *= T1; 944 T0 *= T1;
737 RETURN(); 945 RETURN();
738 } 946 }
  947 +#endif
739 948
740 void OPPROTO op_mullwo (void) 949 void OPPROTO op_mullwo (void)
741 { 950 {
@@ -743,21 +952,47 @@ void OPPROTO op_mullwo (void) @@ -743,21 +952,47 @@ void OPPROTO op_mullwo (void)
743 RETURN(); 952 RETURN();
744 } 953 }
745 954
  955 +#if defined(TARGET_PPC64)
  956 +void OPPROTO op_mulldo (void)
  957 +{
  958 + do_mulldo();
  959 + RETURN();
  960 +}
  961 +#endif
  962 +
746 /* negate */ 963 /* negate */
747 -PPC_OP(neg) 964 +void OPPROTO op_neg (void)
748 { 965 {
749 - if (T0 != 0x80000000) {  
750 - T0 = -Ts0; 966 + if (likely(T0 != INT32_MIN)) {
  967 + T0 = -(int32_t)T0;
751 } 968 }
752 RETURN(); 969 RETURN();
753 } 970 }
754 971
  972 +#if defined(TARGET_PPC64)
  973 +void OPPROTO op_neg_64 (void)
  974 +{
  975 + if (likely(T0 != INT64_MIN)) {
  976 + T0 = -(int64_t)T0;
  977 + }
  978 + RETURN();
  979 +}
  980 +#endif
  981 +
755 void OPPROTO op_nego (void) 982 void OPPROTO op_nego (void)
756 { 983 {
757 do_nego(); 984 do_nego();
758 RETURN(); 985 RETURN();
759 } 986 }
760 987
  988 +#if defined(TARGET_PPC64)
  989 +void OPPROTO op_nego_64 (void)
  990 +{
  991 + do_nego_64();
  992 + RETURN();
  993 +}
  994 +#endif
  995 +
761 /* substract from */ 996 /* substract from */
762 PPC_OP(subf) 997 PPC_OP(subf)
763 { 998 {
@@ -765,29 +1000,54 @@ PPC_OP(subf) @@ -765,29 +1000,54 @@ PPC_OP(subf)
765 RETURN(); 1000 RETURN();
766 } 1001 }
767 1002
768 -void OPPROTO op_subfo (void) 1003 +void OPPROTO op_check_subfo (void)
  1004 +{
  1005 + if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
  1006 + ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
  1007 + xer_ov = 0;
  1008 + } else {
  1009 + xer_so = 1;
  1010 + xer_ov = 1;
  1011 + }
  1012 + RETURN();
  1013 +}
  1014 +
  1015 +#if defined(TARGET_PPC64)
  1016 +void OPPROTO op_check_subfo_64 (void)
769 { 1017 {
770 - do_subfo(); 1018 + if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
  1019 + ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
  1020 + xer_ov = 0;
  1021 + } else {
  1022 + xer_so = 1;
  1023 + xer_ov = 1;
  1024 + }
771 RETURN(); 1025 RETURN();
772 } 1026 }
  1027 +#endif
773 1028
774 /* substract from carrying */ 1029 /* substract from carrying */
775 -PPC_OP(subfc) 1030 +void OPPROTO op_check_subfc (void)
776 { 1031 {
777 - T0 = T1 - T0;  
778 - if (T0 <= T1) {  
779 - xer_ca = 1;  
780 - } else { 1032 + if (likely((uint32_t)T0 > (uint32_t)T1)) {
781 xer_ca = 0; 1033 xer_ca = 0;
  1034 + } else {
  1035 + xer_ca = 1;
782 } 1036 }
783 RETURN(); 1037 RETURN();
784 } 1038 }
785 1039
786 -void OPPROTO op_subfco (void) 1040 +#if defined(TARGET_PPC64)
  1041 +void OPPROTO op_check_subfc_64 (void)
787 { 1042 {
788 - do_subfco(); 1043 + if (likely((uint64_t)T0 > (uint64_t)T1)) {
  1044 + xer_ca = 0;
  1045 + } else {
  1046 + xer_ca = 1;
  1047 + }
789 RETURN(); 1048 RETURN();
790 } 1049 }
  1050 +#endif
791 1051
792 /* substract from extended */ 1052 /* substract from extended */
793 void OPPROTO op_subfe (void) 1053 void OPPROTO op_subfe (void)
@@ -796,17 +1056,19 @@ void OPPROTO op_subfe (void) @@ -796,17 +1056,19 @@ void OPPROTO op_subfe (void)
796 RETURN(); 1056 RETURN();
797 } 1057 }
798 1058
799 -PPC_OP(subfeo) 1059 +#if defined(TARGET_PPC64)
  1060 +void OPPROTO op_subfe_64 (void)
800 { 1061 {
801 - do_subfeo(); 1062 + do_subfe_64();
802 RETURN(); 1063 RETURN();
803 } 1064 }
  1065 +#endif
804 1066
805 /* substract from immediate carrying */ 1067 /* substract from immediate carrying */
806 -PPC_OP(subfic) 1068 +void OPPROTO op_subfic (void)
807 { 1069 {
808 - T0 = PARAM(1) + ~T0 + 1;  
809 - if (T0 <= PARAM(1)) { 1070 + T0 = PARAM1 + ~T0 + 1;
  1071 + if ((uint32_t)T0 <= (uint32_t)PARAM1) {
810 xer_ca = 1; 1072 xer_ca = 1;
811 } else { 1073 } else {
812 xer_ca = 0; 1074 xer_ca = 0;
@@ -814,15 +1076,37 @@ PPC_OP(subfic) @@ -814,15 +1076,37 @@ PPC_OP(subfic)
814 RETURN(); 1076 RETURN();
815 } 1077 }
816 1078
  1079 +#if defined(TARGET_PPC64)
  1080 +void OPPROTO op_subfic_64 (void)
  1081 +{
  1082 + T0 = PARAM1 + ~T0 + 1;
  1083 + if ((uint64_t)T0 <= (uint64_t)PARAM1) {
  1084 + xer_ca = 1;
  1085 + } else {
  1086 + xer_ca = 0;
  1087 + }
  1088 + RETURN();
  1089 +}
  1090 +#endif
  1091 +
817 /* substract from minus one extended */ 1092 /* substract from minus one extended */
818 -PPC_OP(subfme) 1093 +void OPPROTO op_subfme (void)
819 { 1094 {
820 T0 = ~T0 + xer_ca - 1; 1095 T0 = ~T0 + xer_ca - 1;
  1096 + if (likely((uint32_t)T0 != (uint32_t)-1))
  1097 + xer_ca = 1;
  1098 + RETURN();
  1099 +}
821 1100
822 - if (T0 != -1) 1101 +#if defined(TARGET_PPC64)
  1102 +void OPPROTO op_subfme_64 (void)
  1103 +{
  1104 + T0 = ~T0 + xer_ca - 1;
  1105 + if (likely((uint64_t)T0 != (uint64_t)-1))
823 xer_ca = 1; 1106 xer_ca = 1;
824 RETURN(); 1107 RETURN();
825 } 1108 }
  1109 +#endif
826 1110
827 void OPPROTO op_subfmeo (void) 1111 void OPPROTO op_subfmeo (void)
828 { 1112 {
@@ -830,12 +1114,20 @@ void OPPROTO op_subfmeo (void) @@ -830,12 +1114,20 @@ void OPPROTO op_subfmeo (void)
830 RETURN(); 1114 RETURN();
831 } 1115 }
832 1116
  1117 +#if defined(TARGET_PPC64)
  1118 +void OPPROTO op_subfmeo_64 (void)
  1119 +{
  1120 + do_subfmeo_64();
  1121 + RETURN();
  1122 +}
  1123 +#endif
  1124 +
833 /* substract from zero extended */ 1125 /* substract from zero extended */
834 -PPC_OP(subfze) 1126 +void OPPROTO op_subfze (void)
835 { 1127 {
836 T1 = ~T0; 1128 T1 = ~T0;
837 T0 = T1 + xer_ca; 1129 T0 = T1 + xer_ca;
838 - if (T0 < T1) { 1130 + if ((uint32_t)T0 < (uint32_t)T1) {
839 xer_ca = 1; 1131 xer_ca = 1;
840 } else { 1132 } else {
841 xer_ca = 0; 1133 xer_ca = 0;
@@ -843,32 +1135,68 @@ PPC_OP(subfze) @@ -843,32 +1135,68 @@ PPC_OP(subfze)
843 RETURN(); 1135 RETURN();
844 } 1136 }
845 1137
  1138 +#if defined(TARGET_PPC64)
  1139 +void OPPROTO op_subfze_64 (void)
  1140 +{
  1141 + T1 = ~T0;
  1142 + T0 = T1 + xer_ca;
  1143 + if ((uint64_t)T0 < (uint64_t)T1) {
  1144 + xer_ca = 1;
  1145 + } else {
  1146 + xer_ca = 0;
  1147 + }
  1148 + RETURN();
  1149 +}
  1150 +#endif
  1151 +
846 void OPPROTO op_subfzeo (void) 1152 void OPPROTO op_subfzeo (void)
847 { 1153 {
848 do_subfzeo(); 1154 do_subfzeo();
849 RETURN(); 1155 RETURN();
850 } 1156 }
851 1157
  1158 +#if defined(TARGET_PPC64)
  1159 +void OPPROTO op_subfzeo_64 (void)
  1160 +{
  1161 + do_subfzeo_64();
  1162 + RETURN();
  1163 +}
  1164 +#endif
  1165 +
852 /*** Integer comparison ***/ 1166 /*** Integer comparison ***/
853 /* compare */ 1167 /* compare */
854 -PPC_OP(cmp) 1168 +void OPPROTO op_cmp (void)
  1169 +{
  1170 + if ((int32_t)T0 < (int32_t)T1) {
  1171 + T0 = 0x08;
  1172 + } else if ((int32_t)T0 > (int32_t)T1) {
  1173 + T0 = 0x04;
  1174 + } else {
  1175 + T0 = 0x02;
  1176 + }
  1177 + RETURN();
  1178 +}
  1179 +
  1180 +#if defined(TARGET_PPC64)
  1181 +void OPPROTO op_cmp_64 (void)
855 { 1182 {
856 - if (Ts0 < Ts1) { 1183 + if ((int64_t)T0 < (int64_t)T1) {
857 T0 = 0x08; 1184 T0 = 0x08;
858 - } else if (Ts0 > Ts1) { 1185 + } else if ((int64_t)T0 > (int64_t)T1) {
859 T0 = 0x04; 1186 T0 = 0x04;
860 } else { 1187 } else {
861 T0 = 0x02; 1188 T0 = 0x02;
862 } 1189 }
863 RETURN(); 1190 RETURN();
864 } 1191 }
  1192 +#endif
865 1193
866 /* compare immediate */ 1194 /* compare immediate */
867 -PPC_OP(cmpi) 1195 +void OPPROTO op_cmpi (void)
868 { 1196 {
869 - if (Ts0 < SPARAM(1)) { 1197 + if ((int32_t)T0 < (int32_t)PARAM1) {
870 T0 = 0x08; 1198 T0 = 0x08;
871 - } else if (Ts0 > SPARAM(1)) { 1199 + } else if ((int32_t)T0 > (int32_t)PARAM1) {
872 T0 = 0x04; 1200 T0 = 0x04;
873 } else { 1201 } else {
874 T0 = 0x02; 1202 T0 = 0x02;
@@ -876,12 +1204,26 @@ PPC_OP(cmpi) @@ -876,12 +1204,26 @@ PPC_OP(cmpi)
876 RETURN(); 1204 RETURN();
877 } 1205 }
878 1206
  1207 +#if defined(TARGET_PPC64)
  1208 +void OPPROTO op_cmpi_64 (void)
  1209 +{
  1210 + if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
  1211 + T0 = 0x08;
  1212 + } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
  1213 + T0 = 0x04;
  1214 + } else {
  1215 + T0 = 0x02;
  1216 + }
  1217 + RETURN();
  1218 +}
  1219 +#endif
  1220 +
879 /* compare logical */ 1221 /* compare logical */
880 -PPC_OP(cmpl) 1222 +void OPPROTO op_cmpl (void)
881 { 1223 {
882 - if (T0 < T1) { 1224 + if ((uint32_t)T0 < (uint32_t)T1) {
883 T0 = 0x08; 1225 T0 = 0x08;
884 - } else if (T0 > T1) { 1226 + } else if ((uint32_t)T0 > (uint32_t)T1) {
885 T0 = 0x04; 1227 T0 = 0x04;
886 } else { 1228 } else {
887 T0 = 0x02; 1229 T0 = 0x02;
@@ -889,18 +1231,69 @@ PPC_OP(cmpl) @@ -889,18 +1231,69 @@ PPC_OP(cmpl)
889 RETURN(); 1231 RETURN();
890 } 1232 }
891 1233
  1234 +#if defined(TARGET_PPC64)
  1235 +void OPPROTO op_cmpl_64 (void)
  1236 +{
  1237 + if ((uint64_t)T0 < (uint64_t)T1) {
  1238 + T0 = 0x08;
  1239 + } else if ((uint64_t)T0 > (uint64_t)T1) {
  1240 + T0 = 0x04;
  1241 + } else {
  1242 + T0 = 0x02;
  1243 + }
  1244 + RETURN();
  1245 +}
  1246 +#endif
  1247 +
892 /* compare logical immediate */ 1248 /* compare logical immediate */
893 -PPC_OP(cmpli) 1249 +void OPPROTO op_cmpli (void)
  1250 +{
  1251 + if ((uint32_t)T0 < (uint32_t)PARAM1) {
  1252 + T0 = 0x08;
  1253 + } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
  1254 + T0 = 0x04;
  1255 + } else {
  1256 + T0 = 0x02;
  1257 + }
  1258 + RETURN();
  1259 +}
  1260 +
  1261 +#if defined(TARGET_PPC64)
  1262 +void OPPROTO op_cmpli_64 (void)
894 { 1263 {
895 - if (T0 < PARAM(1)) { 1264 + if ((uint64_t)T0 < (uint64_t)PARAM1) {
896 T0 = 0x08; 1265 T0 = 0x08;
897 - } else if (T0 > PARAM(1)) { 1266 + } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
898 T0 = 0x04; 1267 T0 = 0x04;
899 } else { 1268 } else {
900 T0 = 0x02; 1269 T0 = 0x02;
901 } 1270 }
902 RETURN(); 1271 RETURN();
903 } 1272 }
  1273 +#endif
  1274 +
  1275 +void OPPROTO op_isel (void)
  1276 +{
  1277 + if (T0)
  1278 + T0 = T1;
  1279 + else
  1280 + T0 = T2;
  1281 + RETURN();
  1282 +}
  1283 +
  1284 +void OPPROTO op_popcntb (void)
  1285 +{
  1286 + do_popcntb();
  1287 + RETURN();
  1288 +}
  1289 +
  1290 +#if defined(TARGET_PPC64)
  1291 +void OPPROTO op_popcntb_64 (void)
  1292 +{
  1293 + do_popcntb_64();
  1294 + RETURN();
  1295 +}
  1296 +#endif
904 1297
905 /*** Integer logical ***/ 1298 /*** Integer logical ***/
906 /* and */ 1299 /* and */
@@ -963,6 +1356,80 @@ void OPPROTO op_cntlzw (void) @@ -963,6 +1356,80 @@ void OPPROTO op_cntlzw (void)
963 RETURN(); 1356 RETURN();
964 } 1357 }
965 1358
  1359 +#if defined(TARGET_PPC64)
  1360 +void OPPROTO op_cntlzd (void)
  1361 +{
  1362 +#if HOST_LONG_BITS == 64
  1363 + int cnt;
  1364 +
  1365 + cnt = 0;
  1366 + if (!(T0 & 0xFFFFFFFF00000000ULL)) {
  1367 + cnt += 32;
  1368 + T0 <<= 32;
  1369 + }
  1370 + if (!(T0 & 0xFFFF000000000000ULL)) {
  1371 + cnt += 16;
  1372 + T0 <<= 16;
  1373 + }
  1374 + if (!(T0 & 0xFF00000000000000ULL)) {
  1375 + cnt += 8;
  1376 + T0 <<= 8;
  1377 + }
  1378 + if (!(T0 & 0xF000000000000000ULL)) {
  1379 + cnt += 4;
  1380 + T0 <<= 4;
  1381 + }
  1382 + if (!(T0 & 0xC000000000000000ULL)) {
  1383 + cnt += 2;
  1384 + T0 <<= 2;
  1385 + }
  1386 + if (!(T0 & 0x8000000000000000ULL)) {
  1387 + cnt++;
  1388 + T0 <<= 1;
  1389 + }
  1390 + if (!(T0 & 0x8000000000000000ULL)) {
  1391 + cnt++;
  1392 + }
  1393 + T0 = cnt;
  1394 +#else
  1395 + uint32_t tmp;
  1396 +
  1397 + /* Make it easier on 32 bits host machines */
  1398 + if (!(T0 >> 32)) {
  1399 + tmp = T0;
  1400 + T0 = 32;
  1401 + } else {
  1402 + tmp = T0 >> 32;
  1403 + T0 = 0;
  1404 + }
  1405 + if (!(tmp & 0xFFFF0000UL)) {
  1406 + T0 += 16;
  1407 + tmp <<= 16;
  1408 + }
  1409 + if (!(tmp & 0xFF000000UL)) {
  1410 + T0 += 8;
  1411 + tmp <<= 8;
  1412 + }
  1413 + if (!(tmp & 0xF0000000UL)) {
  1414 + T0 += 4;
  1415 + tmp <<= 4;
  1416 + }
  1417 + if (!(tmp & 0xC0000000UL)) {
  1418 + T0 += 2;
  1419 + tmp <<= 2;
  1420 + }
  1421 + if (!(tmp & 0x80000000UL)) {
  1422 + T0++;
  1423 + tmp <<= 1;
  1424 + }
  1425 + if (!(tmp & 0x80000000UL)) {
  1426 + T0++;
  1427 + }
  1428 +#endif
  1429 + RETURN();
  1430 +}
  1431 +#endif
  1432 +
966 /* eqv */ 1433 /* eqv */
967 PPC_OP(eqv) 1434 PPC_OP(eqv)
968 { 1435 {
@@ -971,19 +1438,35 @@ PPC_OP(eqv) @@ -971,19 +1438,35 @@ PPC_OP(eqv)
971 } 1438 }
972 1439
973 /* extend sign byte */ 1440 /* extend sign byte */
974 -PPC_OP(extsb) 1441 +void OPPROTO op_extsb (void)
975 { 1442 {
976 - T0 = (int32_t)((int8_t)(Ts0)); 1443 +#if defined (TARGET_PPC64)
  1444 + T0 = (int64_t)((int8_t)T0);
  1445 +#else
  1446 + T0 = (int32_t)((int8_t)T0);
  1447 +#endif
977 RETURN(); 1448 RETURN();
978 } 1449 }
979 1450
980 /* extend sign half word */ 1451 /* extend sign half word */
981 -PPC_OP(extsh) 1452 +void OPPROTO op_extsh (void)
982 { 1453 {
983 - T0 = (int32_t)((int16_t)(Ts0)); 1454 +#if defined (TARGET_PPC64)
  1455 + T0 = (int64_t)((int16_t)T0);
  1456 +#else
  1457 + T0 = (int32_t)((int16_t)T0);
  1458 +#endif
984 RETURN(); 1459 RETURN();
985 } 1460 }
986 1461
  1462 +#if defined (TARGET_PPC64)
  1463 +void OPPROTO op_extsw (void)
  1464 +{
  1465 + T0 = (int64_t)((int32_t)T0);
  1466 + RETURN();
  1467 +}
  1468 +#endif
  1469 +
987 /* nand */ 1470 /* nand */
988 PPC_OP(nand) 1471 PPC_OP(nand)
989 { 1472 {
@@ -1048,15 +1531,27 @@ void OPPROTO op_rotli32_T0 (void) @@ -1048,15 +1531,27 @@ void OPPROTO op_rotli32_T0 (void)
1048 1531
1049 /*** Integer shift ***/ 1532 /*** Integer shift ***/
1050 /* shift left word */ 1533 /* shift left word */
1051 -PPC_OP(slw) 1534 +void OPPROTO op_slw (void)
1052 { 1535 {
1053 if (T1 & 0x20) { 1536 if (T1 & 0x20) {
1054 T0 = 0; 1537 T0 = 0;
1055 } else { 1538 } else {
  1539 + T0 = (uint32_t)(T0 << T1);
  1540 + }
  1541 + RETURN();
  1542 +}
  1543 +
  1544 +#if defined(TARGET_PPC64)
  1545 +void OPPROTO op_sld (void)
  1546 +{
  1547 + if (T1 & 0x40) {
  1548 + T0 = 0;
  1549 + } else {
1056 T0 = T0 << T1; 1550 T0 = T0 << T1;
1057 } 1551 }
1058 RETURN(); 1552 RETURN();
1059 } 1553 }
  1554 +#endif
1060 1555
1061 /* shift right algebraic word */ 1556 /* shift right algebraic word */
1062 void OPPROTO op_sraw (void) 1557 void OPPROTO op_sraw (void)
@@ -1065,12 +1560,21 @@ void OPPROTO op_sraw (void) @@ -1065,12 +1560,21 @@ void OPPROTO op_sraw (void)
1065 RETURN(); 1560 RETURN();
1066 } 1561 }
1067 1562
  1563 +#if defined(TARGET_PPC64)
  1564 +void OPPROTO op_srad (void)
  1565 +{
  1566 + do_srad();
  1567 + RETURN();
  1568 +}
  1569 +#endif
  1570 +
1068 /* shift right algebraic word immediate */ 1571 /* shift right algebraic word immediate */
1069 -PPC_OP(srawi) 1572 +void OPPROTO op_srawi (void)
1070 { 1573 {
1071 - T1 = T0;  
1072 - T0 = (Ts0 >> PARAM(1));  
1073 - if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) { 1574 + uint32_t mask = (uint32_t)PARAM2;
  1575 +
  1576 + T0 = (int32_t)T0 >> PARAM1;
  1577 + if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1074 xer_ca = 1; 1578 xer_ca = 1;
1075 } else { 1579 } else {
1076 xer_ca = 0; 1580 xer_ca = 0;
@@ -1078,16 +1582,43 @@ PPC_OP(srawi) @@ -1078,16 +1582,43 @@ PPC_OP(srawi)
1078 RETURN(); 1582 RETURN();
1079 } 1583 }
1080 1584
  1585 +#if defined(TARGET_PPC64)
  1586 +void OPPROTO op_sradi (void)
  1587 +{
  1588 + uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
  1589 +
  1590 + T0 = (int64_t)T0 >> PARAM1;
  1591 + if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
  1592 + xer_ca = 1;
  1593 + } else {
  1594 + xer_ca = 0;
  1595 + }
  1596 + RETURN();
  1597 +}
  1598 +#endif
  1599 +
1081 /* shift right word */ 1600 /* shift right word */
1082 -PPC_OP(srw) 1601 +void OPPROTO op_srw (void)
1083 { 1602 {
1084 if (T1 & 0x20) { 1603 if (T1 & 0x20) {
1085 T0 = 0; 1604 T0 = 0;
1086 } else { 1605 } else {
1087 - T0 = T0 >> T1; 1606 + T0 = (uint32_t)T0 >> T1;
  1607 + }
  1608 + RETURN();
  1609 +}
  1610 +
  1611 +#if defined(TARGET_PPC64)
  1612 +void OPPROTO op_srd (void)
  1613 +{
  1614 + if (T1 & 0x40) {
  1615 + T0 = 0;
  1616 + } else {
  1617 + T0 = (uint64_t)T0 >> T1;
1088 } 1618 }
1089 RETURN(); 1619 RETURN();
1090 } 1620 }
  1621 +#endif
1091 1622
1092 void OPPROTO op_sl_T0_T1 (void) 1623 void OPPROTO op_sl_T0_T1 (void)
1093 { 1624 {
@@ -1103,22 +1634,46 @@ void OPPROTO op_sli_T0 (void) @@ -1103,22 +1634,46 @@ void OPPROTO op_sli_T0 (void)
1103 1634
1104 void OPPROTO op_srl_T0_T1 (void) 1635 void OPPROTO op_srl_T0_T1 (void)
1105 { 1636 {
1106 - T0 = T0 >> T1; 1637 + T0 = (uint32_t)T0 >> T1;
  1638 + RETURN();
  1639 +}
  1640 +
  1641 +#if defined(TARGET_PPC64)
  1642 +void OPPROTO op_srl_T0_T1_64 (void)
  1643 +{
  1644 + T0 = (uint32_t)T0 >> T1;
1107 RETURN(); 1645 RETURN();
1108 } 1646 }
  1647 +#endif
1109 1648
1110 void OPPROTO op_srli_T0 (void) 1649 void OPPROTO op_srli_T0 (void)
1111 { 1650 {
1112 - T0 = T0 >> PARAM1; 1651 + T0 = (uint32_t)T0 >> PARAM1;
1113 RETURN(); 1652 RETURN();
1114 } 1653 }
1115 1654
  1655 +#if defined(TARGET_PPC64)
  1656 +void OPPROTO op_srli_T0_64 (void)
  1657 +{
  1658 + T0 = (uint64_t)T0 >> PARAM1;
  1659 + RETURN();
  1660 +}
  1661 +#endif
  1662 +
1116 void OPPROTO op_srli_T1 (void) 1663 void OPPROTO op_srli_T1 (void)
1117 { 1664 {
1118 - T1 = T1 >> PARAM1; 1665 + T1 = (uint32_t)T1 >> PARAM1;
1119 RETURN(); 1666 RETURN();
1120 } 1667 }
1121 1668
  1669 +#if defined(TARGET_PPC64)
  1670 +void OPPROTO op_srli_T1_64 (void)
  1671 +{
  1672 + T1 = (uint64_t)T1 >> PARAM1;
  1673 + RETURN();
  1674 +}
  1675 +#endif
  1676 +
1122 /*** Floating-Point arithmetic ***/ 1677 /*** Floating-Point arithmetic ***/
1123 /* fadd - fadd. */ 1678 /* fadd - fadd. */
1124 PPC_OP(fadd) 1679 PPC_OP(fadd)
@@ -1281,13 +1836,22 @@ PPC_OP(fneg) @@ -1281,13 +1836,22 @@ PPC_OP(fneg)
1281 #endif 1836 #endif
1282 1837
1283 /* Special op to check and maybe clear reservation */ 1838 /* Special op to check and maybe clear reservation */
1284 -PPC_OP(check_reservation) 1839 +void OPPROTO op_check_reservation (void)
1285 { 1840 {
1286 if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003)) 1841 if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1287 env->reserve = -1; 1842 env->reserve = -1;
1288 RETURN(); 1843 RETURN();
1289 } 1844 }
1290 1845
  1846 +#if defined(TARGET_PPC64)
  1847 +void OPPROTO op_check_reservation_64 (void)
  1848 +{
  1849 + if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
  1850 + env->reserve = -1;
  1851 + RETURN();
  1852 +}
  1853 +#endif
  1854 +
1291 /* Return from interrupt */ 1855 /* Return from interrupt */
1292 #if !defined(CONFIG_USER_ONLY) 1856 #if !defined(CONFIG_USER_ONLY)
1293 void OPPROTO op_rfi (void) 1857 void OPPROTO op_rfi (void)
@@ -1295,6 +1859,14 @@ void OPPROTO op_rfi (void) @@ -1295,6 +1859,14 @@ void OPPROTO op_rfi (void)
1295 do_rfi(); 1859 do_rfi();
1296 RETURN(); 1860 RETURN();
1297 } 1861 }
  1862 +
  1863 +#if defined(TARGET_PPC64)
  1864 +void OPPROTO op_rfi_32 (void)
  1865 +{
  1866 + do_rfi_32();
  1867 + RETURN();
  1868 +}
  1869 +#endif
1298 #endif 1870 #endif
1299 1871
1300 /* Trap word */ 1872 /* Trap word */
@@ -1304,13 +1876,29 @@ void OPPROTO op_tw (void) @@ -1304,13 +1876,29 @@ void OPPROTO op_tw (void)
1304 RETURN(); 1876 RETURN();
1305 } 1877 }
1306 1878
  1879 +#if defined(TARGET_PPC64)
  1880 +void OPPROTO op_td (void)
  1881 +{
  1882 + do_td(PARAM1);
  1883 + RETURN();
  1884 +}
  1885 +#endif
  1886 +
1307 /* Instruction cache block invalidate */ 1887 /* Instruction cache block invalidate */
1308 -PPC_OP(icbi) 1888 +void OPPROTO op_icbi (void)
1309 { 1889 {
1310 do_icbi(); 1890 do_icbi();
1311 RETURN(); 1891 RETURN();
1312 } 1892 }
1313 1893
  1894 +#if defined(TARGET_PPC64)
  1895 +void OPPROTO op_icbi_64 (void)
  1896 +{
  1897 + do_icbi_64();
  1898 + RETURN();
  1899 +}
  1900 +#endif
  1901 +
1314 #if !defined(CONFIG_USER_ONLY) 1902 #if !defined(CONFIG_USER_ONLY)
1315 /* tlbia */ 1903 /* tlbia */
1316 PPC_OP(tlbia) 1904 PPC_OP(tlbia)
@@ -1320,11 +1908,33 @@ PPC_OP(tlbia) @@ -1320,11 +1908,33 @@ PPC_OP(tlbia)
1320 } 1908 }
1321 1909
1322 /* tlbie */ 1910 /* tlbie */
1323 -PPC_OP(tlbie) 1911 +void OPPROTO op_tlbie (void)
1324 { 1912 {
1325 do_tlbie(); 1913 do_tlbie();
1326 RETURN(); 1914 RETURN();
1327 } 1915 }
  1916 +
  1917 +#if defined(TARGET_PPC64)
  1918 +void OPPROTO op_tlbie_64 (void)
  1919 +{
  1920 + do_tlbie_64();
  1921 + RETURN();
  1922 +}
  1923 +#endif
  1924 +
  1925 +#if defined(TARGET_PPC64)
  1926 +void OPPROTO op_slbia (void)
  1927 +{
  1928 + do_slbia();
  1929 + RETURN();
  1930 +}
  1931 +
  1932 +void OPPROTO op_slbie (void)
  1933 +{
  1934 + do_slbie();
  1935 + RETURN();
  1936 +}
  1937 +#endif
1328 #endif 1938 #endif
1329 1939
1330 /* PowerPC 602/603/755 software TLB load instructions */ 1940 /* PowerPC 602/603/755 software TLB load instructions */
@@ -1343,14 +1953,12 @@ void OPPROTO op_6xx_tlbli (void) @@ -1343,14 +1953,12 @@ void OPPROTO op_6xx_tlbli (void)
1343 #endif 1953 #endif
1344 1954
1345 /* 601 specific */ 1955 /* 601 specific */
1346 -uint32_t cpu_ppc601_load_rtcl (CPUState *env);  
1347 void OPPROTO op_load_601_rtcl (void) 1956 void OPPROTO op_load_601_rtcl (void)
1348 { 1957 {
1349 T0 = cpu_ppc601_load_rtcl(env); 1958 T0 = cpu_ppc601_load_rtcl(env);
1350 RETURN(); 1959 RETURN();
1351 } 1960 }
1352 1961
1353 -uint32_t cpu_ppc601_load_rtcu (CPUState *env);  
1354 void OPPROTO op_load_601_rtcu (void) 1962 void OPPROTO op_load_601_rtcu (void)
1355 { 1963 {
1356 T0 = cpu_ppc601_load_rtcu(env); 1964 T0 = cpu_ppc601_load_rtcu(env);
@@ -1358,14 +1966,12 @@ void OPPROTO op_load_601_rtcu (void) @@ -1358,14 +1966,12 @@ void OPPROTO op_load_601_rtcu (void)
1358 } 1966 }
1359 1967
1360 #if !defined(CONFIG_USER_ONLY) 1968 #if !defined(CONFIG_USER_ONLY)
1361 -void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value);  
1362 void OPPROTO op_store_601_rtcl (void) 1969 void OPPROTO op_store_601_rtcl (void)
1363 { 1970 {
1364 cpu_ppc601_store_rtcl(env, T0); 1971 cpu_ppc601_store_rtcl(env, T0);
1365 RETURN(); 1972 RETURN();
1366 } 1973 }
1367 1974
1368 -void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value);  
1369 void OPPROTO op_store_601_rtcu (void) 1975 void OPPROTO op_store_601_rtcu (void)
1370 { 1976 {
1371 cpu_ppc601_store_rtcu(env, T0); 1977 cpu_ppc601_store_rtcu(env, T0);
@@ -1449,7 +2055,7 @@ void OPPROTO op_POWER_divso (void) @@ -1449,7 +2055,7 @@ void OPPROTO op_POWER_divso (void)
1449 2055
1450 void OPPROTO op_POWER_doz (void) 2056 void OPPROTO op_POWER_doz (void)
1451 { 2057 {
1452 - if (Ts1 > Ts0) 2058 + if ((int32_t)T1 > (int32_t)T0)
1453 T0 = T1 - T0; 2059 T0 = T1 - T0;
1454 else 2060 else
1455 T0 = 0; 2061 T0 = 0;
@@ -1580,7 +2186,7 @@ void OPPROTO op_POWER_sraq (void) @@ -1580,7 +2186,7 @@ void OPPROTO op_POWER_sraq (void)
1580 if (T1 & 0x20UL) 2186 if (T1 & 0x20UL)
1581 T0 = -1L; 2187 T0 = -1L;
1582 else 2188 else
1583 - T0 = Ts0 >> T1; 2189 + T0 = (int32_t)T0 >> T1;
1584 RETURN(); 2190 RETURN();
1585 } 2191 }
1586 2192
@@ -1588,7 +2194,7 @@ void OPPROTO op_POWER_sre (void) @@ -1588,7 +2194,7 @@ void OPPROTO op_POWER_sre (void)
1588 { 2194 {
1589 T1 &= 0x1FUL; 2195 T1 &= 0x1FUL;
1590 env->spr[SPR_MQ] = rotl32(T0, 32 - T1); 2196 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
1591 - T0 = Ts0 >> T1; 2197 + T0 = (int32_t)T0 >> T1;
1592 RETURN(); 2198 RETURN();
1593 } 2199 }
1594 2200
@@ -1596,7 +2202,7 @@ void OPPROTO op_POWER_srea (void) @@ -1596,7 +2202,7 @@ void OPPROTO op_POWER_srea (void)
1596 { 2202 {
1597 T1 &= 0x1FUL; 2203 T1 &= 0x1FUL;
1598 env->spr[SPR_MQ] = T0 >> T1; 2204 env->spr[SPR_MQ] = T0 >> T1;
1599 - T0 = Ts0 >> T1; 2205 + T0 = (int32_t)T0 >> T1;
1600 RETURN(); 2206 RETURN();
1601 } 2207 }
1602 2208
@@ -1848,28 +2454,24 @@ void OPPROTO op_store_403_pb (void) @@ -1848,28 +2454,24 @@ void OPPROTO op_store_403_pb (void)
1848 RETURN(); 2454 RETURN();
1849 } 2455 }
1850 2456
1851 -target_ulong load_40x_pit (CPUState *env);  
1852 void OPPROTO op_load_40x_pit (void) 2457 void OPPROTO op_load_40x_pit (void)
1853 { 2458 {
1854 T0 = load_40x_pit(env); 2459 T0 = load_40x_pit(env);
1855 RETURN(); 2460 RETURN();
1856 } 2461 }
1857 2462
1858 -void store_40x_pit (CPUState *env, target_ulong val);  
1859 void OPPROTO op_store_40x_pit (void) 2463 void OPPROTO op_store_40x_pit (void)
1860 { 2464 {
1861 store_40x_pit(env, T0); 2465 store_40x_pit(env, T0);
1862 RETURN(); 2466 RETURN();
1863 } 2467 }
1864 2468
1865 -void store_booke_tcr (CPUState *env, target_ulong val);  
1866 void OPPROTO op_store_booke_tcr (void) 2469 void OPPROTO op_store_booke_tcr (void)
1867 { 2470 {
1868 store_booke_tcr(env, T0); 2471 store_booke_tcr(env, T0);
1869 RETURN(); 2472 RETURN();
1870 } 2473 }
1871 2474
1872 -void store_booke_tsr (CPUState *env, target_ulong val);  
1873 void OPPROTO op_store_booke_tsr (void) 2475 void OPPROTO op_store_booke_tsr (void)
1874 { 2476 {
1875 store_booke_tsr(env, T0); 2477 store_booke_tsr(env, T0);
target-ppc/op_helper.c
@@ -33,10 +33,6 @@ @@ -33,10 +33,6 @@
33 //#define DEBUG_SOFTWARE_TLB 33 //#define DEBUG_SOFTWARE_TLB
34 //#define FLUSH_ALL_TLBS 34 //#define FLUSH_ALL_TLBS
35 35
36 -#define Ts0 (long)((target_long)T0)  
37 -#define Ts1 (long)((target_long)T1)  
38 -#define Ts2 (long)((target_long)T2)  
39 -  
40 /*****************************************************************************/ 36 /*****************************************************************************/
41 /* Exceptions processing helpers */ 37 /* Exceptions processing helpers */
42 void cpu_loop_exit (void) 38 void cpu_loop_exit (void)
@@ -106,7 +102,7 @@ void do_store_xer (void) @@ -106,7 +102,7 @@ void do_store_xer (void)
106 xer_ov = (T0 >> XER_OV) & 0x01; 102 xer_ov = (T0 >> XER_OV) & 0x01;
107 xer_ca = (T0 >> XER_CA) & 0x01; 103 xer_ca = (T0 >> XER_CA) & 0x01;
108 xer_cmp = (T0 >> XER_CMP) & 0xFF; 104 xer_cmp = (T0 >> XER_CMP) & 0xFF;
109 - xer_bc = (T0 >> XER_BC) & 0x3F; 105 + xer_bc = (T0 >> XER_BC) & 0x7F;
110 } 106 }
111 107
112 void do_load_fpscr (void) 108 void do_load_fpscr (void)
@@ -122,7 +118,7 @@ void do_load_fpscr (void) @@ -122,7 +118,7 @@ void do_load_fpscr (void)
122 } u; 118 } u;
123 int i; 119 int i;
124 120
125 -#ifdef WORDS_BIGENDIAN 121 +#if defined(WORDS_BIGENDIAN)
126 #define WORD0 0 122 #define WORD0 0
127 #define WORD1 1 123 #define WORD1 1
128 #else 124 #else
@@ -182,68 +178,110 @@ void do_store_fpscr (uint32_t mask) @@ -182,68 +178,110 @@ void do_store_fpscr (uint32_t mask)
182 178
183 /*****************************************************************************/ 179 /*****************************************************************************/
184 /* Fixed point operations helpers */ 180 /* Fixed point operations helpers */
185 -void do_addo (void) 181 +#if defined(TARGET_PPC64)
  182 +static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
186 { 183 {
187 - T2 = T0;  
188 - T0 += T1;  
189 - if (likely(!((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)))) {  
190 - xer_ov = 0;  
191 - } else {  
192 - xer_so = 1;  
193 - xer_ov = 1;  
194 - } 184 + *plow += a;
  185 + /* carry test */
  186 + if (*plow < a)
  187 + (*phigh)++;
  188 + *phigh += b;
195 } 189 }
196 190
197 -void do_addco (void) 191 +static void neg128 (uint64_t *plow, uint64_t *phigh)
198 { 192 {
199 - T2 = T0;  
200 - T0 += T1;  
201 - if (likely(T0 >= T2)) {  
202 - xer_ca = 0;  
203 - } else {  
204 - xer_ca = 1;  
205 - }  
206 - if (likely(!((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)))) {  
207 - xer_ov = 0;  
208 - } else {  
209 - xer_so = 1;  
210 - xer_ov = 1; 193 + *plow = ~ *plow;
  194 + *phigh = ~ *phigh;
  195 + add128(plow, phigh, 1, 0);
  196 +}
  197 +
  198 +static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
  199 +{
  200 + uint32_t a0, a1, b0, b1;
  201 + uint64_t v;
  202 +
  203 + a0 = a;
  204 + a1 = a >> 32;
  205 +
  206 + b0 = b;
  207 + b1 = b >> 32;
  208 +
  209 + v = (uint64_t)a0 * (uint64_t)b0;
  210 + *plow = v;
  211 + *phigh = 0;
  212 +
  213 + v = (uint64_t)a0 * (uint64_t)b1;
  214 + add128(plow, phigh, v << 32, v >> 32);
  215 +
  216 + v = (uint64_t)a1 * (uint64_t)b0;
  217 + add128(plow, phigh, v << 32, v >> 32);
  218 +
  219 + v = (uint64_t)a1 * (uint64_t)b1;
  220 + *phigh += v;
  221 +#if defined(DEBUG_MULDIV)
  222 + printf("mul: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
  223 + a, b, *phigh, *plow);
  224 +#endif
  225 +}
  226 +
  227 +void do_mul64 (uint64_t *plow, uint64_t *phigh)
  228 +{
  229 + mul64(plow, phigh, T0, T1);
  230 +}
  231 +
  232 +static void imul64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
  233 +{
  234 + int sa, sb;
  235 + sa = (a < 0);
  236 + if (sa)
  237 + a = -a;
  238 + sb = (b < 0);
  239 + if (sb)
  240 + b = -b;
  241 + mul64(plow, phigh, a, b);
  242 + if (sa ^ sb) {
  243 + neg128(plow, phigh);
211 } 244 }
212 } 245 }
213 246
  247 +void do_imul64 (uint64_t *plow, uint64_t *phigh)
  248 +{
  249 + imul64(plow, phigh, T0, T1);
  250 +}
  251 +#endif
  252 +
214 void do_adde (void) 253 void do_adde (void)
215 { 254 {
216 T2 = T0; 255 T2 = T0;
217 T0 += T1 + xer_ca; 256 T0 += T1 + xer_ca;
218 - if (likely(!(T0 < T2 || (xer_ca == 1 && T0 == T2)))) { 257 + if (likely(!((uint32_t)T0 < (uint32_t)T2 ||
  258 + (xer_ca == 1 && (uint32_t)T0 == (uint32_t)T2)))) {
219 xer_ca = 0; 259 xer_ca = 0;
220 } else { 260 } else {
221 xer_ca = 1; 261 xer_ca = 1;
222 } 262 }
223 } 263 }
224 264
225 -void do_addeo (void) 265 +#if defined(TARGET_PPC64)
  266 +void do_adde_64 (void)
226 { 267 {
227 T2 = T0; 268 T2 = T0;
228 T0 += T1 + xer_ca; 269 T0 += T1 + xer_ca;
229 - if (likely(!(T0 < T2 || (xer_ca == 1 && T0 == T2)))) { 270 + if (likely(!((uint64_t)T0 < (uint64_t)T2 ||
  271 + (xer_ca == 1 && (uint64_t)T0 == (uint64_t)T2)))) {
230 xer_ca = 0; 272 xer_ca = 0;
231 } else { 273 } else {
232 xer_ca = 1; 274 xer_ca = 1;
233 } 275 }
234 - if (likely(!((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)))) {  
235 - xer_ov = 0;  
236 - } else {  
237 - xer_so = 1;  
238 - xer_ov = 1;  
239 - }  
240 } 276 }
  277 +#endif
241 278
242 void do_addmeo (void) 279 void do_addmeo (void)
243 { 280 {
244 T1 = T0; 281 T1 = T0;
245 T0 += xer_ca + (-1); 282 T0 += xer_ca + (-1);
246 - if (likely(!(T1 & (T1 ^ T0) & (1 << 31)))) { 283 + if (likely(!((uint32_t)T1 &
  284 + ((uint32_t)T1 ^ (uint32_t)T0) & (1UL << 31)))) {
247 xer_ov = 0; 285 xer_ov = 0;
248 } else { 286 } else {
249 xer_so = 1; 287 xer_so = 1;
@@ -253,28 +291,29 @@ void do_addmeo (void) @@ -253,28 +291,29 @@ void do_addmeo (void)
253 xer_ca = 1; 291 xer_ca = 1;
254 } 292 }
255 293
256 -void do_addzeo (void) 294 +#if defined(TARGET_PPC64)
  295 +void do_addmeo_64 (void)
257 { 296 {
258 T1 = T0; 297 T1 = T0;
259 - T0 += xer_ca;  
260 - if (likely(!((T1 ^ (-1)) & (T1 ^ T0) & (1 << 31)))) { 298 + T0 += xer_ca + (-1);
  299 + if (likely(!((uint64_t)T1 &
  300 + ((uint64_t)T1 ^ (uint64_t)T0) & (1ULL << 63)))) {
261 xer_ov = 0; 301 xer_ov = 0;
262 } else { 302 } else {
263 xer_so = 1; 303 xer_so = 1;
264 xer_ov = 1; 304 xer_ov = 1;
265 } 305 }
266 - if (likely(T0 >= T1)) {  
267 - xer_ca = 0;  
268 - } else { 306 + if (likely(T1 != 0))
269 xer_ca = 1; 307 xer_ca = 1;
270 - }  
271 } 308 }
  309 +#endif
272 310
273 void do_divwo (void) 311 void do_divwo (void)
274 { 312 {
275 - if (likely(!((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0))) { 313 + if (likely(!(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
  314 + (int32_t)T1 == 0))) {
276 xer_ov = 0; 315 xer_ov = 0;
277 - T0 = (Ts0 / Ts1); 316 + T0 = (int32_t)T0 / (int32_t)T1;
278 } else { 317 } else {
279 xer_so = 1; 318 xer_so = 1;
280 xer_ov = 1; 319 xer_ov = 1;
@@ -282,6 +321,21 @@ void do_divwo (void) @@ -282,6 +321,21 @@ void do_divwo (void)
282 } 321 }
283 } 322 }
284 323
  324 +#if defined(TARGET_PPC64)
  325 +void do_divdo (void)
  326 +{
  327 + if (likely(!(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1ULL) ||
  328 + (int64_t)T1 == 0))) {
  329 + xer_ov = 0;
  330 + T0 = (int64_t)T0 / (int64_t)T1;
  331 + } else {
  332 + xer_so = 1;
  333 + xer_ov = 1;
  334 + T0 = (-1ULL) * ((uint64_t)T0 >> 63);
  335 + }
  336 +}
  337 +#endif
  338 +
285 void do_divwuo (void) 339 void do_divwuo (void)
286 { 340 {
287 if (likely((uint32_t)T1 != 0)) { 341 if (likely((uint32_t)T1 != 0)) {
@@ -294,9 +348,23 @@ void do_divwuo (void) @@ -294,9 +348,23 @@ void do_divwuo (void)
294 } 348 }
295 } 349 }
296 350
  351 +#if defined(TARGET_PPC64)
  352 +void do_divduo (void)
  353 +{
  354 + if (likely((uint64_t)T1 != 0)) {
  355 + xer_ov = 0;
  356 + T0 = (uint64_t)T0 / (uint64_t)T1;
  357 + } else {
  358 + xer_so = 1;
  359 + xer_ov = 1;
  360 + T0 = 0;
  361 + }
  362 +}
  363 +#endif
  364 +
297 void do_mullwo (void) 365 void do_mullwo (void)
298 { 366 {
299 - int64_t res = (int64_t)Ts0 * (int64_t)Ts1; 367 + int64_t res = (int64_t)T0 * (int64_t)T1;
300 368
301 if (likely((int32_t)res == res)) { 369 if (likely((int32_t)res == res)) {
302 xer_ov = 0; 370 xer_ov = 0;
@@ -307,112 +375,148 @@ void do_mullwo (void) @@ -307,112 +375,148 @@ void do_mullwo (void)
307 T0 = (int32_t)res; 375 T0 = (int32_t)res;
308 } 376 }
309 377
310 -void do_nego (void) 378 +#if defined(TARGET_PPC64)
  379 +void do_mulldo (void)
311 { 380 {
312 - if (likely(T0 != INT32_MIN)) { 381 + int64_t th;
  382 + uint64_t tl;
  383 +
  384 + do_imul64(&tl, &th);
  385 + if (likely(th == 0)) {
313 xer_ov = 0; 386 xer_ov = 0;
314 - T0 = -Ts0;  
315 } else { 387 } else {
316 xer_ov = 1; 388 xer_ov = 1;
317 xer_so = 1; 389 xer_so = 1;
318 } 390 }
  391 + T0 = (int64_t)tl;
319 } 392 }
  393 +#endif
320 394
321 -void do_subfo (void) 395 +void do_nego (void)
322 { 396 {
323 - T2 = T0;  
324 - T0 = T1 - T0;  
325 - if (likely(!(((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)))) { 397 + if (likely((int32_t)T0 != INT32_MIN)) {
326 xer_ov = 0; 398 xer_ov = 0;
  399 + T0 = -(int32_t)T0;
327 } else { 400 } else {
328 - xer_so = 1;  
329 xer_ov = 1; 401 xer_ov = 1;
  402 + xer_so = 1;
330 } 403 }
331 - RETURN();  
332 } 404 }
333 405
334 -void do_subfco (void) 406 +#if defined(TARGET_PPC64)
  407 +void do_nego_64 (void)
335 { 408 {
336 - T2 = T0;  
337 - T0 = T1 - T0;  
338 - if (likely(T0 > T1)) {  
339 - xer_ca = 0;  
340 - } else {  
341 - xer_ca = 1;  
342 - }  
343 - if (likely(!(((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)))) { 409 + if (likely((int64_t)T0 != INT64_MIN)) {
344 xer_ov = 0; 410 xer_ov = 0;
  411 + T0 = -(int64_t)T0;
345 } else { 412 } else {
346 - xer_so = 1;  
347 xer_ov = 1; 413 xer_ov = 1;
  414 + xer_so = 1;
348 } 415 }
349 } 416 }
  417 +#endif
350 418
351 void do_subfe (void) 419 void do_subfe (void)
352 { 420 {
353 T0 = T1 + ~T0 + xer_ca; 421 T0 = T1 + ~T0 + xer_ca;
354 - if (likely(T0 >= T1 && (xer_ca == 0 || T0 != T1))) { 422 + if (likely((uint32_t)T0 >= (uint32_t)T1 &&
  423 + (xer_ca == 0 || (uint32_t)T0 != (uint32_t)T1))) {
355 xer_ca = 0; 424 xer_ca = 0;
356 } else { 425 } else {
357 xer_ca = 1; 426 xer_ca = 1;
358 } 427 }
359 } 428 }
360 429
361 -void do_subfeo (void) 430 +#if defined(TARGET_PPC64)
  431 +void do_subfe_64 (void)
362 { 432 {
363 - T2 = T0;  
364 T0 = T1 + ~T0 + xer_ca; 433 T0 = T1 + ~T0 + xer_ca;
365 - if (likely(!((~T2 ^ T1 ^ (-1)) & (~T2 ^ T0) & (1 << 31)))) { 434 + if (likely((uint64_t)T0 >= (uint64_t)T1 &&
  435 + (xer_ca == 0 || (uint64_t)T0 != (uint64_t)T1))) {
  436 + xer_ca = 0;
  437 + } else {
  438 + xer_ca = 1;
  439 + }
  440 +}
  441 +#endif
  442 +
  443 +void do_subfmeo (void)
  444 +{
  445 + T1 = T0;
  446 + T0 = ~T0 + xer_ca - 1;
  447 + if (likely(!((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0) &
  448 + (1UL << 31)))) {
366 xer_ov = 0; 449 xer_ov = 0;
367 } else { 450 } else {
368 xer_so = 1; 451 xer_so = 1;
369 xer_ov = 1; 452 xer_ov = 1;
370 } 453 }
371 - if (likely(T0 >= T1 && (xer_ca == 0 || T0 != T1))) {  
372 - xer_ca = 0;  
373 - } else { 454 + if (likely((uint32_t)T1 != UINT32_MAX))
374 xer_ca = 1; 455 xer_ca = 1;
375 - }  
376 } 456 }
377 457
378 -void do_subfmeo (void) 458 +#if defined(TARGET_PPC64)
  459 +void do_subfmeo_64 (void)
379 { 460 {
380 T1 = T0; 461 T1 = T0;
381 T0 = ~T0 + xer_ca - 1; 462 T0 = ~T0 + xer_ca - 1;
382 - if (likely(!(~T1 & (~T1 ^ T0) & (1 << 31)))) { 463 + if (likely(!((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0) &
  464 + (1ULL << 63)))) {
383 xer_ov = 0; 465 xer_ov = 0;
384 } else { 466 } else {
385 xer_so = 1; 467 xer_so = 1;
386 xer_ov = 1; 468 xer_ov = 1;
387 } 469 }
388 - if (likely(T1 != -1)) 470 + if (likely((uint64_t)T1 != UINT64_MAX))
389 xer_ca = 1; 471 xer_ca = 1;
390 } 472 }
  473 +#endif
391 474
392 void do_subfzeo (void) 475 void do_subfzeo (void)
393 { 476 {
394 T1 = T0; 477 T1 = T0;
395 T0 = ~T0 + xer_ca; 478 T0 = ~T0 + xer_ca;
396 - if (likely(!((~T1 ^ (-1)) & ((~T1) ^ T0) & (1 << 31)))) { 479 + if (likely(!(((uint32_t)~T1 ^ UINT32_MAX) &
  480 + ((uint32_t)(~T1) ^ (uint32_t)T0) & (1UL << 31)))) {
397 xer_ov = 0; 481 xer_ov = 0;
398 } else { 482 } else {
399 xer_ov = 1; 483 xer_ov = 1;
400 xer_so = 1; 484 xer_so = 1;
401 } 485 }
402 - if (likely(T0 >= ~T1)) { 486 + if (likely((uint32_t)T0 >= (uint32_t)~T1)) {
403 xer_ca = 0; 487 xer_ca = 0;
404 } else { 488 } else {
405 xer_ca = 1; 489 xer_ca = 1;
406 } 490 }
407 } 491 }
408 492
  493 +#if defined(TARGET_PPC64)
  494 +void do_subfzeo_64 (void)
  495 +{
  496 + T1 = T0;
  497 + T0 = ~T0 + xer_ca;
  498 + if (likely(!(((uint64_t)~T1 ^ UINT64_MAX) &
  499 + ((uint64_t)(~T1) ^ (uint64_t)T0) & (1ULL << 63)))) {
  500 + xer_ov = 0;
  501 + } else {
  502 + xer_ov = 1;
  503 + xer_so = 1;
  504 + }
  505 + if (likely((uint64_t)T0 >= (uint64_t)~T1)) {
  506 + xer_ca = 0;
  507 + } else {
  508 + xer_ca = 1;
  509 + }
  510 +}
  511 +#endif
  512 +
409 /* shift right arithmetic helper */ 513 /* shift right arithmetic helper */
410 void do_sraw (void) 514 void do_sraw (void)
411 { 515 {
412 int32_t ret; 516 int32_t ret;
413 517
414 if (likely(!(T1 & 0x20UL))) { 518 if (likely(!(T1 & 0x20UL))) {
415 - if (likely(T1 != 0)) { 519 + if (likely((uint32_t)T1 != 0)) {
416 ret = (int32_t)T0 >> (T1 & 0x1fUL); 520 ret = (int32_t)T0 >> (T1 & 0x1fUL);
417 if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) { 521 if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) {
418 xer_ca = 0; 522 xer_ca = 0;
@@ -434,6 +538,69 @@ void do_sraw (void) @@ -434,6 +538,69 @@ void do_sraw (void)
434 T0 = ret; 538 T0 = ret;
435 } 539 }
436 540
  541 +#if defined(TARGET_PPC64)
  542 +void do_srad (void)
  543 +{
  544 + int64_t ret;
  545 +
  546 + if (likely(!(T1 & 0x40UL))) {
  547 + if (likely((uint64_t)T1 != 0)) {
  548 + ret = (int64_t)T0 >> (T1 & 0x3FUL);
  549 + if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) {
  550 + xer_ca = 0;
  551 + } else {
  552 + xer_ca = 1;
  553 + }
  554 + } else {
  555 + ret = T0;
  556 + xer_ca = 0;
  557 + }
  558 + } else {
  559 + ret = (-1) * ((uint64_t)T0 >> 63);
  560 + if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) {
  561 + xer_ca = 0;
  562 + } else {
  563 + xer_ca = 1;
  564 + }
  565 + }
  566 + T0 = ret;
  567 +}
  568 +#endif
  569 +
  570 +static inline int popcnt (uint32_t val)
  571 +{
  572 + int i;
  573 +
  574 + for (i = 0; val != 0;)
  575 + val = val ^ (val - 1);
  576 +
  577 + return i;
  578 +}
  579 +
  580 +void do_popcntb (void)
  581 +{
  582 + uint32_t ret;
  583 + int i;
  584 +
  585 + ret = 0;
  586 + for (i = 0; i < 32; i += 8)
  587 + ret |= popcnt((T0 >> i) & 0xFF) << i;
  588 + T0 = ret;
  589 +}
  590 +
  591 +#if defined(TARGET_PPC64)
  592 +void do_popcntb_64 (void)
  593 +{
  594 + uint64_t ret;
  595 + int i;
  596 +
  597 + ret = 0;
  598 + for (i = 0; i < 64; i += 8)
  599 + ret |= popcnt((T0 >> i) & 0xFF) << i;
  600 + T0 = ret;
  601 +}
  602 +#endif
  603 +
437 /*****************************************************************************/ 604 /*****************************************************************************/
438 /* Floating point operations helpers */ 605 /* Floating point operations helpers */
439 void do_fctiw (void) 606 void do_fctiw (void)
@@ -459,7 +626,7 @@ void do_fctiwz (void) @@ -459,7 +626,7 @@ void do_fctiwz (void)
459 } p; 626 } p;
460 627
461 /* XXX: higher bits are not supposed to be significant. 628 /* XXX: higher bits are not supposed to be significant.
462 - * to make tests easier, return the same as a real PowerPC 750 (aka G3) 629 + * to make tests easier, return the same as a real PowerPC 750 (aka G3)
463 */ 630 */
464 p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status); 631 p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);
465 p.i |= 0xFFF80000ULL << 32; 632 p.i |= 0xFFF80000ULL << 32;
@@ -596,26 +763,51 @@ void do_fcmpo (void) @@ -596,26 +763,51 @@ void do_fcmpo (void)
596 #if !defined (CONFIG_USER_ONLY) 763 #if !defined (CONFIG_USER_ONLY)
597 void do_rfi (void) 764 void do_rfi (void)
598 { 765 {
599 - env->nip = env->spr[SPR_SRR0] & ~0x00000003;  
600 - T0 = env->spr[SPR_SRR1] & ~0xFFFF0000UL; 766 + env->nip = (target_ulong)(env->spr[SPR_SRR0] & ~0x00000003);
  767 + T0 = (target_ulong)(env->spr[SPR_SRR1] & ~0xFFFF0000UL);
601 do_store_msr(env, T0); 768 do_store_msr(env, T0);
602 #if defined (DEBUG_OP) 769 #if defined (DEBUG_OP)
603 dump_rfi(); 770 dump_rfi();
604 #endif 771 #endif
605 env->interrupt_request |= CPU_INTERRUPT_EXITTB; 772 env->interrupt_request |= CPU_INTERRUPT_EXITTB;
606 } 773 }
  774 +
  775 +#if defined(TARGET_PPC64)
  776 +void do_rfi_32 (void)
  777 +{
  778 + env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
  779 + T0 = (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL);
  780 + do_store_msr(env, T0);
  781 +#if defined (DEBUG_OP)
  782 + dump_rfi();
  783 +#endif
  784 + env->interrupt_request |= CPU_INTERRUPT_EXITTB;
  785 +}
  786 +#endif
607 #endif 787 #endif
608 788
609 void do_tw (int flags) 789 void do_tw (int flags)
610 { 790 {
611 - if (!likely(!((Ts0 < Ts1 && (flags & 0x10)) ||  
612 - (Ts0 > Ts1 && (flags & 0x08)) ||  
613 - (Ts0 == Ts1 && (flags & 0x04)) ||  
614 - (T0 < T1 && (flags & 0x02)) ||  
615 - (T0 > T1 && (flags & 0x01))))) 791 + if (!likely(!(((int32_t)T0 < (int32_t)T1 && (flags & 0x10)) ||
  792 + ((int32_t)T0 > (int32_t)T1 && (flags & 0x08)) ||
  793 + ((int32_t)T0 == (int32_t)T1 && (flags & 0x04)) ||
  794 + ((uint32_t)T0 < (uint32_t)T1 && (flags & 0x02)) ||
  795 + ((uint32_t)T0 > (uint32_t)T1 && (flags & 0x01)))))
616 do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP); 796 do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP);
617 } 797 }
618 798
  799 +#if defined(TARGET_PPC64)
  800 +void do_td (int flags)
  801 +{
  802 + if (!likely(!(((int64_t)T0 < (int64_t)T1 && (flags & 0x10)) ||
  803 + ((int64_t)T0 > (int64_t)T1 && (flags & 0x08)) ||
  804 + ((int64_t)T0 == (int64_t)T1 && (flags & 0x04)) ||
  805 + ((uint64_t)T0 < (uint64_t)T1 && (flags & 0x02)) ||
  806 + ((uint64_t)T0 > (uint64_t)T1 && (flags & 0x01)))))
  807 + do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP);
  808 +}
  809 +#endif
  810 +
619 /* Instruction cache invalidation helper */ 811 /* Instruction cache invalidation helper */
620 void do_icbi (void) 812 void do_icbi (void)
621 { 813 {
@@ -625,20 +817,31 @@ void do_icbi (void) @@ -625,20 +817,31 @@ void do_icbi (void)
625 * (not a fetch) by the MMU. To be sure it will be so, 817 * (not a fetch) by the MMU. To be sure it will be so,
626 * do the load "by hand". 818 * do the load "by hand".
627 */ 819 */
  820 + tmp = ldl_kernel((uint32_t)T0);
  821 + T0 &= ~(ICACHE_LINE_SIZE - 1);
  822 + tb_invalidate_page_range((uint32_t)T0, (uint32_t)(T0 + ICACHE_LINE_SIZE));
  823 +}
  824 +
628 #if defined(TARGET_PPC64) 825 #if defined(TARGET_PPC64)
629 - if (!msr_sf)  
630 - T0 &= 0xFFFFFFFFULL;  
631 -#endif  
632 - tmp = ldl_kernel(T0); 826 +void do_icbi_64 (void)
  827 +{
  828 + uint64_t tmp;
  829 + /* Invalidate one cache line :
  830 + * PowerPC specification says this is to be treated like a load
  831 + * (not a fetch) by the MMU. To be sure it will be so,
  832 + * do the load "by hand".
  833 + */
  834 + tmp = ldq_kernel((uint64_t)T0);
633 T0 &= ~(ICACHE_LINE_SIZE - 1); 835 T0 &= ~(ICACHE_LINE_SIZE - 1);
634 - tb_invalidate_page_range(T0, T0 + ICACHE_LINE_SIZE); 836 + tb_invalidate_page_range((uint64_t)T0, (uint64_t)(T0 + ICACHE_LINE_SIZE));
635 } 837 }
  838 +#endif
636 839
637 /*****************************************************************************/ 840 /*****************************************************************************/
638 /* PowerPC 601 specific instructions (POWER bridge) */ 841 /* PowerPC 601 specific instructions (POWER bridge) */
639 void do_POWER_abso (void) 842 void do_POWER_abso (void)
640 { 843 {
641 - if (T0 == INT32_MIN) { 844 + if ((uint32_t)T0 == INT32_MIN) {
642 T0 = INT32_MAX; 845 T0 = INT32_MAX;
643 xer_ov = 1; 846 xer_ov = 1;
644 xer_so = 1; 847 xer_so = 1;
@@ -679,13 +882,13 @@ void do_POWER_div (void) @@ -679,13 +882,13 @@ void do_POWER_div (void)
679 { 882 {
680 uint64_t tmp; 883 uint64_t tmp;
681 884
682 - if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { 885 + if (((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) || (int32_t)T1 == 0) {
683 T0 = (long)((-1) * (T0 >> 31)); 886 T0 = (long)((-1) * (T0 >> 31));
684 env->spr[SPR_MQ] = 0; 887 env->spr[SPR_MQ] = 0;
685 } else { 888 } else {
686 tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ]; 889 tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ];
687 env->spr[SPR_MQ] = tmp % T1; 890 env->spr[SPR_MQ] = tmp % T1;
688 - T0 = tmp / Ts1; 891 + T0 = tmp / (int32_t)T1;
689 } 892 }
690 } 893 }
691 894
@@ -693,7 +896,7 @@ void do_POWER_divo (void) @@ -693,7 +896,7 @@ void do_POWER_divo (void)
693 { 896 {
694 int64_t tmp; 897 int64_t tmp;
695 898
696 - if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { 899 + if (((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) || (int32_t)T1 == 0) {
697 T0 = (long)((-1) * (T0 >> 31)); 900 T0 = (long)((-1) * (T0 >> 31));
698 env->spr[SPR_MQ] = 0; 901 env->spr[SPR_MQ] = 0;
699 xer_ov = 1; 902 xer_ov = 1;
@@ -701,7 +904,7 @@ void do_POWER_divo (void) @@ -701,7 +904,7 @@ void do_POWER_divo (void)
701 } else { 904 } else {
702 tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ]; 905 tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ];
703 env->spr[SPR_MQ] = tmp % T1; 906 env->spr[SPR_MQ] = tmp % T1;
704 - tmp /= Ts1; 907 + tmp /= (int32_t)T1;
705 if (tmp > (int64_t)INT32_MAX || tmp < (int64_t)INT32_MIN) { 908 if (tmp > (int64_t)INT32_MAX || tmp < (int64_t)INT32_MIN) {
706 xer_ov = 1; 909 xer_ov = 1;
707 xer_so = 1; 910 xer_so = 1;
@@ -714,35 +917,36 @@ void do_POWER_divo (void) @@ -714,35 +917,36 @@ void do_POWER_divo (void)
714 917
715 void do_POWER_divs (void) 918 void do_POWER_divs (void)
716 { 919 {
717 - if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { 920 + if (((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) || (int32_t)T1 == 0) {
718 T0 = (long)((-1) * (T0 >> 31)); 921 T0 = (long)((-1) * (T0 >> 31));
719 env->spr[SPR_MQ] = 0; 922 env->spr[SPR_MQ] = 0;
720 } else { 923 } else {
721 env->spr[SPR_MQ] = T0 % T1; 924 env->spr[SPR_MQ] = T0 % T1;
722 - T0 = Ts0 / Ts1; 925 + T0 = (int32_t)T0 / (int32_t)T1;
723 } 926 }
724 } 927 }
725 928
726 void do_POWER_divso (void) 929 void do_POWER_divso (void)
727 { 930 {
728 - if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { 931 + if (((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) || (int32_t)T1 == 0) {
729 T0 = (long)((-1) * (T0 >> 31)); 932 T0 = (long)((-1) * (T0 >> 31));
730 env->spr[SPR_MQ] = 0; 933 env->spr[SPR_MQ] = 0;
731 xer_ov = 1; 934 xer_ov = 1;
732 xer_so = 1; 935 xer_so = 1;
733 } else { 936 } else {
734 - T0 = Ts0 / Ts1;  
735 - env->spr[SPR_MQ] = Ts0 % Ts1; 937 + T0 = (int32_t)T0 / (int32_t)T1;
  938 + env->spr[SPR_MQ] = (int32_t)T0 % (int32_t)T1;
736 xer_ov = 0; 939 xer_ov = 0;
737 } 940 }
738 } 941 }
739 942
740 void do_POWER_dozo (void) 943 void do_POWER_dozo (void)
741 { 944 {
742 - if (Ts1 > Ts0) { 945 + if ((int32_t)T1 > (int32_t)T0) {
743 T2 = T0; 946 T2 = T0;
744 T0 = T1 - T0; 947 T0 = T1 - T0;
745 - if (((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)) { 948 + if (((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
  949 + ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)) {
746 xer_so = 1; 950 xer_so = 1;
747 xer_ov = 1; 951 xer_ov = 1;
748 } else { 952 } else {
@@ -758,12 +962,12 @@ void do_POWER_maskg (void) @@ -758,12 +962,12 @@ void do_POWER_maskg (void)
758 { 962 {
759 uint32_t ret; 963 uint32_t ret;
760 964
761 - if (T0 == T1 + 1) { 965 + if ((uint32_t)T0 == (uint32_t)(T1 + 1)) {
762 ret = -1; 966 ret = -1;
763 } else { 967 } else {
764 - ret = (((uint32_t)(-1)) >> (T0)) ^  
765 - (((uint32_t)(-1) >> (T1)) >> 1);  
766 - if (T0 > T1) 968 + ret = (((uint32_t)(-1)) >> ((uint32_t)T0)) ^
  969 + (((uint32_t)(-1) >> ((uint32_t)T1)) >> 1);
  970 + if ((uint32_t)T0 > (uint32_t)T1)
767 ret = ~ret; 971 ret = ~ret;
768 } 972 }
769 T0 = ret; 973 T0 = ret;
@@ -812,7 +1016,7 @@ void do_POWER_rfsvc (void) @@ -812,7 +1016,7 @@ void do_POWER_rfsvc (void)
812 /* PowerPC 601 BAT management helper */ 1016 /* PowerPC 601 BAT management helper */
813 void do_store_601_batu (int nr) 1017 void do_store_601_batu (int nr)
814 { 1018 {
815 - do_store_ibatu(env, nr, T0); 1019 + do_store_ibatu(env, nr, (uint32_t)T0);
816 env->DBAT[0][nr] = env->IBAT[0][nr]; 1020 env->DBAT[0][nr] = env->IBAT[0][nr];
817 env->DBAT[1][nr] = env->IBAT[1][nr]; 1021 env->DBAT[1][nr] = env->IBAT[1][nr];
818 } 1022 }
@@ -826,7 +1030,7 @@ void do_store_601_batu (int nr) @@ -826,7 +1030,7 @@ void do_store_601_batu (int nr)
826 void do_op_602_mfrom (void) 1030 void do_op_602_mfrom (void)
827 { 1031 {
828 if (likely(T0 < 602)) { 1032 if (likely(T0 < 602)) {
829 -#ifdef USE_MFROM_ROM_TABLE 1033 +#if defined(USE_MFROM_ROM_TABLE)
830 #include "mfrom_table.c" 1034 #include "mfrom_table.c"
831 T0 = mfrom_ROM_table[T0]; 1035 T0 = mfrom_ROM_table[T0];
832 #else 1036 #else
@@ -854,7 +1058,8 @@ void do_op_602_mfrom (void) @@ -854,7 +1058,8 @@ void do_op_602_mfrom (void)
854 /* Embedded PowerPC specific helpers */ 1058 /* Embedded PowerPC specific helpers */
855 void do_405_check_ov (void) 1059 void do_405_check_ov (void)
856 { 1060 {
857 - if (likely(((T1 ^ T2) >> 31) || !((T0 ^ T2) >> 31))) { 1061 + if (likely((((uint32_t)T1 ^ (uint32_t)T2) >> 31) ||
  1062 + !(((uint32_t)T0 ^ (uint32_t)T2) >> 31))) {
858 xer_ov = 0; 1063 xer_ov = 0;
859 } else { 1064 } else {
860 xer_ov = 1; 1065 xer_ov = 1;
@@ -864,7 +1069,8 @@ void do_405_check_ov (void) @@ -864,7 +1069,8 @@ void do_405_check_ov (void)
864 1069
865 void do_405_check_sat (void) 1070 void do_405_check_sat (void)
866 { 1071 {
867 - if (!likely(((T1 ^ T2) >> 31) || !((T0 ^ T2) >> 31))) { 1072 + if (!likely((((uint32_t)T1 ^ (uint32_t)T2) >> 31) ||
  1073 + !(((uint32_t)T0 ^ (uint32_t)T2) >> 31))) {
868 /* Saturate result */ 1074 /* Saturate result */
869 if (T2 >> 31) { 1075 if (T2 >> 31) {
870 T0 = INT32_MIN; 1076 T0 = INT32_MIN;
@@ -1010,6 +1216,7 @@ void do_tlbia (void) @@ -1010,6 +1216,7 @@ void do_tlbia (void)
1010 1216
1011 void do_tlbie (void) 1217 void do_tlbie (void)
1012 { 1218 {
  1219 + T0 = (uint32_t)T0;
1013 #if !defined(FLUSH_ALL_TLBS) 1220 #if !defined(FLUSH_ALL_TLBS)
1014 if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) { 1221 if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
1015 ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0); 1222 ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
@@ -1050,13 +1257,78 @@ void do_tlbie (void) @@ -1050,13 +1257,78 @@ void do_tlbie (void)
1050 #endif 1257 #endif
1051 } 1258 }
1052 1259
  1260 +#if defined(TARGET_PPC64)
  1261 +void do_tlbie_64 (void)
  1262 +{
  1263 + T0 = (uint64_t)T0;
  1264 +#if !defined(FLUSH_ALL_TLBS)
  1265 + if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
  1266 + ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
  1267 + if (env->id_tlbs == 1)
  1268 + ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1);
  1269 + } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
  1270 + /* XXX: TODO */
  1271 +#if 0
  1272 + ppcbooke_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
  1273 + env->spr[SPR_BOOKE_PID]);
  1274 +#endif
  1275 + } else {
  1276 + /* tlbie invalidate TLBs for all segments
  1277 + * As we have 2^36 segments, invalidate all qemu TLBs
  1278 + */
  1279 +#if 0
  1280 + T0 &= TARGET_PAGE_MASK;
  1281 + T0 &= ~((target_ulong)-1 << 28);
  1282 + /* XXX: this case should be optimized,
  1283 + * giving a mask to tlb_flush_page
  1284 + */
  1285 + tlb_flush_page(env, T0 | (0x0 << 28));
  1286 + tlb_flush_page(env, T0 | (0x1 << 28));
  1287 + tlb_flush_page(env, T0 | (0x2 << 28));
  1288 + tlb_flush_page(env, T0 | (0x3 << 28));
  1289 + tlb_flush_page(env, T0 | (0x4 << 28));
  1290 + tlb_flush_page(env, T0 | (0x5 << 28));
  1291 + tlb_flush_page(env, T0 | (0x6 << 28));
  1292 + tlb_flush_page(env, T0 | (0x7 << 28));
  1293 + tlb_flush_page(env, T0 | (0x8 << 28));
  1294 + tlb_flush_page(env, T0 | (0x9 << 28));
  1295 + tlb_flush_page(env, T0 | (0xA << 28));
  1296 + tlb_flush_page(env, T0 | (0xB << 28));
  1297 + tlb_flush_page(env, T0 | (0xC << 28));
  1298 + tlb_flush_page(env, T0 | (0xD << 28));
  1299 + tlb_flush_page(env, T0 | (0xE << 28));
  1300 + tlb_flush_page(env, T0 | (0xF << 28));
  1301 +#else
  1302 + tlb_flush(env, 1);
  1303 +#endif
  1304 + }
  1305 +#else
  1306 + do_tlbia();
  1307 +#endif
  1308 +}
  1309 +#endif
  1310 +
  1311 +#if defined(TARGET_PPC64)
  1312 +void do_slbia (void)
  1313 +{
  1314 + /* XXX: TODO */
  1315 + tlb_flush(env, 1);
  1316 +}
  1317 +
  1318 +void do_slbie (void)
  1319 +{
  1320 + /* XXX: TODO */
  1321 + tlb_flush(env, 1);
  1322 +}
  1323 +#endif
  1324 +
1053 /* Software driven TLBs management */ 1325 /* Software driven TLBs management */
1054 /* PowerPC 602/603 software TLB load instructions helpers */ 1326 /* PowerPC 602/603 software TLB load instructions helpers */
1055 void do_load_6xx_tlb (int is_code) 1327 void do_load_6xx_tlb (int is_code)
1056 { 1328 {
1057 target_ulong RPN, CMP, EPN; 1329 target_ulong RPN, CMP, EPN;
1058 int way; 1330 int way;
1059 - 1331 +
1060 RPN = env->spr[SPR_RPA]; 1332 RPN = env->spr[SPR_RPA];
1061 if (is_code) { 1333 if (is_code) {
1062 CMP = env->spr[SPR_ICMP]; 1334 CMP = env->spr[SPR_ICMP];
@@ -1074,7 +1346,8 @@ void do_load_6xx_tlb (int is_code) @@ -1074,7 +1346,8 @@ void do_load_6xx_tlb (int is_code)
1074 } 1346 }
1075 #endif 1347 #endif
1076 /* Store this TLB */ 1348 /* Store this TLB */
1077 - ppc6xx_tlb_store(env, T0 & TARGET_PAGE_MASK, way, is_code, CMP, RPN); 1349 + ppc6xx_tlb_store(env, (uint32_t)(T0 & TARGET_PAGE_MASK),
  1350 + way, is_code, CMP, RPN);
1078 } 1351 }
1079 1352
1080 /* Helpers for 4xx TLB management */ 1353 /* Helpers for 4xx TLB management */
target-ppc/op_helper.h
@@ -35,6 +35,17 @@ void glue(do_POWER2_lfq_le, MEMSUFFIX) (void); @@ -35,6 +35,17 @@ void glue(do_POWER2_lfq_le, MEMSUFFIX) (void);
35 void glue(do_POWER2_stfq, MEMSUFFIX) (void); 35 void glue(do_POWER2_stfq, MEMSUFFIX) (void);
36 void glue(do_POWER2_stfq_le, MEMSUFFIX) (void); 36 void glue(do_POWER2_stfq_le, MEMSUFFIX) (void);
37 37
  38 +#if defined(TARGET_PPC64)
  39 +void glue(do_lsw_64, MEMSUFFIX) (int dst);
  40 +void glue(do_lsw_le_64, MEMSUFFIX) (int dst);
  41 +void glue(do_stsw_64, MEMSUFFIX) (int src);
  42 +void glue(do_stsw_le_64, MEMSUFFIX) (int src);
  43 +void glue(do_lmw_64, MEMSUFFIX) (int dst);
  44 +void glue(do_lmw_le_64, MEMSUFFIX) (int dst);
  45 +void glue(do_stmw_64, MEMSUFFIX) (int src);
  46 +void glue(do_stmw_le_64, MEMSUFFIX) (int src);
  47 +#endif
  48 +
38 #else 49 #else
39 50
40 /* Registers load and stores */ 51 /* Registers load and stores */
@@ -46,23 +57,34 @@ void do_load_fpscr (void); @@ -46,23 +57,34 @@ void do_load_fpscr (void);
46 void do_store_fpscr (uint32_t mask); 57 void do_store_fpscr (uint32_t mask);
47 58
48 /* Integer arithmetic helpers */ 59 /* Integer arithmetic helpers */
49 -void do_addo (void);  
50 -void do_addco (void);  
51 void do_adde (void); 60 void do_adde (void);
52 -void do_addeo (void);  
53 void do_addmeo (void); 61 void do_addmeo (void);
54 -void do_addzeo (void);  
55 void do_divwo (void); 62 void do_divwo (void);
56 void do_divwuo (void); 63 void do_divwuo (void);
57 void do_mullwo (void); 64 void do_mullwo (void);
58 void do_nego (void); 65 void do_nego (void);
59 -void do_subfo (void);  
60 -void do_subfco (void);  
61 void do_subfe (void); 66 void do_subfe (void);
62 -void do_subfeo (void);  
63 void do_subfmeo (void); 67 void do_subfmeo (void);
64 void do_subfzeo (void); 68 void do_subfzeo (void);
65 -void do_sraw(void); 69 +void do_sraw (void);
  70 +#if defined(TARGET_PPC64)
  71 +void do_adde_64 (void);
  72 +void do_addmeo_64 (void);
  73 +void do_imul64 (uint64_t *tl, uint64_t *th);
  74 +void do_mul64 (uint64_t *tl, uint64_t *th);
  75 +void do_divdo (void);
  76 +void do_divduo (void);
  77 +void do_mulldo (void);
  78 +void do_nego_64 (void);
  79 +void do_subfe_64 (void);
  80 +void do_subfmeo_64 (void);
  81 +void do_subfzeo_64 (void);
  82 +void do_srad (void);
  83 +#endif
  84 +void do_popcntb (void);
  85 +#if defined(TARGET_PPC64)
  86 +void do_popcntb_64 (void);
  87 +#endif
66 88
67 /* Floating-point arithmetic helpers */ 89 /* Floating-point arithmetic helpers */
68 void do_fsqrt (void); 90 void do_fsqrt (void);
@@ -77,13 +99,29 @@ void do_fcmpu (void); @@ -77,13 +99,29 @@ void do_fcmpu (void);
77 void do_fcmpo (void); 99 void do_fcmpo (void);
78 100
79 void do_tw (int flags); 101 void do_tw (int flags);
  102 +#if defined(TARGET_PPC64)
  103 +void do_td (int flags);
  104 +#endif
80 void do_icbi (void); 105 void do_icbi (void);
  106 +#if defined(TARGET_PPC64)
  107 +void do_icbi_64 (void);
  108 +#endif
81 109
82 #if !defined(CONFIG_USER_ONLY) 110 #if !defined(CONFIG_USER_ONLY)
83 void do_rfi (void); 111 void do_rfi (void);
  112 +#if defined(TARGET_PPC64)
  113 +void do_rfi_32 (void);
  114 +#endif
84 void do_tlbia (void); 115 void do_tlbia (void);
85 void do_tlbie (void); 116 void do_tlbie (void);
  117 +#if defined(TARGET_PPC64)
  118 +void do_tlbie_64 (void);
  119 +#endif
86 void do_load_6xx_tlb (int is_code); 120 void do_load_6xx_tlb (int is_code);
  121 +#if defined(TARGET_PPC64)
  122 +void do_slbia (void);
  123 +void do_slbie (void);
  124 +#endif
87 #endif 125 #endif
88 126
89 /* POWER / PowerPC 601 specific helpers */ 127 /* POWER / PowerPC 601 specific helpers */
target-ppc/op_helper_mem.h
1 /* 1 /*
2 * PowerPC emulation micro-operations helpers for qemu. 2 * PowerPC emulation micro-operations helpers for qemu.
3 - * 3 + *
4 * Copyright (c) 2003-2007 Jocelyn Mayer 4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
@@ -37,98 +37,210 @@ static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, target_ulong data) @@ -37,98 +37,210 @@ static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, target_ulong data)
37 void glue(do_lmw, MEMSUFFIX) (int dst) 37 void glue(do_lmw, MEMSUFFIX) (int dst)
38 { 38 {
39 for (; dst < 32; dst++, T0 += 4) { 39 for (; dst < 32; dst++, T0 += 4) {
40 - ugpr(dst) = glue(ldl, MEMSUFFIX)(T0); 40 + ugpr(dst) = glue(ldl, MEMSUFFIX)((uint32_t)T0);
  41 + }
  42 +}
  43 +
  44 +#if defined(TARGET_PPC64)
  45 +void glue(do_lmw_64, MEMSUFFIX) (int dst)
  46 +{
  47 + for (; dst < 32; dst++, T0 += 4) {
  48 + ugpr(dst) = glue(ldl, MEMSUFFIX)((uint64_t)T0);
41 } 49 }
42 } 50 }
  51 +#endif
43 52
44 void glue(do_stmw, MEMSUFFIX) (int src) 53 void glue(do_stmw, MEMSUFFIX) (int src)
45 { 54 {
46 for (; src < 32; src++, T0 += 4) { 55 for (; src < 32; src++, T0 += 4) {
47 - glue(stl, MEMSUFFIX)(T0, ugpr(src)); 56 + glue(stl, MEMSUFFIX)((uint32_t)T0, ugpr(src));
  57 + }
  58 +}
  59 +
  60 +#if defined(TARGET_PPC64)
  61 +void glue(do_stmw_64, MEMSUFFIX) (int src)
  62 +{
  63 + for (; src < 32; src++, T0 += 4) {
  64 + glue(stl, MEMSUFFIX)((uint64_t)T0, ugpr(src));
48 } 65 }
49 } 66 }
  67 +#endif
50 68
51 void glue(do_lmw_le, MEMSUFFIX) (int dst) 69 void glue(do_lmw_le, MEMSUFFIX) (int dst)
52 { 70 {
53 for (; dst < 32; dst++, T0 += 4) { 71 for (; dst < 32; dst++, T0 += 4) {
54 - ugpr(dst) = glue(ld32r, MEMSUFFIX)(T0); 72 + ugpr(dst) = glue(ld32r, MEMSUFFIX)((uint32_t)T0);
  73 + }
  74 +}
  75 +
  76 +#if defined(TARGET_PPC64)
  77 +void glue(do_lmw_le_64, MEMSUFFIX) (int dst)
  78 +{
  79 + for (; dst < 32; dst++, T0 += 4) {
  80 + ugpr(dst) = glue(ld32r, MEMSUFFIX)((uint64_t)T0);
55 } 81 }
56 } 82 }
  83 +#endif
57 84
58 void glue(do_stmw_le, MEMSUFFIX) (int src) 85 void glue(do_stmw_le, MEMSUFFIX) (int src)
59 { 86 {
60 for (; src < 32; src++, T0 += 4) { 87 for (; src < 32; src++, T0 += 4) {
61 - glue(st32r, MEMSUFFIX)(T0, ugpr(src)); 88 + glue(st32r, MEMSUFFIX)((uint32_t)T0, ugpr(src));
62 } 89 }
63 } 90 }
64 91
  92 +#if defined(TARGET_PPC64)
  93 +void glue(do_stmw_le_64, MEMSUFFIX) (int src)
  94 +{
  95 + for (; src < 32; src++, T0 += 4) {
  96 + glue(st32r, MEMSUFFIX)((uint64_t)T0, ugpr(src));
  97 + }
  98 +}
  99 +#endif
  100 +
65 void glue(do_lsw, MEMSUFFIX) (int dst) 101 void glue(do_lsw, MEMSUFFIX) (int dst)
66 { 102 {
67 uint32_t tmp; 103 uint32_t tmp;
68 int sh; 104 int sh;
69 105
70 for (; T1 > 3; T1 -= 4, T0 += 4) { 106 for (; T1 > 3; T1 -= 4, T0 += 4) {
71 - ugpr(dst++) = glue(ldl, MEMSUFFIX)(T0); 107 + ugpr(dst++) = glue(ldl, MEMSUFFIX)((uint32_t)T0);
72 if (unlikely(dst == 32)) 108 if (unlikely(dst == 32))
73 dst = 0; 109 dst = 0;
74 } 110 }
75 if (unlikely(T1 != 0)) { 111 if (unlikely(T1 != 0)) {
76 tmp = 0; 112 tmp = 0;
77 for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) { 113 for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) {
78 - tmp |= glue(ldub, MEMSUFFIX)(T0) << sh; 114 + tmp |= glue(ldub, MEMSUFFIX)((uint32_t)T0) << sh;
79 } 115 }
80 ugpr(dst) = tmp; 116 ugpr(dst) = tmp;
81 } 117 }
82 } 118 }
83 119
  120 +#if defined(TARGET_PPC64)
  121 +void glue(do_lsw_64, MEMSUFFIX) (int dst)
  122 +{
  123 + uint32_t tmp;
  124 + int sh;
  125 +
  126 + for (; T1 > 3; T1 -= 4, T0 += 4) {
  127 + ugpr(dst++) = glue(ldl, MEMSUFFIX)((uint64_t)T0);
  128 + if (unlikely(dst == 32))
  129 + dst = 0;
  130 + }
  131 + if (unlikely(T1 != 0)) {
  132 + tmp = 0;
  133 + for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) {
  134 + tmp |= glue(ldub, MEMSUFFIX)((uint64_t)T0) << sh;
  135 + }
  136 + ugpr(dst) = tmp;
  137 + }
  138 +}
  139 +#endif
  140 +
84 void glue(do_stsw, MEMSUFFIX) (int src) 141 void glue(do_stsw, MEMSUFFIX) (int src)
85 { 142 {
86 int sh; 143 int sh;
87 144
88 for (; T1 > 3; T1 -= 4, T0 += 4) { 145 for (; T1 > 3; T1 -= 4, T0 += 4) {
89 - glue(stl, MEMSUFFIX)(T0, ugpr(src++)); 146 + glue(stl, MEMSUFFIX)((uint32_t)T0, ugpr(src++));
90 if (unlikely(src == 32)) 147 if (unlikely(src == 32))
91 src = 0; 148 src = 0;
92 } 149 }
93 if (unlikely(T1 != 0)) { 150 if (unlikely(T1 != 0)) {
94 for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) 151 for (sh = 24; T1 > 0; T1--, T0++, sh -= 8)
95 - glue(stb, MEMSUFFIX)(T0, (ugpr(src) >> sh) & 0xFF); 152 + glue(stb, MEMSUFFIX)((uint32_t)T0, (ugpr(src) >> sh) & 0xFF);
96 } 153 }
97 } 154 }
98 155
  156 +#if defined(TARGET_PPC64)
  157 +void glue(do_stsw_64, MEMSUFFIX) (int src)
  158 +{
  159 + int sh;
  160 +
  161 + for (; T1 > 3; T1 -= 4, T0 += 4) {
  162 + glue(stl, MEMSUFFIX)((uint64_t)T0, ugpr(src++));
  163 + if (unlikely(src == 32))
  164 + src = 0;
  165 + }
  166 + if (unlikely(T1 != 0)) {
  167 + for (sh = 24; T1 > 0; T1--, T0++, sh -= 8)
  168 + glue(stb, MEMSUFFIX)((uint64_t)T0, (ugpr(src) >> sh) & 0xFF);
  169 + }
  170 +}
  171 +#endif
  172 +
99 void glue(do_lsw_le, MEMSUFFIX) (int dst) 173 void glue(do_lsw_le, MEMSUFFIX) (int dst)
100 { 174 {
101 uint32_t tmp; 175 uint32_t tmp;
102 int sh; 176 int sh;
103 177
104 for (; T1 > 3; T1 -= 4, T0 += 4) { 178 for (; T1 > 3; T1 -= 4, T0 += 4) {
105 - ugpr(dst++) = glue(ld32r, MEMSUFFIX)(T0); 179 + ugpr(dst++) = glue(ld32r, MEMSUFFIX)((uint32_t)T0);
  180 + if (unlikely(dst == 32))
  181 + dst = 0;
  182 + }
  183 + if (unlikely(T1 != 0)) {
  184 + tmp = 0;
  185 + for (sh = 0; T1 > 0; T1--, T0++, sh += 8) {
  186 + tmp |= glue(ldub, MEMSUFFIX)((uint32_t)T0) << sh;
  187 + }
  188 + ugpr(dst) = tmp;
  189 + }
  190 +}
  191 +
  192 +#if defined(TARGET_PPC64)
  193 +void glue(do_lsw_le_64, MEMSUFFIX) (int dst)
  194 +{
  195 + uint32_t tmp;
  196 + int sh;
  197 +
  198 + for (; T1 > 3; T1 -= 4, T0 += 4) {
  199 + ugpr(dst++) = glue(ld32r, MEMSUFFIX)((uint64_t)T0);
106 if (unlikely(dst == 32)) 200 if (unlikely(dst == 32))
107 dst = 0; 201 dst = 0;
108 } 202 }
109 if (unlikely(T1 != 0)) { 203 if (unlikely(T1 != 0)) {
110 tmp = 0; 204 tmp = 0;
111 for (sh = 0; T1 > 0; T1--, T0++, sh += 8) { 205 for (sh = 0; T1 > 0; T1--, T0++, sh += 8) {
112 - tmp |= glue(ldub, MEMSUFFIX)(T0) << sh; 206 + tmp |= glue(ldub, MEMSUFFIX)((uint64_t)T0) << sh;
113 } 207 }
114 ugpr(dst) = tmp; 208 ugpr(dst) = tmp;
115 } 209 }
116 } 210 }
  211 +#endif
117 212
118 void glue(do_stsw_le, MEMSUFFIX) (int src) 213 void glue(do_stsw_le, MEMSUFFIX) (int src)
119 { 214 {
120 int sh; 215 int sh;
121 216
122 for (; T1 > 3; T1 -= 4, T0 += 4) { 217 for (; T1 > 3; T1 -= 4, T0 += 4) {
123 - glue(st32r, MEMSUFFIX)(T0, ugpr(src++)); 218 + glue(st32r, MEMSUFFIX)((uint32_t)T0, ugpr(src++));
  219 + if (unlikely(src == 32))
  220 + src = 0;
  221 + }
  222 + if (unlikely(T1 != 0)) {
  223 + for (sh = 0; T1 > 0; T1--, T0++, sh += 8)
  224 + glue(stb, MEMSUFFIX)((uint32_t)T0, (ugpr(src) >> sh) & 0xFF);
  225 + }
  226 +}
  227 +
  228 +#if defined(TARGET_PPC64)
  229 +void glue(do_stsw_le_64, MEMSUFFIX) (int src)
  230 +{
  231 + int sh;
  232 +
  233 + for (; T1 > 3; T1 -= 4, T0 += 4) {
  234 + glue(st32r, MEMSUFFIX)((uint64_t)T0, ugpr(src++));
124 if (unlikely(src == 32)) 235 if (unlikely(src == 32))
125 src = 0; 236 src = 0;
126 } 237 }
127 if (unlikely(T1 != 0)) { 238 if (unlikely(T1 != 0)) {
128 for (sh = 0; T1 > 0; T1--, T0++, sh += 8) 239 for (sh = 0; T1 > 0; T1--, T0++, sh += 8)
129 - glue(stb, MEMSUFFIX)(T0, (ugpr(src) >> sh) & 0xFF); 240 + glue(stb, MEMSUFFIX)((uint64_t)T0, (ugpr(src) >> sh) & 0xFF);
130 } 241 }
131 } 242 }
  243 +#endif
132 244
133 /* PPC 601 specific instructions (POWER bridge) */ 245 /* PPC 601 specific instructions (POWER bridge) */
134 // XXX: to be tested 246 // XXX: to be tested
@@ -139,7 +251,7 @@ void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) @@ -139,7 +251,7 @@ void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
139 d = 24; 251 d = 24;
140 reg = dest; 252 reg = dest;
141 for (i = 0; i < T1; i++) { 253 for (i = 0; i < T1; i++) {
142 - c = glue(ldub, MEMSUFFIX)(T0++); 254 + c = glue(ldub, MEMSUFFIX)((uint32_t)T0++);
143 /* ra (if not 0) and rb are never modified */ 255 /* ra (if not 0) and rb are never modified */
144 if (likely(reg != rb && (ra == 0 || reg != ra))) { 256 if (likely(reg != rb && (ra == 0 || reg != ra))) {
145 ugpr(reg) = (ugpr(reg) & ~(0xFF << d)) | (c << d); 257 ugpr(reg) = (ugpr(reg) & ~(0xFF << d)) | (c << d);
@@ -160,8 +272,8 @@ void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) @@ -160,8 +272,8 @@ void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
160 /* XXX: TAGs are not managed */ 272 /* XXX: TAGs are not managed */
161 void glue(do_POWER2_lfq, MEMSUFFIX) (void) 273 void glue(do_POWER2_lfq, MEMSUFFIX) (void)
162 { 274 {
163 - FT0 = glue(ldfq, MEMSUFFIX)(T0);  
164 - FT1 = glue(ldfq, MEMSUFFIX)(T0 + 4); 275 + FT0 = glue(ldfq, MEMSUFFIX)((uint32_t)T0);
  276 + FT1 = glue(ldfq, MEMSUFFIX)((uint32_t)(T0 + 4));
165 } 277 }
166 278
167 static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA) 279 static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
@@ -186,14 +298,14 @@ static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA) @@ -186,14 +298,14 @@ static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
186 298
187 void glue(do_POWER2_lfq_le, MEMSUFFIX) (void) 299 void glue(do_POWER2_lfq_le, MEMSUFFIX) (void)
188 { 300 {
189 - FT0 = glue(ldfqr, MEMSUFFIX)(T0 + 4);  
190 - FT1 = glue(ldfqr, MEMSUFFIX)(T0); 301 + FT0 = glue(ldfqr, MEMSUFFIX)((uint32_t)(T0 + 4));
  302 + FT1 = glue(ldfqr, MEMSUFFIX)((uint32_t)T0);
191 } 303 }
192 304
193 void glue(do_POWER2_stfq, MEMSUFFIX) (void) 305 void glue(do_POWER2_stfq, MEMSUFFIX) (void)
194 { 306 {
195 - glue(stfq, MEMSUFFIX)(T0, FT0);  
196 - glue(stfq, MEMSUFFIX)(T0 + 4, FT1); 307 + glue(stfq, MEMSUFFIX)((uint32_t)T0, FT0);
  308 + glue(stfq, MEMSUFFIX)((uint32_t)(T0 + 4), FT1);
197 } 309 }
198 310
199 static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d) 311 static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
@@ -217,8 +329,8 @@ static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d) @@ -217,8 +329,8 @@ static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
217 329
218 void glue(do_POWER2_stfq_le, MEMSUFFIX) (void) 330 void glue(do_POWER2_stfq_le, MEMSUFFIX) (void)
219 { 331 {
220 - glue(stfqr, MEMSUFFIX)(T0 + 4, FT0);  
221 - glue(stfqr, MEMSUFFIX)(T0, FT1); 332 + glue(stfqr, MEMSUFFIX)((uint32_t)(T0 + 4), FT0);
  333 + glue(stfqr, MEMSUFFIX)((uint32_t)T0, FT1);
222 } 334 }
223 335
224 #undef MEMSUFFIX 336 #undef MEMSUFFIX
target-ppc/op_mem.h
@@ -37,6 +37,33 @@ static inline uint32_t glue(ld32r, MEMSUFFIX) (target_ulong EA) @@ -37,6 +37,33 @@ static inline uint32_t glue(ld32r, MEMSUFFIX) (target_ulong EA)
37 ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24); 37 ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24);
38 } 38 }
39 39
  40 +#if defined(TARGET_PPC64)
  41 +static inline int64_t glue(ldsl, MEMSUFFIX) (target_ulong EA)
  42 +{
  43 + return (int32_t)glue(ldl, MEMSUFFIX)(EA);
  44 +}
  45 +
  46 +static inline uint64_t glue(ld64r, MEMSUFFIX) (target_ulong EA)
  47 +{
  48 + uint64_t tmp = glue(ldq, MEMSUFFIX)(EA);
  49 + return ((tmp & 0xFF00000000000000ULL) >> 56) |
  50 + ((tmp & 0x00FF000000000000ULL) >> 40) |
  51 + ((tmp & 0x0000FF0000000000ULL) >> 24) |
  52 + ((tmp & 0x000000FF00000000ULL) >> 8) |
  53 + ((tmp & 0x00000000FF000000ULL) << 8) |
  54 + ((tmp & 0x0000000000FF0000ULL) << 24) |
  55 + ((tmp & 0x000000000000FF00ULL) << 40) |
  56 + ((tmp & 0x00000000000000FFULL) << 54);
  57 +}
  58 +
  59 +static inline int64_t glue(ld32rs, MEMSUFFIX) (target_ulong EA)
  60 +{
  61 + uint32_t tmp = glue(ldl, MEMSUFFIX)(EA);
  62 + return (int32_t)((tmp & 0xFF000000) >> 24) | ((tmp & 0x00FF0000) >> 8) |
  63 + ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24);
  64 +}
  65 +#endif
  66 +
40 static inline void glue(st16r, MEMSUFFIX) (target_ulong EA, uint16_t data) 67 static inline void glue(st16r, MEMSUFFIX) (target_ulong EA, uint16_t data)
41 { 68 {
42 uint16_t tmp = ((data & 0xFF00) >> 8) | ((data & 0x00FF) << 8); 69 uint16_t tmp = ((data & 0xFF00) >> 8) | ((data & 0x00FF) << 8);
@@ -50,140 +77,328 @@ static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, uint32_t data) @@ -50,140 +77,328 @@ static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, uint32_t data)
50 glue(stl, MEMSUFFIX)(EA, tmp); 77 glue(stl, MEMSUFFIX)(EA, tmp);
51 } 78 }
52 79
  80 +#if defined(TARGET_PPC64)
  81 +static inline void glue(st64r, MEMSUFFIX) (target_ulong EA, uint64_t data)
  82 +{
  83 + uint64_t tmp = ((data & 0xFF00000000000000ULL) >> 56) |
  84 + ((data & 0x00FF000000000000ULL) >> 40) |
  85 + ((data & 0x0000FF0000000000ULL) >> 24) |
  86 + ((data & 0x000000FF00000000ULL) >> 8) |
  87 + ((data & 0x00000000FF000000ULL) << 8) |
  88 + ((data & 0x0000000000FF0000ULL) << 24) |
  89 + ((data & 0x000000000000FF00ULL) << 40) |
  90 + ((data & 0x00000000000000FFULL) << 56);
  91 + glue(stq, MEMSUFFIX)(EA, tmp);
  92 +}
  93 +#endif
  94 +
53 /*** Integer load ***/ 95 /*** Integer load ***/
54 #define PPC_LD_OP(name, op) \ 96 #define PPC_LD_OP(name, op) \
55 -PPC_OP(glue(glue(l, name), MEMSUFFIX)) \ 97 +void OPPROTO glue(glue(op_l, name), MEMSUFFIX) (void) \
56 { \ 98 { \
57 - T1 = glue(op, MEMSUFFIX)(T0); \ 99 + T1 = glue(op, MEMSUFFIX)((uint32_t)T0); \
58 RETURN(); \ 100 RETURN(); \
59 } 101 }
60 102
  103 +#if defined(TARGET_PPC64)
  104 +#define PPC_LD_OP_64(name, op) \
  105 +void OPPROTO glue(glue(glue(op_l, name), _64), MEMSUFFIX) (void) \
  106 +{ \
  107 + T1 = glue(op, MEMSUFFIX)((uint64_t)T0); \
  108 + RETURN(); \
  109 +}
  110 +#endif
  111 +
61 #define PPC_ST_OP(name, op) \ 112 #define PPC_ST_OP(name, op) \
62 -PPC_OP(glue(glue(st, name), MEMSUFFIX)) \ 113 +void OPPROTO glue(glue(op_st, name), MEMSUFFIX) (void) \
63 { \ 114 { \
64 - glue(op, MEMSUFFIX)(T0, T1); \ 115 + glue(op, MEMSUFFIX)((uint32_t)T0, T1); \
65 RETURN(); \ 116 RETURN(); \
66 } 117 }
67 118
  119 +#if defined(TARGET_PPC64)
  120 +#define PPC_ST_OP_64(name, op) \
  121 +void OPPROTO glue(glue(glue(op_st, name), _64), MEMSUFFIX) (void) \
  122 +{ \
  123 + glue(op, MEMSUFFIX)((uint64_t)T0, T1); \
  124 + RETURN(); \
  125 +}
  126 +#endif
  127 +
68 PPC_LD_OP(bz, ldub); 128 PPC_LD_OP(bz, ldub);
69 PPC_LD_OP(ha, ldsw); 129 PPC_LD_OP(ha, ldsw);
70 PPC_LD_OP(hz, lduw); 130 PPC_LD_OP(hz, lduw);
71 PPC_LD_OP(wz, ldl); 131 PPC_LD_OP(wz, ldl);
  132 +#if defined(TARGET_PPC64)
  133 +PPC_LD_OP(d, ldq);
  134 +PPC_LD_OP(wa, ldsl);
  135 +PPC_LD_OP_64(d, ldq);
  136 +PPC_LD_OP_64(wa, ldsl);
  137 +PPC_LD_OP_64(bz, ldub);
  138 +PPC_LD_OP_64(ha, ldsw);
  139 +PPC_LD_OP_64(hz, lduw);
  140 +PPC_LD_OP_64(wz, ldl);
  141 +#endif
72 142
73 PPC_LD_OP(ha_le, ld16rs); 143 PPC_LD_OP(ha_le, ld16rs);
74 PPC_LD_OP(hz_le, ld16r); 144 PPC_LD_OP(hz_le, ld16r);
75 PPC_LD_OP(wz_le, ld32r); 145 PPC_LD_OP(wz_le, ld32r);
  146 +#if defined(TARGET_PPC64)
  147 +PPC_LD_OP(d_le, ld64r);
  148 +PPC_LD_OP(wa_le, ld32rs);
  149 +PPC_LD_OP_64(d_le, ld64r);
  150 +PPC_LD_OP_64(wa_le, ld32rs);
  151 +PPC_LD_OP_64(ha_le, ld16rs);
  152 +PPC_LD_OP_64(hz_le, ld16r);
  153 +PPC_LD_OP_64(wz_le, ld32r);
  154 +#endif
76 155
77 /*** Integer store ***/ 156 /*** Integer store ***/
78 PPC_ST_OP(b, stb); 157 PPC_ST_OP(b, stb);
79 PPC_ST_OP(h, stw); 158 PPC_ST_OP(h, stw);
80 PPC_ST_OP(w, stl); 159 PPC_ST_OP(w, stl);
  160 +#if defined(TARGET_PPC64)
  161 +PPC_ST_OP(d, stq);
  162 +PPC_ST_OP_64(d, stq);
  163 +PPC_ST_OP_64(b, stb);
  164 +PPC_ST_OP_64(h, stw);
  165 +PPC_ST_OP_64(w, stl);
  166 +#endif
81 167
82 PPC_ST_OP(h_le, st16r); 168 PPC_ST_OP(h_le, st16r);
83 PPC_ST_OP(w_le, st32r); 169 PPC_ST_OP(w_le, st32r);
  170 +#if defined(TARGET_PPC64)
  171 +PPC_ST_OP(d_le, st64r);
  172 +PPC_ST_OP_64(d_le, st64r);
  173 +PPC_ST_OP_64(h_le, st16r);
  174 +PPC_ST_OP_64(w_le, st32r);
  175 +#endif
84 176
85 /*** Integer load and store with byte reverse ***/ 177 /*** Integer load and store with byte reverse ***/
86 PPC_LD_OP(hbr, ld16r); 178 PPC_LD_OP(hbr, ld16r);
87 PPC_LD_OP(wbr, ld32r); 179 PPC_LD_OP(wbr, ld32r);
88 PPC_ST_OP(hbr, st16r); 180 PPC_ST_OP(hbr, st16r);
89 PPC_ST_OP(wbr, st32r); 181 PPC_ST_OP(wbr, st32r);
  182 +#if defined(TARGET_PPC64)
  183 +PPC_LD_OP_64(hbr, ld16r);
  184 +PPC_LD_OP_64(wbr, ld32r);
  185 +PPC_ST_OP_64(hbr, st16r);
  186 +PPC_ST_OP_64(wbr, st32r);
  187 +#endif
90 188
91 PPC_LD_OP(hbr_le, lduw); 189 PPC_LD_OP(hbr_le, lduw);
92 PPC_LD_OP(wbr_le, ldl); 190 PPC_LD_OP(wbr_le, ldl);
93 PPC_ST_OP(hbr_le, stw); 191 PPC_ST_OP(hbr_le, stw);
94 PPC_ST_OP(wbr_le, stl); 192 PPC_ST_OP(wbr_le, stl);
  193 +#if defined(TARGET_PPC64)
  194 +PPC_LD_OP_64(hbr_le, lduw);
  195 +PPC_LD_OP_64(wbr_le, ldl);
  196 +PPC_ST_OP_64(hbr_le, stw);
  197 +PPC_ST_OP_64(wbr_le, stl);
  198 +#endif
95 199
96 /*** Integer load and store multiple ***/ 200 /*** Integer load and store multiple ***/
97 -PPC_OP(glue(lmw, MEMSUFFIX)) 201 +void OPPROTO glue(op_lmw, MEMSUFFIX) (void)
98 { 202 {
99 glue(do_lmw, MEMSUFFIX)(PARAM1); 203 glue(do_lmw, MEMSUFFIX)(PARAM1);
100 RETURN(); 204 RETURN();
101 } 205 }
102 206
103 -PPC_OP(glue(lmw_le, MEMSUFFIX)) 207 +#if defined(TARGET_PPC64)
  208 +void OPPROTO glue(op_lmw_64, MEMSUFFIX) (void)
  209 +{
  210 + glue(do_lmw_64, MEMSUFFIX)(PARAM1);
  211 + RETURN();
  212 +}
  213 +#endif
  214 +
  215 +void OPPROTO glue(op_lmw_le, MEMSUFFIX) (void)
104 { 216 {
105 glue(do_lmw_le, MEMSUFFIX)(PARAM1); 217 glue(do_lmw_le, MEMSUFFIX)(PARAM1);
106 RETURN(); 218 RETURN();
107 } 219 }
108 220
109 -PPC_OP(glue(stmw, MEMSUFFIX)) 221 +#if defined(TARGET_PPC64)
  222 +void OPPROTO glue(op_lmw_le_64, MEMSUFFIX) (void)
  223 +{
  224 + glue(do_lmw_le_64, MEMSUFFIX)(PARAM1);
  225 + RETURN();
  226 +}
  227 +#endif
  228 +
  229 +void OPPROTO glue(op_stmw, MEMSUFFIX) (void)
110 { 230 {
111 glue(do_stmw, MEMSUFFIX)(PARAM1); 231 glue(do_stmw, MEMSUFFIX)(PARAM1);
112 RETURN(); 232 RETURN();
113 } 233 }
114 234
115 -PPC_OP(glue(stmw_le, MEMSUFFIX)) 235 +#if defined(TARGET_PPC64)
  236 +void OPPROTO glue(op_stmw_64, MEMSUFFIX) (void)
  237 +{
  238 + glue(do_stmw_64, MEMSUFFIX)(PARAM1);
  239 + RETURN();
  240 +}
  241 +#endif
  242 +
  243 +void OPPROTO glue(op_stmw_le, MEMSUFFIX) (void)
116 { 244 {
117 glue(do_stmw_le, MEMSUFFIX)(PARAM1); 245 glue(do_stmw_le, MEMSUFFIX)(PARAM1);
118 RETURN(); 246 RETURN();
119 } 247 }
120 248
  249 +#if defined(TARGET_PPC64)
  250 +void OPPROTO glue(op_stmw_le_64, MEMSUFFIX) (void)
  251 +{
  252 + glue(do_stmw_le_64, MEMSUFFIX)(PARAM1);
  253 + RETURN();
  254 +}
  255 +#endif
  256 +
121 /*** Integer load and store strings ***/ 257 /*** Integer load and store strings ***/
122 -PPC_OP(glue(lswi, MEMSUFFIX)) 258 +void OPPROTO glue(op_lswi, MEMSUFFIX) (void)
  259 +{
  260 + glue(do_lsw, MEMSUFFIX)(PARAM1);
  261 + RETURN();
  262 +}
  263 +
  264 +#if defined(TARGET_PPC64)
  265 +void OPPROTO glue(op_lswi_64, MEMSUFFIX) (void)
123 { 266 {
124 - glue(do_lsw, MEMSUFFIX)(PARAM(1)); 267 + glue(do_lsw_64, MEMSUFFIX)(PARAM1);
125 RETURN(); 268 RETURN();
126 } 269 }
  270 +#endif
127 271
128 -PPC_OP(glue(lswi_le, MEMSUFFIX)) 272 +void OPPROTO glue(op_lswi_le, MEMSUFFIX) (void)
129 { 273 {
130 - glue(do_lsw_le, MEMSUFFIX)(PARAM(1)); 274 + glue(do_lsw_le, MEMSUFFIX)(PARAM1);
131 RETURN(); 275 RETURN();
132 } 276 }
133 277
  278 +#if defined(TARGET_PPC64)
  279 +void OPPROTO glue(op_lswi_le_64, MEMSUFFIX) (void)
  280 +{
  281 + glue(do_lsw_le_64, MEMSUFFIX)(PARAM1);
  282 + RETURN();
  283 +}
  284 +#endif
  285 +
134 /* PPC32 specification says we must generate an exception if 286 /* PPC32 specification says we must generate an exception if
135 * rA is in the range of registers to be loaded. 287 * rA is in the range of registers to be loaded.
136 * In an other hand, IBM says this is valid, but rA won't be loaded. 288 * In an other hand, IBM says this is valid, but rA won't be loaded.
137 * For now, I'll follow the spec... 289 * For now, I'll follow the spec...
138 */ 290 */
139 -PPC_OP(glue(lswx, MEMSUFFIX)) 291 +void OPPROTO glue(op_lswx, MEMSUFFIX) (void)
  292 +{
  293 + /* Note: T1 comes from xer_bc then no cast is needed */
  294 + if (likely(T1 != 0)) {
  295 + if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
  296 + (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
  297 + do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
  298 + } else {
  299 + glue(do_lsw, MEMSUFFIX)(PARAM1);
  300 + }
  301 + }
  302 + RETURN();
  303 +}
  304 +
  305 +#if defined(TARGET_PPC64)
  306 +void OPPROTO glue(op_lswx_64, MEMSUFFIX) (void)
  307 +{
  308 + /* Note: T1 comes from xer_bc then no cast is needed */
  309 + if (likely(T1 != 0)) {
  310 + if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
  311 + (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
  312 + do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
  313 + } else {
  314 + glue(do_lsw_64, MEMSUFFIX)(PARAM1);
  315 + }
  316 + }
  317 + RETURN();
  318 +}
  319 +#endif
  320 +
  321 +void OPPROTO glue(op_lswx_le, MEMSUFFIX) (void)
140 { 322 {
141 - if (unlikely(T1 > 0)) { 323 + /* Note: T1 comes from xer_bc then no cast is needed */
  324 + if (likely(T1 != 0)) {
142 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || 325 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
143 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { 326 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
144 do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); 327 do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
145 } else { 328 } else {
146 - glue(do_lsw, MEMSUFFIX)(PARAM(1)); 329 + glue(do_lsw_le, MEMSUFFIX)(PARAM1);
147 } 330 }
148 } 331 }
149 RETURN(); 332 RETURN();
150 } 333 }
151 334
152 -PPC_OP(glue(lswx_le, MEMSUFFIX)) 335 +#if defined(TARGET_PPC64)
  336 +void OPPROTO glue(op_lswx_le_64, MEMSUFFIX) (void)
153 { 337 {
154 - if (unlikely(T1 > 0)) { 338 + /* Note: T1 comes from xer_bc then no cast is needed */
  339 + if (likely(T1 != 0)) {
155 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || 340 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
156 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { 341 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
157 do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); 342 do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
158 } else { 343 } else {
159 - glue(do_lsw_le, MEMSUFFIX)(PARAM(1)); 344 + glue(do_lsw_le_64, MEMSUFFIX)(PARAM1);
160 } 345 }
161 } 346 }
162 RETURN(); 347 RETURN();
163 } 348 }
  349 +#endif
  350 +
  351 +void OPPROTO glue(op_stsw, MEMSUFFIX) (void)
  352 +{
  353 + glue(do_stsw, MEMSUFFIX)(PARAM1);
  354 + RETURN();
  355 +}
  356 +
  357 +#if defined(TARGET_PPC64)
  358 +void OPPROTO glue(op_stsw_64, MEMSUFFIX) (void)
  359 +{
  360 + glue(do_stsw_64, MEMSUFFIX)(PARAM1);
  361 + RETURN();
  362 +}
  363 +#endif
164 364
165 -PPC_OP(glue(stsw, MEMSUFFIX)) 365 +void OPPROTO glue(op_stsw_le, MEMSUFFIX) (void)
166 { 366 {
167 - glue(do_stsw, MEMSUFFIX)(PARAM(1)); 367 + glue(do_stsw_le, MEMSUFFIX)(PARAM1);
168 RETURN(); 368 RETURN();
169 } 369 }
170 370
171 -PPC_OP(glue(stsw_le, MEMSUFFIX)) 371 +#if defined(TARGET_PPC64)
  372 +void OPPROTO glue(op_stsw_le_64, MEMSUFFIX) (void)
172 { 373 {
173 - glue(do_stsw_le, MEMSUFFIX)(PARAM(1)); 374 + glue(do_stsw_le_64, MEMSUFFIX)(PARAM1);
174 RETURN(); 375 RETURN();
175 } 376 }
  377 +#endif
176 378
177 /*** Floating-point store ***/ 379 /*** Floating-point store ***/
178 #define PPC_STF_OP(name, op) \ 380 #define PPC_STF_OP(name, op) \
179 -PPC_OP(glue(glue(st, name), MEMSUFFIX)) \ 381 +void OPPROTO glue(glue(op_st, name), MEMSUFFIX) (void) \
  382 +{ \
  383 + glue(op, MEMSUFFIX)((uint32_t)T0, FT0); \
  384 + RETURN(); \
  385 +}
  386 +
  387 +#if defined(TARGET_PPC64)
  388 +#define PPC_STF_OP_64(name, op) \
  389 +void OPPROTO glue(glue(glue(op_st, name), _64), MEMSUFFIX) (void) \
180 { \ 390 { \
181 - glue(op, MEMSUFFIX)(T0, FT0); \ 391 + glue(op, MEMSUFFIX)((uint64_t)T0, FT0); \
182 RETURN(); \ 392 RETURN(); \
183 } 393 }
  394 +#endif
184 395
185 PPC_STF_OP(fd, stfq); 396 PPC_STF_OP(fd, stfq);
186 PPC_STF_OP(fs, stfl); 397 PPC_STF_OP(fs, stfl);
  398 +#if defined(TARGET_PPC64)
  399 +PPC_STF_OP_64(fd, stfq);
  400 +PPC_STF_OP_64(fs, stfl);
  401 +#endif
187 402
188 static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d) 403 static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
189 { 404 {
@@ -221,17 +436,34 @@ static inline void glue(stflr, MEMSUFFIX) (target_ulong EA, float f) @@ -221,17 +436,34 @@ static inline void glue(stflr, MEMSUFFIX) (target_ulong EA, float f)
221 436
222 PPC_STF_OP(fd_le, stfqr); 437 PPC_STF_OP(fd_le, stfqr);
223 PPC_STF_OP(fs_le, stflr); 438 PPC_STF_OP(fs_le, stflr);
  439 +#if defined(TARGET_PPC64)
  440 +PPC_STF_OP_64(fd_le, stfqr);
  441 +PPC_STF_OP_64(fs_le, stflr);
  442 +#endif
224 443
225 /*** Floating-point load ***/ 444 /*** Floating-point load ***/
226 #define PPC_LDF_OP(name, op) \ 445 #define PPC_LDF_OP(name, op) \
227 -PPC_OP(glue(glue(l, name), MEMSUFFIX)) \ 446 +void OPPROTO glue(glue(op_l, name), MEMSUFFIX) (void) \
  447 +{ \
  448 + FT0 = glue(op, MEMSUFFIX)((uint32_t)T0); \
  449 + RETURN(); \
  450 +}
  451 +
  452 +#if defined(TARGET_PPC64)
  453 +#define PPC_LDF_OP_64(name, op) \
  454 +void OPPROTO glue(glue(glue(op_l, name), _64), MEMSUFFIX) (void) \
228 { \ 455 { \
229 - FT0 = glue(op, MEMSUFFIX)(T0); \ 456 + FT0 = glue(op, MEMSUFFIX)((uint64_t)T0); \
230 RETURN(); \ 457 RETURN(); \
231 } 458 }
  459 +#endif
232 460
233 PPC_LDF_OP(fd, ldfq); 461 PPC_LDF_OP(fd, ldfq);
234 PPC_LDF_OP(fs, ldfl); 462 PPC_LDF_OP(fs, ldfl);
  463 +#if defined(TARGET_PPC64)
  464 +PPC_LDF_OP_64(fd, ldfq);
  465 +PPC_LDF_OP_64(fs, ldfl);
  466 +#endif
235 467
236 static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA) 468 static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
237 { 469 {
@@ -271,40 +503,142 @@ static inline float glue(ldflr, MEMSUFFIX) (target_ulong EA) @@ -271,40 +503,142 @@ static inline float glue(ldflr, MEMSUFFIX) (target_ulong EA)
271 503
272 PPC_LDF_OP(fd_le, ldfqr); 504 PPC_LDF_OP(fd_le, ldfqr);
273 PPC_LDF_OP(fs_le, ldflr); 505 PPC_LDF_OP(fs_le, ldflr);
  506 +#if defined(TARGET_PPC64)
  507 +PPC_LDF_OP_64(fd_le, ldfqr);
  508 +PPC_LDF_OP_64(fs_le, ldflr);
  509 +#endif
274 510
275 /* Load and set reservation */ 511 /* Load and set reservation */
276 -PPC_OP(glue(lwarx, MEMSUFFIX)) 512 +void OPPROTO glue(op_lwarx, MEMSUFFIX) (void)
  513 +{
  514 + if (unlikely(T0 & 0x03)) {
  515 + do_raise_exception(EXCP_ALIGN);
  516 + } else {
  517 + T1 = glue(ldl, MEMSUFFIX)((uint32_t)T0);
  518 + regs->reserve = (uint32_t)T0;
  519 + }
  520 + RETURN();
  521 +}
  522 +
  523 +#if defined(TARGET_PPC64)
  524 +void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void)
  525 +{
  526 + if (unlikely(T0 & 0x03)) {
  527 + do_raise_exception(EXCP_ALIGN);
  528 + } else {
  529 + T1 = glue(ldl, MEMSUFFIX)((uint64_t)T0);
  530 + regs->reserve = (uint64_t)T0;
  531 + }
  532 + RETURN();
  533 +}
  534 +
  535 +void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void)
  536 +{
  537 + if (unlikely(T0 & 0x03)) {
  538 + do_raise_exception(EXCP_ALIGN);
  539 + } else {
  540 + T1 = glue(ldq, MEMSUFFIX)((uint64_t)T0);
  541 + regs->reserve = (uint64_t)T0;
  542 + }
  543 + RETURN();
  544 +}
  545 +#endif
  546 +
  547 +void OPPROTO glue(op_lwarx_le, MEMSUFFIX) (void)
  548 +{
  549 + if (unlikely(T0 & 0x03)) {
  550 + do_raise_exception(EXCP_ALIGN);
  551 + } else {
  552 + T1 = glue(ld32r, MEMSUFFIX)((uint32_t)T0);
  553 + regs->reserve = (uint32_t)T0;
  554 + }
  555 + RETURN();
  556 +}
  557 +
  558 +#if defined(TARGET_PPC64)
  559 +void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void)
277 { 560 {
278 if (unlikely(T0 & 0x03)) { 561 if (unlikely(T0 & 0x03)) {
279 do_raise_exception(EXCP_ALIGN); 562 do_raise_exception(EXCP_ALIGN);
280 } else { 563 } else {
281 - T1 = glue(ldl, MEMSUFFIX)(T0);  
282 - regs->reserve = T0; 564 + T1 = glue(ld32r, MEMSUFFIX)((uint64_t)T0);
  565 + regs->reserve = (uint64_t)T0;
283 } 566 }
284 RETURN(); 567 RETURN();
285 } 568 }
286 569
287 -PPC_OP(glue(lwarx_le, MEMSUFFIX)) 570 +void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void)
288 { 571 {
289 if (unlikely(T0 & 0x03)) { 572 if (unlikely(T0 & 0x03)) {
290 do_raise_exception(EXCP_ALIGN); 573 do_raise_exception(EXCP_ALIGN);
291 } else { 574 } else {
292 - T1 = glue(ld32r, MEMSUFFIX)(T0);  
293 - regs->reserve = T0; 575 + T1 = glue(ld64r, MEMSUFFIX)((uint64_t)T0);
  576 + regs->reserve = (uint64_t)T0;
294 } 577 }
295 RETURN(); 578 RETURN();
296 } 579 }
  580 +#endif
297 581
298 /* Store with reservation */ 582 /* Store with reservation */
299 -PPC_OP(glue(stwcx, MEMSUFFIX)) 583 +void OPPROTO glue(op_stwcx, MEMSUFFIX) (void)
  584 +{
  585 + if (unlikely(T0 & 0x03)) {
  586 + do_raise_exception(EXCP_ALIGN);
  587 + } else {
  588 + if (unlikely(regs->reserve != (uint32_t)T0)) {
  589 + env->crf[0] = xer_ov;
  590 + } else {
  591 + glue(stl, MEMSUFFIX)((uint32_t)T0, T1);
  592 + env->crf[0] = xer_ov | 0x02;
  593 + }
  594 + }
  595 + regs->reserve = -1;
  596 + RETURN();
  597 +}
  598 +
  599 +#if defined(TARGET_PPC64)
  600 +void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void)
  601 +{
  602 + if (unlikely(T0 & 0x03)) {
  603 + do_raise_exception(EXCP_ALIGN);
  604 + } else {
  605 + if (unlikely(regs->reserve != (uint64_t)T0)) {
  606 + env->crf[0] = xer_ov;
  607 + } else {
  608 + glue(stl, MEMSUFFIX)((uint64_t)T0, T1);
  609 + env->crf[0] = xer_ov | 0x02;
  610 + }
  611 + }
  612 + regs->reserve = -1;
  613 + RETURN();
  614 +}
  615 +
  616 +void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void)
300 { 617 {
301 if (unlikely(T0 & 0x03)) { 618 if (unlikely(T0 & 0x03)) {
302 do_raise_exception(EXCP_ALIGN); 619 do_raise_exception(EXCP_ALIGN);
303 } else { 620 } else {
304 - if (unlikely(regs->reserve != T0)) { 621 + if (unlikely(regs->reserve != (uint64_t)T0)) {
305 env->crf[0] = xer_ov; 622 env->crf[0] = xer_ov;
306 } else { 623 } else {
307 - glue(stl, MEMSUFFIX)(T0, T1); 624 + glue(stq, MEMSUFFIX)((uint64_t)T0, T1);
  625 + env->crf[0] = xer_ov | 0x02;
  626 + }
  627 + }
  628 + regs->reserve = -1;
  629 + RETURN();
  630 +}
  631 +#endif
  632 +
  633 +void OPPROTO glue(op_stwcx_le, MEMSUFFIX) (void)
  634 +{
  635 + if (unlikely(T0 & 0x03)) {
  636 + do_raise_exception(EXCP_ALIGN);
  637 + } else {
  638 + if (unlikely(regs->reserve != (uint32_t)T0)) {
  639 + env->crf[0] = xer_ov;
  640 + } else {
  641 + glue(st32r, MEMSUFFIX)((uint32_t)T0, T1);
308 env->crf[0] = xer_ov | 0x02; 642 env->crf[0] = xer_ov | 0x02;
309 } 643 }
310 } 644 }
@@ -312,15 +646,16 @@ PPC_OP(glue(stwcx, MEMSUFFIX)) @@ -312,15 +646,16 @@ PPC_OP(glue(stwcx, MEMSUFFIX))
312 RETURN(); 646 RETURN();
313 } 647 }
314 648
315 -PPC_OP(glue(stwcx_le, MEMSUFFIX)) 649 +#if defined(TARGET_PPC64)
  650 +void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void)
316 { 651 {
317 if (unlikely(T0 & 0x03)) { 652 if (unlikely(T0 & 0x03)) {
318 do_raise_exception(EXCP_ALIGN); 653 do_raise_exception(EXCP_ALIGN);
319 } else { 654 } else {
320 - if (unlikely(regs->reserve != T0)) { 655 + if (unlikely(regs->reserve != (uint64_t)T0)) {
321 env->crf[0] = xer_ov; 656 env->crf[0] = xer_ov;
322 } else { 657 } else {
323 - glue(st32r, MEMSUFFIX)(T0, T1); 658 + glue(st32r, MEMSUFFIX)((uint64_t)T0, T1);
324 env->crf[0] = xer_ov | 0x02; 659 env->crf[0] = xer_ov | 0x02;
325 } 660 }
326 } 661 }
@@ -328,61 +663,136 @@ PPC_OP(glue(stwcx_le, MEMSUFFIX)) @@ -328,61 +663,136 @@ PPC_OP(glue(stwcx_le, MEMSUFFIX))
328 RETURN(); 663 RETURN();
329 } 664 }
330 665
331 -PPC_OP(glue(dcbz, MEMSUFFIX)) 666 +void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void)
  667 +{
  668 + if (unlikely(T0 & 0x03)) {
  669 + do_raise_exception(EXCP_ALIGN);
  670 + } else {
  671 + if (unlikely(regs->reserve != (uint64_t)T0)) {
  672 + env->crf[0] = xer_ov;
  673 + } else {
  674 + glue(st64r, MEMSUFFIX)((uint64_t)T0, T1);
  675 + env->crf[0] = xer_ov | 0x02;
  676 + }
  677 + }
  678 + regs->reserve = -1;
  679 + RETURN();
  680 +}
  681 +#endif
  682 +
  683 +void OPPROTO glue(op_dcbz, MEMSUFFIX) (void)
  684 +{
  685 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0);
  686 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0);
  687 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x08), 0);
  688 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x0C), 0);
  689 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x10), 0);
  690 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0);
  691 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0);
  692 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0);
  693 +#if DCACHE_LINE_SIZE == 64
  694 + /* XXX: cache line size should be 64 for POWER & PowerPC 601 */
  695 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x20UL), 0);
  696 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x24UL), 0);
  697 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x28UL), 0);
  698 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x2CUL), 0);
  699 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x30UL), 0);
  700 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x34UL), 0);
  701 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x38UL), 0);
  702 + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x3CUL), 0);
  703 +#endif
  704 + RETURN();
  705 +}
  706 +
  707 +#if defined(TARGET_PPC64)
  708 +void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void)
332 { 709 {
333 - glue(stl, MEMSUFFIX)(T0 + 0x00, 0);  
334 - glue(stl, MEMSUFFIX)(T0 + 0x04, 0);  
335 - glue(stl, MEMSUFFIX)(T0 + 0x08, 0);  
336 - glue(stl, MEMSUFFIX)(T0 + 0x0C, 0);  
337 - glue(stl, MEMSUFFIX)(T0 + 0x10, 0);  
338 - glue(stl, MEMSUFFIX)(T0 + 0x14, 0);  
339 - glue(stl, MEMSUFFIX)(T0 + 0x18, 0);  
340 - glue(stl, MEMSUFFIX)(T0 + 0x1C, 0); 710 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0);
  711 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0);
  712 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x08), 0);
  713 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x0C), 0);
  714 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x10), 0);
  715 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0);
  716 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0);
  717 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0);
341 #if DCACHE_LINE_SIZE == 64 718 #if DCACHE_LINE_SIZE == 64
342 /* XXX: cache line size should be 64 for POWER & PowerPC 601 */ 719 /* XXX: cache line size should be 64 for POWER & PowerPC 601 */
343 - glue(stl, MEMSUFFIX)(T0 + 0x20UL, 0);  
344 - glue(stl, MEMSUFFIX)(T0 + 0x24UL, 0);  
345 - glue(stl, MEMSUFFIX)(T0 + 0x28UL, 0);  
346 - glue(stl, MEMSUFFIX)(T0 + 0x2CUL, 0);  
347 - glue(stl, MEMSUFFIX)(T0 + 0x30UL, 0);  
348 - glue(stl, MEMSUFFIX)(T0 + 0x34UL, 0);  
349 - glue(stl, MEMSUFFIX)(T0 + 0x38UL, 0);  
350 - glue(stl, MEMSUFFIX)(T0 + 0x3CUL, 0); 720 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x20UL), 0);
  721 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x24UL), 0);
  722 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x28UL), 0);
  723 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x2CUL), 0);
  724 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x30UL), 0);
  725 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x34UL), 0);
  726 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x38UL), 0);
  727 + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x3CUL), 0);
351 #endif 728 #endif
352 RETURN(); 729 RETURN();
353 } 730 }
  731 +#endif
354 732
355 /* External access */ 733 /* External access */
356 -PPC_OP(glue(eciwx, MEMSUFFIX)) 734 +void OPPROTO glue(op_eciwx, MEMSUFFIX) (void)
  735 +{
  736 + T1 = glue(ldl, MEMSUFFIX)((uint32_t)T0);
  737 + RETURN();
  738 +}
  739 +
  740 +#if defined(TARGET_PPC64)
  741 +void OPPROTO glue(op_eciwx_64, MEMSUFFIX) (void)
  742 +{
  743 + T1 = glue(ldl, MEMSUFFIX)((uint64_t)T0);
  744 + RETURN();
  745 +}
  746 +#endif
  747 +
  748 +void OPPROTO glue(op_ecowx, MEMSUFFIX) (void)
  749 +{
  750 + glue(stl, MEMSUFFIX)((uint32_t)T0, T1);
  751 + RETURN();
  752 +}
  753 +
  754 +#if defined(TARGET_PPC64)
  755 +void OPPROTO glue(op_ecowx_64, MEMSUFFIX) (void)
357 { 756 {
358 - T1 = glue(ldl, MEMSUFFIX)(T0); 757 + glue(stl, MEMSUFFIX)((uint64_t)T0, T1);
359 RETURN(); 758 RETURN();
360 } 759 }
  760 +#endif
361 761
362 -PPC_OP(glue(ecowx, MEMSUFFIX)) 762 +void OPPROTO glue(op_eciwx_le, MEMSUFFIX) (void)
363 { 763 {
364 - glue(stl, MEMSUFFIX)(T0, T1); 764 + T1 = glue(ld32r, MEMSUFFIX)((uint32_t)T0);
365 RETURN(); 765 RETURN();
366 } 766 }
367 767
368 -PPC_OP(glue(eciwx_le, MEMSUFFIX)) 768 +#if defined(TARGET_PPC64)
  769 +void OPPROTO glue(op_eciwx_le_64, MEMSUFFIX) (void)
369 { 770 {
370 - T1 = glue(ld32r, MEMSUFFIX)(T0); 771 + T1 = glue(ld32r, MEMSUFFIX)((uint64_t)T0);
371 RETURN(); 772 RETURN();
372 } 773 }
  774 +#endif
373 775
374 -PPC_OP(glue(ecowx_le, MEMSUFFIX)) 776 +void OPPROTO glue(op_ecowx_le, MEMSUFFIX) (void)
375 { 777 {
376 - glue(st32r, MEMSUFFIX)(T0, T1); 778 + glue(st32r, MEMSUFFIX)((uint32_t)T0, T1);
377 RETURN(); 779 RETURN();
378 } 780 }
379 781
  782 +#if defined(TARGET_PPC64)
  783 +void OPPROTO glue(op_ecowx_le_64, MEMSUFFIX) (void)
  784 +{
  785 + glue(st32r, MEMSUFFIX)((uint64_t)T0, T1);
  786 + RETURN();
  787 +}
  788 +#endif
  789 +
380 /* XXX: those micro-ops need tests ! */ 790 /* XXX: those micro-ops need tests ! */
381 /* PowerPC 601 specific instructions (POWER bridge) */ 791 /* PowerPC 601 specific instructions (POWER bridge) */
382 void OPPROTO glue(op_POWER_lscbx, MEMSUFFIX) (void) 792 void OPPROTO glue(op_POWER_lscbx, MEMSUFFIX) (void)
383 { 793 {
384 /* When byte count is 0, do nothing */ 794 /* When byte count is 0, do nothing */
385 - if (likely(T1 > 0)) { 795 + if (likely(T1 != 0)) {
386 glue(do_POWER_lscbx, MEMSUFFIX)(PARAM1, PARAM2, PARAM3); 796 glue(do_POWER_lscbx, MEMSUFFIX)(PARAM1, PARAM2, PARAM3);
387 } 797 }
388 RETURN(); 798 RETURN();