Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Bhushan Attarde <bhushan.attarde@imgtec.com>
To: <gdb-patches@sourceware.org>
Cc: <Maciej.Rozycki@imgtec.com>, <Matthew.Fortune@imgtec.com>,
	<James.Hogan@imgtec.com>, <Andrew.Bennett@imgtec.com>,
	<Jaydeep.Patil@imgtec.com>,
	Bhushan Attarde <bhushan.attarde@imgtec.com>
Subject: [PATCH 19/24]     Add MIPS MSA vector branch instruction support
Date: Mon, 27 Jun 2016 14:51:00 -0000	[thread overview]
Message-ID: <1467038991-6600-19-git-send-email-bhushan.attarde@imgtec.com> (raw)
In-Reply-To: <1467038991-6600-1-git-send-email-bhushan.attarde@imgtec.com>

    Add support for the MIPS & microMIPS MSA vector branch instructions,
    primarily to allow them to be single stepped.

    There are 4 such branch encodings:
     - BZ.df (BZ.B, BZ.H, BZ.W, BZ.D)
       Branch if any element in vector in the given format is zero.
     - BZ.V
       Branch if every element in vector in any format (i.e. the whole vector)
       is zero.
     - BNZ.df (BZ.B, BZ.H, BZ.W, BZ.D)
       Branch if no element in vector in the given format is zero. This is the
       inverse of BZ.df.
     - BNZ.V
       Branch if any element in vector in any format (i.e. any bit in whole
       vector) is non-zero. This is the inverse of BZ.V.

    The MIPS encodings use the COP1 opcode, and the microMIPS encodings use
    the POOL32D opcode.

    gdb/ChangeLog:

    	* mips-tdep.c (mips_bc1_w_taken): New function.
    	(mips32_bc1_w_pc): Likewise.
    	(micromips_bc1_w_pc): Likewise.
    	(mips32_next_pc): Add cases for BZ.df/BNZ.df and BZ.V/BNZ.V.
    	(micromips_next_pc): Likewise.
    	(mips_deal_with_atomic_sequence): Recognise BZ.df/BNZ.df and
    	BZ.V/BNZ.V as branches.
    	(micromips_deal_with_atomic_sequence): Likewise.
    	(mips32_instruction_has_delay_slot): Likewise.
    	(micromips_instruction_has_delay_slot): Likewise.
---
 gdb/mips-tdep.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 171 insertions(+), 4 deletions(-)

diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 63291db..7a6d23d 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -2496,6 +2496,100 @@ mips32_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
   return pc;
 }
 
