Port-mips archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

branch emulation bug in matt-nb5-mips64 branch



Hello,
in the matt-nb5-mips64 branch, in mips_emul.c:MachEmulateBranch(), the
BRANCHTARGET macro was changed to take the value instead of a pointer to
instruction. But the effect of this change is that now, the
instruction's word value is used to compute the new PC, instead of the
instruction's address. Of course this can't give good results, and
in my case this gave an unaligned PC.

The attached diff fixes the problem for me; it should probably be
commited to the branch.

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: mips_emul.c
===================================================================
--- mips_emul.c (revision 66)
+++ mips_emul.c (working copy)
@@ -102,11 +102,11 @@
 MachEmulateBranch(struct trapframe *tf, vaddr_t instpc, unsigned fpuCSR,
     int allowNonBranch)
 {
-#define        BRANCHTARGET(i) (4 + ((i).word) + ((short)(i).IType.imm << 2))
+#define        BRANCHTARGET(pc, i) (4 + (pc) + ((short)(i).IType.imm << 2))
        InstFmt inst;
        vaddr_t nextpc;
 
        if (instpc < MIPS_KSEG0_START)
                inst.word = ufetch_uint32((void *)instpc);
        else
                inst.word = *(unsigned *)instpc;
@@ -129,7 +129,7 @@
                case OP_BLTZL:          /* squashed */
                case OP_BLTZALL:        /* squashed */
                        if ((int)(tf->tf_regs[inst.RType.rs]) < 0)
-                               nextpc = BRANCHTARGET(inst);
+                               nextpc = BRANCHTARGET(instpc, inst);
                        else
                                nextpc = instpc + 8;
                        break;
@@ -139,7 +139,7 @@
                case OP_BGEZL:          /* squashed */
                case OP_BGEZALL:        /* squashed */
                        if ((int)(tf->tf_regs[inst.RType.rs]) >= 0)
-                               nextpc = BRANCHTARGET(inst);
+                               nextpc = BRANCHTARGET(instpc, inst);
                        else
                                nextpc = instpc + 8;
                        break;
@@ -159,7 +159,7 @@
        case OP_BEQ:
        case OP_BEQL:   /* squashed */
                if (tf->tf_regs[inst.RType.rs] == tf->tf_regs[inst.RType.rt])
-                       nextpc = BRANCHTARGET(inst);
+                       nextpc = BRANCHTARGET(instpc, inst);
                else
                        nextpc = instpc + 8;
                break;
@@ -167,7 +167,7 @@
        case OP_BNE:
        case OP_BNEL:   /* squashed */
                if (tf->tf_regs[inst.RType.rs] != tf->tf_regs[inst.RType.rt])
-                       nextpc = BRANCHTARGET(inst);
+                       nextpc = BRANCHTARGET(instpc, inst);
                else
                        nextpc = instpc + 8;
                break;
@@ -175,7 +175,7 @@
        case OP_BLEZ:
        case OP_BLEZL:  /* squashed */
                if ((int)(tf->tf_regs[inst.RType.rs]) <= 0)
-                       nextpc = BRANCHTARGET(inst);
+                       nextpc = BRANCHTARGET(instpc, inst);
                else
                        nextpc = instpc + 8;
                break;
@@ -183,7 +183,7 @@
        case OP_BGTZ:
        case OP_BGTZL:  /* squashed */
                if ((int)(tf->tf_regs[inst.RType.rs]) > 0)
-                       nextpc = BRANCHTARGET(inst);
+                       nextpc = BRANCHTARGET(instpc, inst);
                else
                        nextpc = instpc + 8;
                break;
@@ -194,7 +194,7 @@
                        if ((inst.RType.rt & COPz_BC_TF_MASK) != COPz_BC_TRUE)
                                condition = !condition;
                        if (condition)
-                               nextpc = BRANCHTARGET(inst);
+                               nextpc = BRANCHTARGET(instpc, inst);
                        else
                                nextpc = instpc + 8;
                }
@@ -211,6 +211,7 @@
                            __func__, "non-branch", inst.word, instpc);
                nextpc = instpc + 4;
        }
+       KASSERT((nextpc & 0x3) == 0);
        return nextpc;
 #undef BRANCHTARGET
 }


Home | Main Index | Thread Index | Old Index