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