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;