This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] MIPS: Handle MIPS-3D and DSP ASE branch instructions


On Mon, 5 Dec 2011, Joel Brobecker wrote:

> > 2011-11-23  Maciej W. Rozycki  <macro@codesourcery.com>
> > 
> > 	gdb/
> > 	* mips-tdep.c (mips32_bc1_pc): New function, factored out from...
> > 	(mips32_next_pc): ... here.  Handle BC1ANY2F, BC1ANY2T, BC1ANY4F, 
> > 	BC1ANY4T, BPOSGE32 and BPOSGE64 instructions.
> > 	(deal_with_atomic_sequence): Likewise.
> > 	(mips32_instruction_has_delay_slot): Likewise.
> 
> Pre-approved with one minor coding-style change...

 Thanks, this depends on gdb-mips-dsp-linux.diff, so I'll wait till that 
is approved first.

> > +      return (op >> 2 == 5)	/* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
> > +	     || (op == 29)	/* JALX: bits 011101 */
> > +	     || ((op == 17)
> > +		 && ((rs == 8)
> >  				/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
> > +		     || ((rs == 9) && ((rt & 0x2) == 0))
> > +				/* BC1ANY2F, BC1ANY2T: bits 010001 01001 */
> > +		     || ((rs == 10) && ((rt & 0x2) == 0))));
> > +				/* BC1ANY4F, BC1ANY4T: bits 010001 01010 */
> 
> Use an extra pair of parentheses around the entire condition...

 Umm, well...  It's just inherited the weird bracketing style from 
gdb-mips-breakpoint-adjust.diff; I've fixed both now, removing some 
redundant brackets too.  That should improve readability somewhat (except 
for Lisp lovers perhaps).  Here's the result; will apply in due course 
unless you have further comments.

  Maciej

2011-12-07  Maciej W. Rozycki  <macro@codesourcery.com>

	gdb/
	* mips-tdep.c (mips32_bc1_pc): New function.
	(mips32_next_pc): Handle BC1ANY2F, BC1ANY2T, BC1ANY4F, BC1ANY4T,
	BPOSGE32 and BPOSGE64 instructions.
	(deal_with_atomic_sequence): Likewise.
	(mips32_instruction_has_delay_slot): Likewise.

gdb-mips-branch-mips3d-dsp.diff
Index: gdb-fsf-trunk-quilt/gdb/mips-tdep.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/mips-tdep.c	2011-12-07 20:32:38.000000000 +0000
+++ gdb-fsf-trunk-quilt/gdb/mips-tdep.c	2011-12-07 20:43:52.165559962 +0000
@@ -1134,6 +1134,36 @@ mips32_relative_offset (ULONGEST inst)
   return ((itype_immediate (inst) ^ 0x8000) - 0x8000) << 2;
 }
 
+/* Determine the address of the next instruction executed after the INST
+   floating condition branch instruction at PC.  COUNT specifies the
+   number of the floating condition bits tested by the branch.  */
+
+static CORE_ADDR
+mips32_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
+	       ULONGEST inst, CORE_ADDR pc, int count)
+{
+  int fcsr = mips_regnum (gdbarch)->fp_control_status;
+  int cnum = (itype_rt (inst) >> 2) & (count - 1);
+  int tf = itype_rt (inst) & 1;
+  int mask = (1 << count) - 1;
+  ULONGEST fcs;
+  int cond;
+
+  if (fcsr == -1)
+    /* No way to handle; it'll most likely trap anyway.  */
+    return pc;
+
+  fcs = get_frame_register_unsigned (frame, fcsr);
+  cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);
+
+  if (((cond >> cnum) & mask) != mask * !tf)
+    pc += mips32_relative_offset (inst);
+  else
+    pc += 4;
+
+  return pc;
+}
+
 /* Determine where to set a single step breakpoint while considering
    branch prediction.  */
 static CORE_ADDR
@@ -1166,20 +1196,15 @@ mips32_next_pc (struct frame_info *frame
 	}
       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 =
-	    get_frame_register_signed (frame,
-				       mips_regnum (get_frame_arch (frame))->
-						fp_control_status);
-	  int cond = ((fcrcs >> 24) & 0xfe) | ((fcrcs >> 23) & 0x01);
-
-	  if (((cond >> cnum) & 0x01) == tf)
-	    pc += mips32_relative_offset (inst) + 4;
-	  else
-	    pc += 8;
-	}
+	pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 1);
+      else if (itype_op (inst) == 17 && itype_rs (inst) == 9
+	       && (itype_rt (inst) & 2) == 0)
+	/* BC1ANY2F, BC1ANY2T: 010001 01001 xxx0x */
+	pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 2);
+      else if (itype_op (inst) == 17 && itype_rs (inst) == 10
+	       && (itype_rt (inst) & 2) == 0)
+	/* BC1ANY4F, BC1ANY4T: 010001 01010 xxx0x */
+	pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 4);
       else
 	pc += 4;		/* Not a branch, next instruction is easy.  */
     }
