Commit a9d9eb8fd45279fa8455afa03331296dbe2871ff
1 parent
b33c17e1
Implement PowerPC Altivec load & stores, used by Apple firmware for memcpy.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3349 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
274 additions
and
8 deletions
target-ppc/cpu.h
@@ -292,7 +292,7 @@ typedef struct CPUPPCState CPUPPCState; | @@ -292,7 +292,7 @@ typedef struct CPUPPCState CPUPPCState; | ||
292 | typedef struct ppc_tb_t ppc_tb_t; | 292 | typedef struct ppc_tb_t ppc_tb_t; |
293 | typedef struct ppc_spr_t ppc_spr_t; | 293 | typedef struct ppc_spr_t ppc_spr_t; |
294 | typedef struct ppc_dcr_t ppc_dcr_t; | 294 | typedef struct ppc_dcr_t ppc_dcr_t; |
295 | -typedef struct ppc_avr_t ppc_avr_t; | 295 | +typedef union ppc_avr_t ppc_avr_t; |
296 | typedef union ppc_tlb_t ppc_tlb_t; | 296 | typedef union ppc_tlb_t ppc_tlb_t; |
297 | 297 | ||
298 | /* SPR access micro-ops generations callbacks */ | 298 | /* SPR access micro-ops generations callbacks */ |
@@ -311,8 +311,11 @@ struct ppc_spr_t { | @@ -311,8 +311,11 @@ struct ppc_spr_t { | ||
311 | }; | 311 | }; |
312 | 312 | ||
313 | /* Altivec registers (128 bits) */ | 313 | /* Altivec registers (128 bits) */ |
314 | -struct ppc_avr_t { | ||
315 | - uint32_t u[4]; | 314 | +union ppc_avr_t { |
315 | + uint8_t u8[16]; | ||
316 | + uint16_t u16[8]; | ||
317 | + uint32_t u32[4]; | ||
318 | + uint64_t u64[2]; | ||
316 | }; | 319 | }; |
317 | 320 | ||
318 | /* Software TLB cache */ | 321 | /* Software TLB cache */ |
@@ -454,7 +457,7 @@ struct CPUPPCState { | @@ -454,7 +457,7 @@ struct CPUPPCState { | ||
454 | */ | 457 | */ |
455 | ppc_gpr_t t0, t1, t2; | 458 | ppc_gpr_t t0, t1, t2; |
456 | #endif | 459 | #endif |
457 | - ppc_avr_t t0_avr, t1_avr, t2_avr; | 460 | + ppc_avr_t avr0, avr1, avr2; |
458 | 461 | ||
459 | /* general purpose registers */ | 462 | /* general purpose registers */ |
460 | ppc_gpr_t gpr[32]; | 463 | ppc_gpr_t gpr[32]; |
target-ppc/exec.h
@@ -54,9 +54,9 @@ register unsigned long T2 asm(AREG3); | @@ -54,9 +54,9 @@ register unsigned long T2 asm(AREG3); | ||
54 | #define T2_64 T2 | 54 | #define T2_64 T2 |
55 | #endif | 55 | #endif |
56 | /* Provision for Altivec */ | 56 | /* Provision for Altivec */ |
57 | -#define T0_avr (env->t0_avr) | ||
58 | -#define T1_avr (env->t1_avr) | ||
59 | -#define T2_avr (env->t2_avr) | 57 | +#define AVR0 (env->avr0) |
58 | +#define AVR1 (env->avr1) | ||
59 | +#define AVR2 (env->avr2) | ||
60 | 60 | ||
61 | #define FT0 (env->ft0) | 61 | #define FT0 (env->ft0) |
62 | #define FT1 (env->ft1) | 62 | #define FT1 (env->ft1) |
target-ppc/op_mem.h
@@ -1054,6 +1054,66 @@ void OPPROTO glue(op_POWER2_stfq_le, MEMSUFFIX) (void) | @@ -1054,6 +1054,66 @@ void OPPROTO glue(op_POWER2_stfq_le, MEMSUFFIX) (void) | ||
1054 | RETURN(); | 1054 | RETURN(); |
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | +/* Altivec vector extension */ | ||
1058 | +#if defined(WORDS_BIGENDIAN) | ||
1059 | +#define VR_DWORD0 0 | ||
1060 | +#define VR_DWORD1 1 | ||
1061 | +#else | ||
1062 | +#define VR_DWORD0 1 | ||
1063 | +#define VR_DWORD1 0 | ||
1064 | +#endif | ||
1065 | +void OPPROTO glue(op_vr_lvx, MEMSUFFIX) (void) | ||
1066 | +{ | ||
1067 | + AVR0.u64[VR_DWORD0] = glue(ldq, MEMSUFFIX)((uint32_t)T0); | ||
1068 | + AVR0.u64[VR_DWORD1] = glue(ldq, MEMSUFFIX)((uint32_t)T0 + 8); | ||
1069 | +} | ||
1070 | + | ||
1071 | +void OPPROTO glue(op_vr_lvx_le, MEMSUFFIX) (void) | ||
1072 | +{ | ||
1073 | + AVR0.u64[VR_DWORD1] = glue(ldq, MEMSUFFIX)((uint32_t)T0); | ||
1074 | + AVR0.u64[VR_DWORD0] = glue(ldq, MEMSUFFIX)((uint32_t)T0 + 8); | ||
1075 | +} | ||
1076 | + | ||
1077 | +void OPPROTO glue(op_vr_stvx, MEMSUFFIX) (void) | ||
1078 | +{ | ||
1079 | + glue(stq, MEMSUFFIX)((uint32_t)T0, AVR0.u64[VR_DWORD0]); | ||
1080 | + glue(stq, MEMSUFFIX)((uint32_t)T0 + 8, AVR0.u64[VR_DWORD1]); | ||
1081 | +} | ||
1082 | + | ||
1083 | +void OPPROTO glue(op_vr_stvx_le, MEMSUFFIX) (void) | ||
1084 | +{ | ||
1085 | + glue(stq, MEMSUFFIX)((uint32_t)T0, AVR0.u64[VR_DWORD1]); | ||
1086 | + glue(stq, MEMSUFFIX)((uint32_t)T0 + 8, AVR0.u64[VR_DWORD0]); | ||
1087 | +} | ||
1088 | + | ||
1089 | +#if defined(TARGET_PPC64) | ||
1090 | +void OPPROTO glue(op_vr_lvx_64, MEMSUFFIX) (void) | ||
1091 | +{ | ||
1092 | + AVR0.u64[VR_DWORD0] = glue(ldq, MEMSUFFIX)((uint64_t)T0); | ||
1093 | + AVR0.u64[VR_DWORD1] = glue(ldq, MEMSUFFIX)((uint64_t)T0 + 8); | ||
1094 | +} | ||
1095 | + | ||
1096 | +void OPPROTO glue(op_vr_lvx_le_64, MEMSUFFIX) (void) | ||
1097 | +{ | ||
1098 | + AVR0.u64[VR_DWORD1] = glue(ldq, MEMSUFFIX)((uint64_t)T0); | ||
1099 | + AVR0.u64[VR_DWORD0] = glue(ldq, MEMSUFFIX)((uint64_t)T0 + 8); | ||
1100 | +} | ||
1101 | + | ||
1102 | +void OPPROTO glue(op_vr_stvx_64, MEMSUFFIX) (void) | ||
1103 | +{ | ||
1104 | + glue(stq, MEMSUFFIX)((uint64_t)T0, AVR0.u64[VR_DWORD0]); | ||
1105 | + glue(stq, MEMSUFFIX)((uint64_t)T0 + 8, AVR0.u64[VR_DWORD1]); | ||
1106 | +} | ||
1107 | + | ||
1108 | +void OPPROTO glue(op_vr_stvx_le_64, MEMSUFFIX) (void) | ||
1109 | +{ | ||
1110 | + glue(stq, MEMSUFFIX)((uint64_t)T0, AVR0.u64[VR_DWORD1]); | ||
1111 | + glue(stq, MEMSUFFIX)((uint64_t)T0 + 8, AVR0.u64[VR_DWORD0]); | ||
1112 | +} | ||
1113 | +#endif | ||
1114 | +#undef VR_DWORD0 | ||
1115 | +#undef VR_DWORD1 | ||
1116 | + | ||
1057 | #if defined(TARGET_PPCEMB) | 1117 | #if defined(TARGET_PPCEMB) |
1058 | /* SPE extension */ | 1118 | /* SPE extension */ |
1059 | #define _PPC_SPE_LD_OP(name, op) \ | 1119 | #define _PPC_SPE_LD_OP(name, op) \ |
target-ppc/op_template.h
@@ -57,6 +57,7 @@ void OPPROTO glue(op_store_T2_gpr_gpr, REG) (void) | @@ -57,6 +57,7 @@ void OPPROTO glue(op_store_T2_gpr_gpr, REG) (void) | ||
57 | } | 57 | } |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | +/* General purpose registers containing vector operands moves */ | ||
60 | #if defined(TARGET_PPCEMB) | 61 | #if defined(TARGET_PPCEMB) |
61 | void OPPROTO glue(op_load_gpr64_T0_gpr, REG) (void) | 62 | void OPPROTO glue(op_load_gpr64_T0_gpr, REG) (void) |
62 | { | 63 | { |
@@ -99,6 +100,45 @@ void OPPROTO glue(op_store_T2_gpr64_gpr, REG) (void) | @@ -99,6 +100,45 @@ void OPPROTO glue(op_store_T2_gpr64_gpr, REG) (void) | ||
99 | #endif | 100 | #endif |
100 | #endif /* defined(TARGET_PPCEMB) */ | 101 | #endif /* defined(TARGET_PPCEMB) */ |
101 | 102 | ||
103 | +/* Altivec registers moves */ | ||
104 | +void OPPROTO glue(op_load_avr_A0_avr, REG) (void) | ||
105 | +{ | ||
106 | + AVR0 = env->avr[REG]; | ||
107 | + RETURN(); | ||
108 | +} | ||
109 | + | ||
110 | +void OPPROTO glue(op_load_avr_A1_avr, REG) (void) | ||
111 | +{ | ||
112 | + AVR1 = env->avr[REG]; | ||
113 | + RETURN(); | ||
114 | +} | ||
115 | + | ||
116 | +void OPPROTO glue(op_load_avr_A2_avr, REG) (void) | ||
117 | +{ | ||
118 | + AVR2 = env->avr[REG]; | ||
119 | + RETURN(); | ||
120 | +} | ||
121 | + | ||
122 | +void OPPROTO glue(op_store_A0_avr_avr, REG) (void) | ||
123 | +{ | ||
124 | + env->avr[REG] = AVR0; | ||
125 | + RETURN(); | ||
126 | +} | ||
127 | + | ||
128 | +void OPPROTO glue(op_store_A1_avr_avr, REG) (void) | ||
129 | +{ | ||
130 | + env->avr[REG] = AVR1; | ||
131 | + RETURN(); | ||
132 | +} | ||
133 | + | ||
134 | +#if 0 // unused | ||
135 | +void OPPROTO glue(op_store_A2_avr_avr, REG) (void) | ||
136 | +{ | ||
137 | + env->avr[REG] = AVR2; | ||
138 | + RETURN(); | ||
139 | +} | ||
140 | +#endif | ||
141 | + | ||
102 | #if REG <= 7 | 142 | #if REG <= 7 |
103 | /* Condition register moves */ | 143 | /* Condition register moves */ |
104 | void OPPROTO glue(op_load_crf_T0_crf, REG) (void) | 144 | void OPPROTO glue(op_load_crf_T0_crf, REG) (void) |
target-ppc/translate.c
@@ -164,6 +164,7 @@ typedef struct DisasContext { | @@ -164,6 +164,7 @@ typedef struct DisasContext { | ||
164 | int sf_mode; | 164 | int sf_mode; |
165 | #endif | 165 | #endif |
166 | int fpu_enabled; | 166 | int fpu_enabled; |
167 | + int altivec_enabled; | ||
167 | #if defined(TARGET_PPCEMB) | 168 | #if defined(TARGET_PPCEMB) |
168 | int spe_enabled; | 169 | int spe_enabled; |
169 | #endif | 170 | #endif |
@@ -235,6 +236,9 @@ GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0) | @@ -235,6 +236,9 @@ GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0) | ||
235 | #define GEN_EXCP_NO_AP(ctx) \ | 236 | #define GEN_EXCP_NO_AP(ctx) \ |
236 | GEN_EXCP(ctx, POWERPC_EXCP_APU, 0) | 237 | GEN_EXCP(ctx, POWERPC_EXCP_APU, 0) |
237 | 238 | ||
239 | +#define GEN_EXCP_NO_VR(ctx) \ | ||
240 | +GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0) | ||
241 | + | ||
238 | /* Stop translation */ | 242 | /* Stop translation */ |
239 | static always_inline void GEN_STOP (DisasContext *ctx) | 243 | static always_inline void GEN_STOP (DisasContext *ctx) |
240 | { | 244 | { |
@@ -5530,6 +5534,161 @@ GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE) | @@ -5530,6 +5534,161 @@ GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE) | ||
5530 | */ | 5534 | */ |
5531 | } | 5535 | } |
5532 | 5536 | ||
5537 | +/*** Altivec vector extension ***/ | ||
5538 | +/* Altivec registers moves */ | ||
5539 | +GEN32(gen_op_load_avr_A0, gen_op_load_avr_A0_avr); | ||
5540 | +GEN32(gen_op_load_avr_A1, gen_op_load_avr_A1_avr); | ||
5541 | +GEN32(gen_op_load_avr_A2, gen_op_load_avr_A2_avr); | ||
5542 | + | ||
5543 | +GEN32(gen_op_store_A0_avr, gen_op_store_A0_avr_avr); | ||
5544 | +GEN32(gen_op_store_A1_avr, gen_op_store_A1_avr_avr); | ||
5545 | +#if 0 // unused | ||
5546 | +GEN32(gen_op_store_A2_avr, gen_op_store_A2_avr_avr); | ||
5547 | +#endif | ||
5548 | + | ||
5549 | +#define op_vr_ldst(name) (*gen_op_##name[ctx->mem_idx])() | ||
5550 | +#if defined(CONFIG_USER_ONLY) | ||
5551 | +#if defined(TARGET_PPC64) | ||
5552 | +/* User-mode only - 64 bits mode */ | ||
5553 | +#define OP_VR_LD_TABLE(name) \ | ||
5554 | +static GenOpFunc *gen_op_vr_l##name[] = { \ | ||
5555 | + &gen_op_vr_l##name##_raw, \ | ||
5556 | + &gen_op_vr_l##name##_le_raw, \ | ||
5557 | + &gen_op_vr_l##name##_64_raw, \ | ||
5558 | + &gen_op_vr_l##name##_le_64_raw, \ | ||
5559 | +}; | ||
5560 | +#define OP_VR_ST_TABLE(name) \ | ||
5561 | +static GenOpFunc *gen_op_vr_st##name[] = { \ | ||
5562 | + &gen_op_vr_st##name##_raw, \ | ||
5563 | + &gen_op_vr_st##name##_le_raw, \ | ||
5564 | + &gen_op_vr_st##name##_64_raw, \ | ||
5565 | + &gen_op_vr_st##name##_le_64_raw, \ | ||
5566 | +}; | ||
5567 | +#else /* defined(TARGET_PPC64) */ | ||
5568 | +/* User-mode only - 32 bits mode */ | ||
5569 | +#define OP_VR_LD_TABLE(name) \ | ||
5570 | +static GenOpFunc *gen_op_vr_l##name[] = { \ | ||
5571 | + &gen_op_vr_l##name##_raw, \ | ||
5572 | + &gen_op_vr_l##name##_le_raw, \ | ||
5573 | +}; | ||
5574 | +#define OP_VR_ST_TABLE(name) \ | ||
5575 | +static GenOpFunc *gen_op_vr_st##name[] = { \ | ||
5576 | + &gen_op_vr_st##name##_raw, \ | ||
5577 | + &gen_op_vr_st##name##_le_raw, \ | ||
5578 | +}; | ||
5579 | +#endif /* defined(TARGET_PPC64) */ | ||
5580 | +#else /* defined(CONFIG_USER_ONLY) */ | ||
5581 | +#if defined(TARGET_PPC64H) | ||
5582 | +/* Full system with hypervisor mode */ | ||
5583 | +#define OP_VR_LD_TABLE(name) \ | ||
5584 | +static GenOpFunc *gen_op_vr_l##name[] = { \ | ||
5585 | + &gen_op_vr_l##name##_user, \ | ||
5586 | + &gen_op_vr_l##name##_le_user, \ | ||
5587 | + &gen_op_vr_l##name##_64_user, \ | ||
5588 | + &gen_op_vr_l##name##_le_64_user, \ | ||
5589 | + &gen_op_vr_l##name##_kernel, \ | ||
5590 | + &gen_op_vr_l##name##_le_kernel, \ | ||
5591 | + &gen_op_vr_l##name##_64_kernel, \ | ||
5592 | + &gen_op_vr_l##name##_le_64_kernel, \ | ||
5593 | + &gen_op_vr_l##name##_hypv, \ | ||
5594 | + &gen_op_vr_l##name##_le_hypv, \ | ||
5595 | + &gen_op_vr_l##name##_64_hypv, \ | ||
5596 | + &gen_op_vr_l##name##_le_64_hypv, \ | ||
5597 | +}; | ||
5598 | +#define OP_VR_ST_TABLE(name) \ | ||
5599 | +static GenOpFunc *gen_op_vr_st##name[] = { \ | ||
5600 | + &gen_op_vr_st##name##_user, \ | ||
5601 | + &gen_op_vr_st##name##_le_user, \ | ||
5602 | + &gen_op_vr_st##name##_64_user, \ | ||
5603 | + &gen_op_vr_st##name##_le_64_user, \ | ||
5604 | + &gen_op_vr_st##name##_kernel, \ | ||
5605 | + &gen_op_vr_st##name##_le_kernel, \ | ||
5606 | + &gen_op_vr_st##name##_64_kernel, \ | ||
5607 | + &gen_op_vr_st##name##_le_64_kernel, \ | ||
5608 | + &gen_op_vr_st##name##_hypv, \ | ||
5609 | + &gen_op_vr_st##name##_le_hypv, \ | ||
5610 | + &gen_op_vr_st##name##_64_hypv, \ | ||
5611 | + &gen_op_vr_st##name##_le_64_hypv, \ | ||
5612 | +}; | ||
5613 | +#elif defined(TARGET_PPC64) | ||
5614 | +/* Full system - 64 bits mode */ | ||
5615 | +#define OP_VR_LD_TABLE(name) \ | ||
5616 | +static GenOpFunc *gen_op_vr_l##name[] = { \ | ||
5617 | + &gen_op_vr_l##name##_user, \ | ||
5618 | + &gen_op_vr_l##name##_le_user, \ | ||
5619 | + &gen_op_vr_l##name##_64_user, \ | ||
5620 | + &gen_op_vr_l##name##_le_64_user, \ | ||
5621 | + &gen_op_vr_l##name##_kernel, \ | ||
5622 | + &gen_op_vr_l##name##_le_kernel, \ | ||
5623 | + &gen_op_vr_l##name##_64_kernel, \ | ||
5624 | + &gen_op_vr_l##name##_le_64_kernel, \ | ||
5625 | +}; | ||
5626 | +#define OP_VR_ST_TABLE(name) \ | ||
5627 | +static GenOpFunc *gen_op_vr_st##name[] = { \ | ||
5628 | + &gen_op_vr_st##name##_user, \ | ||
5629 | + &gen_op_vr_st##name##_le_user, \ | ||
5630 | + &gen_op_vr_st##name##_64_user, \ | ||
5631 | + &gen_op_vr_st##name##_le_64_user, \ | ||
5632 | + &gen_op_vr_st##name##_kernel, \ | ||
5633 | + &gen_op_vr_st##name##_le_kernel, \ | ||
5634 | + &gen_op_vr_st##name##_64_kernel, \ | ||
5635 | + &gen_op_vr_st##name##_le_64_kernel, \ | ||
5636 | +}; | ||
5637 | +#else /* defined(TARGET_PPC64) */ | ||
5638 | +/* Full system - 32 bits mode */ | ||
5639 | +#define OP_VR_LD_TABLE(name) \ | ||
5640 | +static GenOpFunc *gen_op_vr_l##name[] = { \ | ||
5641 | + &gen_op_vr_l##name##_user, \ | ||
5642 | + &gen_op_vr_l##name##_le_user, \ | ||
5643 | + &gen_op_vr_l##name##_kernel, \ | ||
5644 | + &gen_op_vr_l##name##_le_kernel, \ | ||
5645 | +}; | ||
5646 | +#define OP_VR_ST_TABLE(name) \ | ||
5647 | +static GenOpFunc *gen_op_vr_st##name[] = { \ | ||
5648 | + &gen_op_vr_st##name##_user, \ | ||
5649 | + &gen_op_vr_st##name##_le_user, \ | ||
5650 | + &gen_op_vr_st##name##_kernel, \ | ||
5651 | + &gen_op_vr_st##name##_le_kernel, \ | ||
5652 | +}; | ||
5653 | +#endif /* defined(TARGET_PPC64) */ | ||
5654 | +#endif /* defined(CONFIG_USER_ONLY) */ | ||
5655 | + | ||
5656 | +#define GEN_VR_LDX(name, opc2, opc3) \ | ||
5657 | +GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \ | ||
5658 | +{ \ | ||
5659 | + if (unlikely(!ctx->altivec_enabled)) { \ | ||
5660 | + GEN_EXCP_NO_VR(ctx); \ | ||
5661 | + return; \ | ||
5662 | + } \ | ||
5663 | + gen_addr_reg_index(ctx); \ | ||
5664 | + op_vr_ldst(vr_l##name); \ | ||
5665 | + gen_op_store_A0_avr(rD(ctx->opcode)); \ | ||
5666 | +} | ||
5667 | + | ||
5668 | +#define GEN_VR_STX(name, opc2, opc3) \ | ||
5669 | +GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \ | ||
5670 | +{ \ | ||
5671 | + if (unlikely(!ctx->altivec_enabled)) { \ | ||
5672 | + GEN_EXCP_NO_VR(ctx); \ | ||
5673 | + return; \ | ||
5674 | + } \ | ||
5675 | + gen_addr_reg_index(ctx); \ | ||
5676 | + gen_op_load_avr_A0(rS(ctx->opcode)); \ | ||
5677 | + op_vr_ldst(vr_st##name); \ | ||
5678 | +} | ||
5679 | + | ||
5680 | +OP_VR_LD_TABLE(vx); | ||
5681 | +GEN_VR_LDX(vx, 0x07, 0x03); | ||
5682 | +/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */ | ||
5683 | +#define gen_op_vr_lvxl gen_op_vr_lvx | ||
5684 | +GEN_VR_LDX(vxl, 0x07, 0x0B); | ||
5685 | + | ||
5686 | +OP_VR_ST_TABLE(vx); | ||
5687 | +GEN_VR_STX(vx, 0x07, 0x07); | ||
5688 | +/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */ | ||
5689 | +#define gen_op_vr_stvxl gen_op_vr_stvx | ||
5690 | +GEN_VR_STX(vxl, 0x07, 0x0F); | ||
5691 | + | ||
5533 | #if defined(TARGET_PPCEMB) | 5692 | #if defined(TARGET_PPCEMB) |
5534 | /*** SPE extension ***/ | 5693 | /*** SPE extension ***/ |
5535 | 5694 | ||
@@ -6553,11 +6712,15 @@ static always_inline int gen_intermediate_code_internal (CPUState *env, | @@ -6553,11 +6712,15 @@ static always_inline int gen_intermediate_code_internal (CPUState *env, | ||
6553 | ctx.dcache_line_size = env->dcache_line_size; | 6712 | ctx.dcache_line_size = env->dcache_line_size; |
6554 | ctx.fpu_enabled = msr_fp; | 6713 | ctx.fpu_enabled = msr_fp; |
6555 | #if defined(TARGET_PPCEMB) | 6714 | #if defined(TARGET_PPCEMB) |
6556 | - if (env->flags & POWERPC_FLAG_SPE) | 6715 | + if ((env->flags & POWERPC_FLAG_SPE) && msr_spe) |
6557 | ctx.spe_enabled = msr_spe; | 6716 | ctx.spe_enabled = msr_spe; |
6558 | else | 6717 | else |
6559 | ctx.spe_enabled = 0; | 6718 | ctx.spe_enabled = 0; |
6560 | #endif | 6719 | #endif |
6720 | + if ((env->flags & POWERPC_FLAG_VRE) && msr_vr) | ||
6721 | + ctx.altivec_enabled = msr_vr; | ||
6722 | + else | ||
6723 | + ctx.altivec_enabled = 0; | ||
6561 | if ((env->flags & POWERPC_FLAG_SE) && msr_se) | 6724 | if ((env->flags & POWERPC_FLAG_SE) && msr_se) |
6562 | single_step = 1; | 6725 | single_step = 1; |
6563 | else | 6726 | else |