+/* Determine whether a vector branch will be taken.
+   Returns 1 if branch taken, 0 if branch not taken, -1 on error. */
+
+static int
+mips_bc1_w_taken (struct gdbarch *gdbarch, struct frame_info *frame,
+		  unsigned int op, unsigned int wt)
+{
+  int wr = gdbarch_num_regs (gdbarch) + mips_regnum (gdbarch)->w0;
+  int taken = -1;
+  int size, elem_size, tog;
+  gdb_byte *buf, *end, *elem_end;
+
+  if (wr == -1)
+    /* No way to handle; it'll most likely trap anyway.  */
+    return -1;
+  wr += wt;
+
+  /* Read vector register.  */
+  size = register_size (gdbarch, wr);
+  buf = alloca (size);
+  if (!deprecated_frame_register_read (frame, wr, buf))
+    return -1;
+
+  if ((op & 0x18) == 0x18)
+    {
+      elem_size = 1 << (op & 0x3);
+      /* Check whether this branch would be taken first:
+	 BZ.df: 110xx (branch if at least one element is zero) */
+      taken = 0;
+      for (end = buf + size; buf < end;)
+	{
+	  taken = 1;
+	  for (elem_end = buf + elem_size; buf < elem_end; ++buf)
+	    if (*buf)
+	      {
+		/* this element is non-zero */
+		taken = 0;
+		break;
+	      }
+	  if (taken)
+	    /* this element zero, branch taken */
+	    break;
+	  buf = elem_end;
+	}
+
+      if (op & 0x4)
+	/* BNZ.df: 111xx (branch if all elements are non-zero)
+	   Branch taken is inverted compared to BZ.df */
+	taken = !taken;
+    }
+  else if ((op & 0x1b) == 0x0b)
+    {
+      /* Check whether this branch would be taken first:
+	 BZ.V:  01011 (branch if all elements are zero) */
+      taken = 1;
+      for (end = buf + size; buf < end; ++buf)
+	if (*buf)
+	  {
+	    /* this element is non-zero, branch not taken */
+	    taken = 0;
+	    break;
+	  }
+      if (op & 0x4)
+	/* BNZ.V: 01111 (branch if any elements are non-zero)
+	   Branch taken is inverted compared to BZ.V */
+	taken = !taken;
+    }
+
+  return taken;
+}
+
+/* Determine the address of the next instruction executed after the INST
+   vector branch instruction at PC.  */
+
+static CORE_ADDR
+mips32_bc1_w_pc (struct gdbarch *gdbarch, struct frame_info *frame,
+		 ULONGEST inst, CORE_ADDR pc)
+{
+  int op = itype_rs (inst);
+  int wt = itype_rt (inst);
+  int taken;
+
+  /* Will the branch be taken? */
+  taken = mips_bc1_w_taken (gdbarch, frame, op, wt);
+
+  /* Calculate branch target */
+  if (taken > 0)
+    pc += mips32_relative_offset (inst);
+  else if (taken == 0)
+    pc += 4;
+
+  return pc;
+}
+
 /* Return nonzero if the gdbarch is an Octeon series.  */
 
 static int
@@ -2567,6 +2661,14 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
 	       && (itype_rt (inst) & 2) == 0)
 	/* BC1ANY4F, BC1ANY4T: 010001 01010 xxx0x */
 	pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 4);
+      else if (op == 17 && (itype_rs (inst) & 0x18) == 0x18)
+	/* BZ.df:  010001 110xx */
+	/* BNZ.df: 010001 111xx */
+	pc = mips32_bc1_w_pc (gdbarch, frame, inst, pc + 4);
+      else if (op == 17 && (itype_rs (inst) & 0x1b) == 0x0b)
+	/* BZ.V:   010001 01011 */
+	/* BNZ.V:  010001 01111 */
+	pc = mips32_bc1_w_pc (gdbarch, frame, inst, pc + 4);
       else if (op == 29)
 	/* JALX: 011101 */
 	/* The new PC will be alternate mode.  */
@@ -2793,6 +2895,30 @@ micromips_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
 }
 
 /* Calculate the address of the next microMIPS instruction to execute
+   after the INSN coprocessor 1 vector conditional branch instruction
+   at the address PC.  */
+
+static CORE_ADDR
+micromips_bc1_w_pc (struct gdbarch *gdbarch, struct frame_info *frame,
+		    ULONGEST insn, CORE_ADDR pc)
+{
+  int op = b5s5_op (insn >> 16);
+  int wt = b0s5_reg (insn >> 16);
+  int taken;
+
+  /* Will the branch be taken? */
+  taken = mips_bc1_w_taken (gdbarch, frame, op, wt);
+
+  /* Calculate branch target */
+  if (taken > 0)
+    pc += micromips_relative_offset16 (insn);
+  else if (taken == 0)
+    pc += micromips_pc_insn_size (gdbarch, pc);
+
+  return pc;
+}
+
+/* Calculate the address of the next microMIPS instruction to execute
    after the instruction at the address PC.  */
 
 static CORE_ADDR
@@ -2914,6 +3040,16 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
 	    }
 	  break;
 
+	case 0x20: /* POOL32D: bits 100000 */
+	  if ((b5s5_op (insn) & 0x18) == 0x18
+			/* BZ.df:  bits 100000 110xx */
+			/* BNZ.df: bits 100000 111xx */
+	      || (b5s5_op (insn) & 0x1b) == 0x0b)
+			/* BZ.V:   bits 100000 01011 */
+			/* BNZ.V:  bits 100000 01111 */
+	      pc = micromips_bc1_w_pc (gdbarch, frame, insn, pc);
+	  break;
+
 	case 0x1d: /* JALS: bits 011101 */
 	case 0x35: /* J: bits 110101 */
 	case 0x3d: /* JAL: bits 111101 */
