Hi,

 Due to a number of bugs mips32_next_pc () does not get many of the
branches right.  As a result breakpoints get inserted in wrong places thus
single-stepping does not work as expected.  The following patch fixes the
problem for me.  It also cleans up comments a bit.

 I was only able to test it on a MIPS I CPU so likely branches are not
runtime tested.  All of them were verified with MIPS documentation.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [EMAIL PROTECTED], PGP key available        +

diff -u --recursive --new-file gdb-5.0.macro/gdb/mips-tdep.c gdb-5.0/gdb/mips-tdep.c
--- gdb-5.0.macro/gdb/mips-tdep.c       Sun Apr  9 14:35:35 2000
+++ gdb-5.0/gdb/mips-tdep.c     Sat Jun 17 15:29:42 2000
@@ -596,21 +596,21 @@
   unsigned long inst;
   int op;
   inst = mips_fetch_instruction (pc);
-  if ((inst & 0xe0000000) != 0)        /* Not a special, junp or branch instruction */
+  if ((inst & 0xe0000000) != 0)        /* Not a special, jump or branch instruction */
     {
-      if ((inst >> 27) == 5)   /* BEQL BNEZ BLEZL BGTZE , bits 0101xx */
+      if ((inst >> 28) == 5)   /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
        {
-         op = ((inst >> 25) & 0x03);
+         op = ((inst >> 26) & 0x03);
          switch (op)
            {
-           case 0:
-             goto equal_branch;        /* BEQL   */
-           case 1:
-             goto neq_branch;  /* BNEZ   */
-           case 2:
-             goto less_branch; /* BLEZ   */
-           case 3:
-             goto greater_branch;      /* BGTZ */
+           case 0:             /* BEQL */
+             goto equal_branch;
+           case 1:             /* BNEL */
+             goto neq_branch;
+           case 2:             /* BLEZL */
+             goto less_branch;
+           case 3:             /* BGTZ */
+             goto greater_branch;
            default:
              pc += 4;
            }
@@ -636,45 +636,45 @@
              pc += 4;
            }
 
-         break;                /* end special */
+         break;        /* end SPECIAL */
        case 1:         /* REGIMM */
          {
            op = jtype_op (inst);       /* branch condition */
            switch (jtype_op (inst))
              {
              case 0:           /* BLTZ */
-             case 2:           /* BLTXL */
-             case 16:          /* BLTZALL */
+             case 2:           /* BLTZL */
+             case 16:          /* BLTZAL */
              case 18:          /* BLTZALL */
              less_branch:
-               if (read_register (itype_rs (inst)) < 0)
+               if ((LONGEST) read_register (itype_rs (inst)) < 0)
                  pc += mips32_relative_offset (inst) + 4;
                else
                  pc += 8;      /* after the delay slot */
                break;
-             case 1:           /* GEZ */
+             case 1:           /* BGEZ */
              case 3:           /* BGEZL */
              case 17:          /* BGEZAL */
              case 19:          /* BGEZALL */
              greater_equal_branch:
-               if (read_register (itype_rs (inst)) >= 0)
+               if ((LONGEST) read_register (itype_rs (inst)) >= 0)
                  pc += mips32_relative_offset (inst) + 4;
                else
                  pc += 8;      /* after the delay slot */
                break;
-               /* All of the other intructions in the REGIMM catagory */
+               /* All of the other instructions in the REGIMM category */
              default:
                pc += 4;
              }
          }
-         break;                /* end REGIMM */
+         break;        /* end REGIMM */
        case 2:         /* J */
        case 3:         /* JAL */
          {
            unsigned long reg;
            reg = jtype_target (inst) << 2;
+           /* Upper four bits never changed... */
            pc = reg + ((pc + 4) & 0xf0000000);
-           /* Whats this mysterious 0xf000000 adjustment ??? */
          }
          break;
          /* FIXME case JALX : */
@@ -685,38 +685,37 @@
            /* Add 1 to indicate 16 bit mode - Invert ISA mode */
          }
          break;                /* The new PC will be alternate mode */
-       case 4:         /* BEQ , BEQL */
+       case 4:         /* BEQ, BEQL */
        equal_branch:
-         if (read_register (itype_rs (inst)) ==
-             read_register (itype_rt (inst)))
+         if ((LONGEST) read_register (itype_rs (inst)) ==
+             (LONGEST) read_register (itype_rt (inst)))
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
-       case 5:         /* BNE , BNEL */
+       case 5:         /* BNE, BNEL */
        neq_branch:
-         if (read_register (itype_rs (inst)) !=
-             read_register (itype_rs (inst)))
+         if ((LONGEST) read_register (itype_rs (inst)) !=
+             (LONGEST) read_register (itype_rt (inst)))
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
-       case 6:         /* BLEZ , BLEZL */
+       case 6:         /* BLEZ, BLEZL */
        less_zero_branch:
-         if (read_register (itype_rs (inst) <= 0))
+         if ((LONGEST) read_register (itype_rs (inst)) <= 0)
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
        case 7:
-       greater_branch: /* BGTZ BGTZL */
-         if (read_register (itype_rs (inst) > 0))
+       default:
+       greater_branch: /* BGTZ, BGTZL */
+         if ((LONGEST) read_register (itype_rs (inst)) > 0)
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
-       default:
-         pc += 8;
        }                       /* switch */
     }                          /* else */
   return pc;

Reply via email to