From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Jacobowitz To: gdb-patches@sources.redhat.com Subject: [RFA] mips32_next_pc overdue cleanup Date: Wed, 04 Jul 2001 11:41:00 -0000 Message-id: <20010704114147.A15695@nevyn.them.org> X-SW-Source: 2001-07/msg00050.html This patch is half style cleanups and half obvious fixes, but there's so many I'd appreciate more eyes. According to the masks in the opcodes directory, these changes are rigt, and what we had before can't possibly work. Especially the fact that we would never, ever predict a BNE as taken before these changes convinced me that they really were correct and this code had never been particularly tested. Comments? -- Daniel Jacobowitz Carnegie Mellon University MontaVista Software Debian GNU/Linux Developer 2001-07-04 Daniel Jacobowitz * mips-tdep.c (mips32_op): Correct offset. (itype_op): Likewise. (itype_rs): Fix formatting. (itype_immediate): Fix formatting. (jtype_op): Correct offset. (jtype_target): Fix formatting. (rtype_op): Correct offset. (rtype_rs): Fix formatting. (rtype_rt): Likewise. (rtype_rd): Likewise. (rtype_shamt): Likewise. (rtype_funct): Likewise. (mips32_next_pc): Fix formatting and comments. Recognize coprocessor 1 branches. Check the correct field for BLT family branches. Use itype_rt instead of itype_rs for the second register of a BNE or BNEL branch. Move (unreachable) default case. Index: gdb/mips-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/mips-tdep.c,v retrieving revision 1.54 diff -u -r1.54 mips-tdep.c --- mips-tdep.c 2001/06/16 20:00:24 1.54 +++ mips-tdep.c 2001/07/04 18:15:03 @@ -669,21 +669,21 @@ /* These the fields of 32 bit mips instructions */ -#define mips32_op(x) (x >> 25) -#define itype_op(x) (x >> 25) -#define itype_rs(x) ((x >> 21)& 0x1f) +#define mips32_op(x) (x >> 26) +#define itype_op(x) (x >> 26) +#define itype_rs(x) ((x >> 21) & 0x1f) #define itype_rt(x) ((x >> 16) & 0x1f) -#define itype_immediate(x) ( x & 0xffff) +#define itype_immediate(x) (x & 0xffff) -#define jtype_op(x) (x >> 25) -#define jtype_target(x) ( x & 0x03fffff) +#define jtype_op(x) (x >> 26) +#define jtype_target(x) (x & 0x03ffffff) -#define rtype_op(x) (x >>25) -#define rtype_rs(x) ((x>>21) & 0x1f) -#define rtype_rt(x) ((x>>16) & 0x1f) -#define rtype_rd(x) ((x>>11) & 0x1f) -#define rtype_shamt(x) ((x>>6) & 0x1f) -#define rtype_funct(x) (x & 0x3f ) +#define rtype_op(x) (x >> 26) +#define rtype_rs(x) ((x >> 21) & 0x1f) +#define rtype_rt(x) ((x >> 16) & 0x1f) +#define rtype_rd(x) ((x >> 11) & 0x1f) +#define rtype_shamt(x) ((x >> 6) & 0x1f) +#define rtype_funct(x) (x & 0x3f) static CORE_ADDR mips32_relative_offset (unsigned long inst) @@ -706,25 +706,39 @@ 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 (itype_op (inst) >> 2 == 5) + /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */ { - op = ((inst >> 25) & 0x03); + op = (itype_op (inst) & 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; } } + else if (itype_op (inst) == 17 && itype_rs (inst) == 8) + /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */ + { + int tf = itype_rt (inst) & 0x01; + int cnum = itype_rt (inst) >> 2; + int fcrcs = read_signed_register (FCRCS_REGNUM); + int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01); + + if (((cond >> cnum) & 0x01) == tf) + pc += mips32_relative_offset (inst) + 4; + else + pc += 8; + } else pc += 4; /* Not a branch, next instruction is easy */ } @@ -732,7 +746,7 @@ { /* This gets way messy */ /* Further subdivide into SPECIAL, REGIMM and other */ - switch (op = ((inst >> 26) & 0x07)) /* extract bits 28,27,26 */ + switch (op = itype_op (inst) & 0x07) /* extract bits 28,27,26 */ { case 0: /* SPECIAL */ op = rtype_funct (inst); @@ -747,15 +761,15 @@ pc += 4; } - break; /* end special */ + break; /* end SPECIAL */ case 1: /* REGIMM */ { - op = jtype_op (inst); /* branch condition */ - switch (jtype_op (inst)) + op = itype_rt (inst); /* branch condition */ + switch (op) { case 0: /* BLTZ */ - case 2: /* BLTXL */ - case 16: /* BLTZALL */ + case 2: /* BLTZL */ + case 16: /* BLTZAL */ case 18: /* BLTZALL */ less_branch: if (read_signed_register (itype_rs (inst)) < 0) @@ -763,7 +777,7 @@ else pc += 8; /* after the delay slot */ break; - case 1: /* GEZ */ + case 1: /* BGEZ */ case 3: /* BGEZL */ case 17: /* BGEZAL */ case 19: /* BGEZALL */ @@ -773,19 +787,19 @@ 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 get never changed... */ pc = reg + ((pc + 4) & 0xf0000000); - /* Whats this mysterious 0xf000000 adjustment ??? */ } break; /* FIXME case JALX : */ @@ -796,7 +810,7 @@ /* 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_signed_register (itype_rs (inst)) == read_signed_register (itype_rt (inst))) @@ -804,15 +818,15 @@ else pc += 8; break; - case 5: /* BNE , BNEL */ + case 5: /* BNE, BNEL */ neq_branch: if (read_signed_register (itype_rs (inst)) != - read_signed_register (itype_rs (inst))) + read_signed_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_signed_register (itype_rs (inst) <= 0)) pc += mips32_relative_offset (inst) + 4; @@ -820,14 +834,13 @@ pc += 8; break; case 7: - greater_branch: /* BGTZ BGTZL */ + default: + greater_branch: /* BGTZ, BGTZL */ if (read_signed_register (itype_rs (inst) > 0)) pc += mips32_relative_offset (inst) + 4; else pc += 8; break; - default: - pc += 8; } /* switch */ } /* else */ return pc;