@@ -4863,9 +4999,16 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
 	  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 */
+	  is_branch = (((itype_rs (insn) == 9 || itype_rs (insn) == 10)
+			&& (itype_rt (insn) & 0x2) == 0)
+				/* BC1ANY2F, BC1ANY2T, BC1ANY4F, BC1ANY4T */
+		       || (itype_rs (insn) & 0x18) == 0x18
+				/* BZ.df:  010001 110xx */
+				/* BNZ.df: 010001 111xx */
+		       || (itype_rs (insn) & 0x1b) == 0x0b);
+				/* BZ.V:   010001 01011 */
+				/* BNZ.V:  010001 01111 */
+	  if (is_branch)
 	    break;
 	/* Fall through.  */
 	case 18: /* COP2 */
@@ -4956,6 +5099,16 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
 	case 2 * MIPS_INSN16_SIZE:
 	  switch (micromips_op (insn))
 	    {
+	    case 0x20: /* POOL32D: bits 100000 */
+	      if ((b5s5_op (insn) & 0x18) != 0x18
+				/* BZ.df:  bits 100000 110xx */
+				/* BNZ.df: bits 100000 111xx */
+		  && (b5s5_op (insn) & 0x1b) != 0x0b)
+				/* BZ.V:   bits 100000 01011 */
+				/* BNZ.V:  bits 100000 01111 */
+		break;
+	      goto handle_branch;
+
 	    case 0x10: /* POOL32I: bits 010000 */
 	      if ((b5s5_op (insn) & 0x18) != 0x0
 				/* BLTZ, BLTZAL, BGEZ, BGEZAL: 010000 000xx */
@@ -4978,6 +5131,7 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
 
 	    case 0x25: /* BEQ: bits 100101 */
 	    case 0x2d: /* BNE: bits 101101 */
+handle_branch:
 	      insn <<= 16;
 	      insn |= mips_fetch_instruction (gdbarch,
 					      ISA_MICROMIPS, loc, NULL);
@@ -8259,8 +8413,14 @@ mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, ULONGEST inst)
 				/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000  */
 		      || (rs == 9 && (rt & 0x2) == 0)
 				/* BC1ANY2F, BC1ANY2T: bits 010001 01001  */
-		      || (rs == 10 && (rt & 0x2) == 0))));
+		      || (rs == 10 && (rt & 0x2) == 0)
 				/* BC1ANY4F, BC1ANY4T: bits 010001 01010  */
+		      || ((rs & 0x18) == 0x18)
+				/* BZ.df:  bits 010001 110xx */
+				/* BNZ.df: bits 010001 111xx */
+		      || ((rs & 0x1b) == 0x0b))));
+				/* BZ.V:   bits 010001 01011 */
+				/* BNZ.V:  bits 010001 01111 */
     }
   else
     switch (op & 0x07)		/* extract bits 28,27,26  */
@@ -8331,6 +8491,13 @@ micromips_instruction_has_delay_slot (ULONGEST insn, int mustbe32)
     case 0x35:			/* J: bits 110101 */
     case 0x2d:			/* BNE: bits 101101 */
     case 0x25:			/* BEQ: bits 100101 */
+    case 0x20:			/* POOL32D: bits 100000 */
+      return ((b5s5_op (major) & 0x18) == 0x18
+				/* BZ.df:  bits 100000 110xx */
+				/* BNZ.df: bits 100000 111xx */
+	      || ((b5s5_op (major) & 0x1b) == 0x0b));
+				/* BZ.V:   bits 100000 01011 */
+				/* BNZ.V:  bits 100000 01111 */
     case 0x1d:			/* JALS: bits 011101 */
       return 1;
     case 0x10:			/* POOL32I: bits 010000 */
