Fix CR ops with complement, thanks to Julian Seward for testing
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 31 Oct 2007 22:02:17 +0000 (22:02 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 31 Oct 2007 22:02:17 +0000 (22:02 +0000)
                            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

target-ppc/op.c
target-ppc/op_template.h
target-ppc/translate.c

index 4c170d8..da08ec5 100644 (file)
@@ -651,25 +651,6 @@ void OPPROTO op_store_fpscr (void)
     RETURN();
 }
 
-/* crf operations */
-void OPPROTO op_getbit_T0 (void)
-{
-    T0 = (T0 >> PARAM1) & 1;
-    RETURN();
-}
-
-void OPPROTO op_getbit_T1 (void)
-{
-    T1 = (T1 >> PARAM1) & 1;
-    RETURN();
-}
-
-void OPPROTO op_setcrfbit (void)
-{
-    T1 = (T1 & (uint32_t)PARAM1) | (T0 << PARAM2);
-    RETURN();
-}
-
 /* Branch */
 #define EIP env->nip
 
@@ -1737,6 +1718,12 @@ void OPPROTO op_sli_T0 (void)
     RETURN();
 }
 
+void OPPROTO op_sli_T1 (void)
+{
+    T1 = T1 << PARAM1;
+    RETURN();
+}
+
 void OPPROTO op_srl_T0_T1 (void)
 {
     T0 = (uint32_t)T0 >> T1;
index bdd8844..51f9b36 100644 (file)
@@ -159,11 +159,13 @@ void OPPROTO glue(op_store_T0_crf_crf, REG) (void)
     RETURN();
 }
 
+#if 0 // Unused
 void OPPROTO glue(op_store_T1_crf_crf, REG) (void)
 {
     env->crf[REG] = T1;
     RETURN();
 }
+#endif
 
 #endif /* REG <= 7 */
 
index c3e5340..015a621 100644 (file)
@@ -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 */