Commit fc0d441e14f07a35f9ea67ac8ca032a2ea902b38
1 parent
a79ee211
Fix CR ops with complement, thanks to Julian Seward for testing
and reporting the bug : * remove bugged CR ops specific micro-ops * use standard and / or / shift operations instead * comment not-used-anymore op_store_T1_crf_crf micro-op template. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3501 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
27 additions
and
24 deletions
target-ppc/op.c
| ... | ... | @@ -651,25 +651,6 @@ void OPPROTO op_store_fpscr (void) |
| 651 | 651 | RETURN(); |
| 652 | 652 | } |
| 653 | 653 | |
| 654 | -/* crf operations */ | |
| 655 | -void OPPROTO op_getbit_T0 (void) | |
| 656 | -{ | |
| 657 | - T0 = (T0 >> PARAM1) & 1; | |
| 658 | - RETURN(); | |
| 659 | -} | |
| 660 | - | |
| 661 | -void OPPROTO op_getbit_T1 (void) | |
| 662 | -{ | |
| 663 | - T1 = (T1 >> PARAM1) & 1; | |
| 664 | - RETURN(); | |
| 665 | -} | |
| 666 | - | |
| 667 | -void OPPROTO op_setcrfbit (void) | |
| 668 | -{ | |
| 669 | - T1 = (T1 & (uint32_t)PARAM1) | (T0 << PARAM2); | |
| 670 | - RETURN(); | |
| 671 | -} | |
| 672 | - | |
| 673 | 654 | /* Branch */ |
| 674 | 655 | #define EIP env->nip |
| 675 | 656 | |
| ... | ... | @@ -1737,6 +1718,12 @@ void OPPROTO op_sli_T0 (void) |
| 1737 | 1718 | RETURN(); |
| 1738 | 1719 | } |
| 1739 | 1720 | |
| 1721 | +void OPPROTO op_sli_T1 (void) | |
| 1722 | +{ | |
| 1723 | + T1 = T1 << PARAM1; | |
| 1724 | + RETURN(); | |
| 1725 | +} | |
| 1726 | + | |
| 1740 | 1727 | void OPPROTO op_srl_T0_T1 (void) |
| 1741 | 1728 | { |
| 1742 | 1729 | T0 = (uint32_t)T0 >> T1; | ... | ... |
target-ppc/op_template.h
| ... | ... | @@ -159,11 +159,13 @@ void OPPROTO glue(op_store_T0_crf_crf, REG) (void) |
| 159 | 159 | RETURN(); |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | +#if 0 // Unused | |
| 162 | 163 | void OPPROTO glue(op_store_T1_crf_crf, REG) (void) |
| 163 | 164 | { |
| 164 | 165 | env->crf[REG] = T1; |
| 165 | 166 | RETURN(); |
| 166 | 167 | } |
| 168 | +#endif | |
| 167 | 169 | |
| 168 | 170 | #endif /* REG <= 7 */ |
| 169 | 171 | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -120,7 +120,9 @@ static always_inline void func (int n) \ |
| 120 | 120 | GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf); |
| 121 | 121 | GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf); |
| 122 | 122 | GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf); |
| 123 | +#if 0 // Unused | |
| 123 | 124 | GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf); |
| 125 | +#endif | |
| 124 | 126 | |
| 125 | 127 | /* General purpose registers moves */ |
| 126 | 128 | GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr); |
| ... | ... | @@ -3318,15 +3320,27 @@ GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW) |
| 3318 | 3320 | #define GEN_CRLOGIC(op, opc) \ |
| 3319 | 3321 | GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) \ |
| 3320 | 3322 | { \ |
| 3323 | + uint8_t bitmask; \ | |
| 3324 | + int sh; \ | |
| 3321 | 3325 | gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \ |
| 3322 | - gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03)); \ | |
| 3326 | + sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03); \ | |
| 3327 | + if (sh > 0) \ | |
| 3328 | + gen_op_srli_T0(sh); \ | |
| 3329 | + else if (sh < 0) \ | |
| 3330 | + gen_op_sli_T0(-sh); \ | |
| 3323 | 3331 | gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \ |
| 3324 | - gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03)); \ | |
| 3332 | + sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03); \ | |
| 3333 | + if (sh > 0) \ | |
| 3334 | + gen_op_srli_T1(sh); \ | |
| 3335 | + else if (sh < 0) \ | |
| 3336 | + gen_op_sli_T1(-sh); \ | |
| 3325 | 3337 | gen_op_##op(); \ |
| 3338 | + bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03)); \ | |
| 3339 | + gen_op_andi_T0(bitmask); \ | |
| 3326 | 3340 | gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \ |
| 3327 | - gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))), \ | |
| 3328 | - 3 - (crbD(ctx->opcode) & 0x03)); \ | |
| 3329 | - gen_op_store_T1_crf(crbD(ctx->opcode) >> 2); \ | |
| 3341 | + gen_op_andi_T1(~bitmask); \ | |
| 3342 | + gen_op_or(); \ | |
| 3343 | + gen_op_store_T0_crf(crbD(ctx->opcode) >> 2); \ | |
| 3330 | 3344 | } |
| 3331 | 3345 | |
| 3332 | 3346 | /* crand */ | ... | ... |