-- 
1.9-rc2


  parent reply	other threads:[~2016-06-27 14:51 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-27 14:50 [PATCH 01/24] MIPS: Handle run-time reconfigurable FPR size Bhushan Attarde
2016-06-27 14:50 ` [PATCH 11/24] MIPS: Add support for hybrid fp32/fp64 mode Bhushan Attarde
2016-06-27 14:50 ` [PATCH 06/24] mips-linux-nat: pick fp64 target description when appropriate Bhushan Attarde
2016-06-27 14:50 ` [PATCH 03/24] regcache: handle invalidated regcache Bhushan Attarde
2016-10-21 22:42   ` Maciej W. Rozycki
2016-06-27 14:50 ` [PATCH 08/24] MIPS: Convert FP mode to enum and put fp registers into fp reggroup Bhushan Attarde
2016-06-27 14:50 ` [PATCH 10/24] MIPS: override fscr/fir types and print control registers specially Bhushan Attarde
2016-06-27 14:51 ` Bhushan Attarde [this message]
2016-06-27 14:51 ` [PATCH 22/24] Support all new ABIs when detecting if an FPU is present Bhushan Attarde
2016-06-27 14:51 ` [PATCH 09/24] MIPS: Enhance cooked FP format Bhushan Attarde
2016-06-27 14:51 ` [PATCH 14/24] Implement core MSA stuff Bhushan Attarde
2016-06-27 14:51 ` [PATCH 20/24] Drop FP and MSA control registers from default info registers Bhushan Attarde
2016-06-27 14:51 ` [PATCH 12/24] o32 sigframe unwinding with FR1 Bhushan Attarde
2016-06-27 14:51 ` [PATCH 24/24] MIPS R6 forbidden slot support Bhushan Attarde
2016-06-27 14:51 ` [PATCH 05/24] MIPS: Add config5 to MIPS GDB target descriptions Bhushan Attarde
2016-06-27 14:51 ` [PATCH 21/24] MIPSR6 support for GDB Bhushan Attarde
2016-07-29 21:10   ` Maciej W. Rozycki
2016-06-27 14:51 ` [PATCH 23/24] MIPS R6 opcode table shuffle for LDC2/SDC2 Bhushan Attarde
2016-06-27 14:51 ` [PATCH 13/24] Add MIPS MSA GDB target descriptions Bhushan Attarde
2016-06-27 14:51 ` [PATCH 07/24] MIPS: Make Linux restart register more dynamic Bhushan Attarde
2016-06-27 14:51 ` [PATCH 04/24] Add MIPS Config5 register related support Bhushan Attarde
2016-06-27 14:51 ` [PATCH 02/24] Add MIPS32 FPU64 GDB target descriptions Bhushan Attarde
2016-10-12 12:42   ` Maciej W. Rozycki
2016-10-12 13:58     ` James Hogan
2016-10-12 16:30       ` Maciej W. Rozycki
2016-10-12 18:05         ` James Hogan
2016-10-12 22:04           ` Maciej W. Rozycki
2016-10-13 10:09             ` Matthew Fortune
2016-10-21 19:17               ` Maciej W. Rozycki
2016-10-21 19:24                 ` Maciej W. Rozycki
2016-06-27 14:51 ` [PATCH 18/24] mips-linux-nat: get msa registers Bhushan Attarde
2016-07-25 14:03 ` [PATCH 01/24] MIPS: Handle run-time reconfigurable FPR size Maciej W. Rozycki
2016-10-18 17:37   ` Maciej W. Rozycki
2016-11-08 19:46 ` Yao Qi
2016-11-10 12:43   ` Maciej W. Rozycki
2016-11-11 12:29     ` Yao Qi
2016-12-02  2:31       ` Maciej W. Rozycki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1467038991-6600-19-git-send-email-bhushan.attarde@imgtec.com \
    --to=bhushan.attarde@imgtec.com \
    --cc=Andrew.Bennett@imgtec.com \
    --cc=James.Hogan@imgtec.com \
    --cc=Jaydeep.Patil@imgtec.com \
    --cc=Maciej.Rozycki@imgtec.com \
    --cc=Matthew.Fortune@imgtec.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox