aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/translate.c
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-10-31 22:02:17 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-10-31 22:02:17 +0000
commitfc0d441e14f07a35f9ea67ac8ca032a2ea902b38 (patch)
treed4a93196453e54252f08e88067000b195d8c10ef /target-ppc/translate.c
parenta79ee211ceee191de97d0862a93128e7688a2843 (diff)
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
Diffstat (limited to 'target-ppc/translate.c')
-rw-r--r--target-ppc/translate.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c3e5340f20..015a6215a3 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -120,7 +120,9 @@ static always_inline void func (int n) \
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
+#if 0 // Unused
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
+#endif
/* General purpose registers moves */
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)
#define GEN_CRLOGIC(op, opc) \
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) \
{ \
+ uint8_t bitmask; \
+ int sh; \
gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \
- gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03)); \
+ sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03); \
+ if (sh > 0) \
+ gen_op_srli_T0(sh); \
+ else if (sh < 0) \
+ gen_op_sli_T0(-sh); \
gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \
- gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03)); \
+ sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03); \
+ if (sh > 0) \
+ gen_op_srli_T1(sh); \
+ else if (sh < 0) \
+ gen_op_sli_T1(-sh); \
gen_op_##op(); \
+ bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03)); \
+ gen_op_andi_T0(bitmask); \
gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \
- gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))), \
- 3 - (crbD(ctx->opcode) & 0x03)); \
- gen_op_store_T1_crf(crbD(ctx->opcode) >> 2); \
+ gen_op_andi_T1(~bitmask); \
+ gen_op_or(); \
+ gen_op_store_T0_crf(crbD(ctx->opcode) >> 2); \
}
/* crand */