@@ -1238,6 +1263,25 @@ mips32_next_pc (struct frame_info *frame
 		else
 		  pc += 8;	/* after the delay slot */
 		break;
+	      case 0x1c:	/* BPOSGE32 */
+	      case 0x1e:	/* BPOSGE64 */
+		pc += 4;
+		if (itype_rs (inst) == 0)
+		  {
+		    unsigned int pos = (op & 2) ? 64 : 32;
+		    int dspctl = mips_regnum (gdbarch)->dspctl;
+
+		    if (dspctl == -1)
+		      /* No way to handle; it'll most likely trap anyway.  */
+		      break;
+
+		    if ((get_frame_register_unsigned (frame,
+						      dspctl) & 0x7f) >= pos)
+		      pc += mips32_relative_offset (inst);
+		    else
+		      pc += 4;
+		  }
+		break;
 		/* All of the other instructions in the REGIMM category */
 	      default:
 		pc += 4;
@@ -2650,7 +2694,9 @@ deal_with_atomic_sequence (struct gdbarc
 	    return 0; /* fallback to the standard single-step code.  */
 	  break;
 	case 1: /* REGIMM */
-	  is_branch = ((itype_rt (insn) & 0xc) == 0); /* B{LT,GE}Z* */
+	  is_branch = ((itype_rt (insn) & 0xc) == 0 /* B{LT,GE}Z* */
+		       || ((itype_rt (insn) & 0x1e) == 0
+			   && itype_rs (insn) == 0)); /* BPOSGE* */
 	  break;
 	case 2: /* J */
 	case 3: /* JAL */
@@ -2666,6 +2712,11 @@ deal_with_atomic_sequence (struct gdbarc
 	  is_branch = 1;
 	  break;
 	case 17: /* COP1 */
+	  is_branch = ((itype_rs (insn) == 9 || itype_rs (insn) == 10)
+		       && (itype_rt (insn) & 0x2) == 0);
+	  if (is_branch) /* BC1ANY2F, BC1ANY2T, BC1ANY4F, BC1ANY4T */
+	    break;
+	/* Fall through.  */
 	case 18: /* COP2 */
 	case 19: /* COP3 */
 	  is_branch = (itype_rs (insn) == 8); /* BCzF, BCzFL, BCzT, BCzTL */
@@ -5365,6 +5416,8 @@ mips32_instruction_has_delay_slot (struc
   unsigned long inst;
   int status;
   int op;
+  int rs;
+  int rt;
 
   status = target_read_memory (addr, buf, MIPS_INSN32_SIZE);
   if (status)
@@ -5373,10 +5426,19 @@ mips32_instruction_has_delay_slot (struc
   inst = mips_fetch_instruction (gdbarch, addr);
   op = itype_op (inst);
   if ((inst & 0xe0000000) != 0)
-    return (op >> 2 == 5	/* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx  */
-	    || op == 29		/* JALX: bits 011101  */
-	    || (op == 17 && itype_rs (inst) == 8));
+    {
+      rs = itype_rs (inst);
+      rt = itype_rt (inst);
+      return (op >> 2 == 5	/* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx  */
+	      || op == 29	/* JALX: bits 011101  */
+	      || (op == 17
+		  && (rs == 8
 				/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000  */
+		      || (rs == 9 && (rt & 0x2) == 0)
+				/* BC1ANY2F, BC1ANY2T: bits 010001 01001  */
+		      || (rs == 10 && (rt & 0x2) == 0))));
+				/* BC1ANY4F, BC1ANY4T: bits 010001 01010  */
+    }
   else
     switch (op & 0x07)		/* extract bits 28,27,26  */
       {
@@ -5386,10 +5448,13 @@ mips32_instruction_has_delay_slot (struc
 		|| op == 9);	/* JALR  */
 	break;			/* end SPECIAL  */
       case 1:			/* REGIMM  */
-	op = itype_rt (inst);	/* branch condition  */
-	return (op & 0xc) == 0;
+	rs = itype_rs (inst);
+	rt = itype_rt (inst);	/* branch condition  */
+	return ((rt & 0xc) == 0
 				/* BLTZ, BLTZL, BGEZ, BGEZL: bits 000xx  */
 				/* BLTZAL, BLTZALL, BGEZAL, BGEZALL: 100xx  */
+		|| ((rt & 0x1e) == 0x1c && rs == 0));
+				/* BPOSGE32, BPOSGE64: bits 1110x  */
 	break;			/* end REGIMM  */
       default:			/* J, JAL, BEQ, BNE, BLEZ, BGTZ  */
 	return 1;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]