This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

[PATCH 7/9] MIPS/opcodes: Fix and clean up MIPS16 branch annotation


Hi,

 This is a change that cleans up MIPS16 branch annotation held by opcodes.  
With this change it is possible to classify a relevant instruction as one 
of: an unconditional branch, a conditional branch or a jump to a 
subroutine, based solely on opcode flags and without a need to decode 
operands, similarly to what the case is with standard MIPS code.

 It fixes MIPS16e compact jump additions; previously these instructions 
were not annotated as branches.

 The most likely beneficiary of this change is GDB, although I do not 
remember off the head if this change showed up as a progression anywhere.  
As it is GDB does mistreat MIPS16 branches in some places though.

2010-07-02  Maciej W. Rozycki  <macro@codesourcery.com>

	gas/
	* config/tc-mips.c (nops_for_insn_or_target): Replace
	MIPS16_INSN_BRANCH with MIPS16_INSN_UNCOND_BRANCH and
	MIPS16_INSN_COND_BRANCH.

	include/opcode/
	* mips.h (MIPS16_INSN_UNCOND_BRANCH): New macro.
	(MIPS16_INSN_BRANCH): Rename to...
	(MIPS16_INSN_COND_BRANCH): ... this.

	opcodes/
	* mips-dis.c (print_mips16_insn_arg): Remove branch instruction
	type and delay slot determination.
	(print_insn_mips16): Extend branch instruction type and delay
	slot determination to cover all instructions.
	* mips16-opc.c (BR): Remove macro.
	(UBR, CBR): New macros.
	(mips16_opcodes): Update branch annotation for "b", "beqz",
	"bnez", "bteqz" and "btnez".  Add branch annotation for "jalrc"
	and "jrc".

 OK to commit?

  Maciej

binutils-254623.diff
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.c	2010-06-30 00:31:59.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c	2010-06-30 14:49:48.000000000 +0100
@@ -2730,7 +2730,9 @@
       if (tmp_nops > nops)
 	nops = tmp_nops;
     }
-  else if (mips_opts.mips16 && (insn->insn_mo->pinfo & MIPS16_INSN_BRANCH))
+  else if (mips_opts.mips16
+	   && (insn->insn_mo->pinfo & (MIPS16_INSN_UNCOND_BRANCH
+				       | MIPS16_INSN_COND_BRANCH)))
     {
       tmp_nops = nops_for_sequence (1, hist, insn);
       if (tmp_nops > nops)
Index: binutils-fsf-trunk-quilt/include/opcode/mips.h
===================================================================
--- binutils-fsf-trunk-quilt.orig/include/opcode/mips.h	2010-06-24 22:49:55.000000000 +0100
+++ binutils-fsf-trunk-quilt/include/opcode/mips.h	2010-06-30 14:49:48.000000000 +0100
@@ -1089,8 +1089,10 @@
 #define MIPS16_INSN_READ_PC		    0x00002000
 /* Reads the general purpose register in MIPS16OP_*_REGR32.  */
 #define MIPS16_INSN_READ_GPR_X		    0x00004000
-/* Is a branch insn. */
-#define MIPS16_INSN_BRANCH                  0x00010000
+/* Is an unconditional branch insn. */
+#define MIPS16_INSN_UNCOND_BRANCH	    0x00008000
+/* Is a conditional branch insn. */
+#define MIPS16_INSN_COND_BRANCH		    0x00010000
 
 /* The following flags have the same value for the mips16 opcode
    table:
Index: binutils-fsf-trunk-quilt/opcodes/mips-dis.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/mips-dis.c	2010-06-24 22:50:15.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/mips-dis.c	2010-06-30 14:49:48.000000000 +0100
@@ -1660,7 +1660,6 @@
 	    signedp = 1;
 	    pcrel = 1;
 	    branch = 1;
-	    info->insn_type = dis_condbranch;
 	    break;
 	  case 'q':
 	    nbits = 11;
@@ -1668,7 +1667,6 @@
 	    signedp = 1;
 	    pcrel = 1;
 	    branch = 1;
-	    info->insn_type = dis_branch;
 	    break;
 	  case 'A':
 	    nbits = 8;
@@ -1789,8 +1787,6 @@
       }
       info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
       (*info->print_address_func) (info->target, info);
-      info->insn_type = dis_jsr;
-      info->branch_delay_insns = 1;
       break;
 
     case 'l':
@@ -2082,12 +2078,19 @@
 				     info);
 	    }
 
+	  /* Figure out branch instruction type and delay slot information.  */
 	  if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
+	    info->branch_delay_insns = 1;
+	  if ((op->pinfo & (INSN_UNCOND_BRANCH_DELAY
+			    | MIPS16_INSN_UNCOND_BRANCH)) != 0)
 	    {
-	      info->branch_delay_insns = 1;
-	      if (info->insn_type != dis_jsr)
+	      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
+		info->insn_type = dis_jsr;
+	      else
 		info->insn_type = dis_branch;
 	    }
+	  else if ((op->pinfo & MIPS16_INSN_COND_BRANCH) != 0)
+	    info->insn_type = dis_condbranch;
 
 	  return length;
 	}
Index: binutils-fsf-trunk-quilt/opcodes/mips16-opc.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/opcodes/mips16-opc.c	2010-05-12 22:08:00.000000000 +0100
+++ binutils-fsf-trunk-quilt/opcodes/mips16-opc.c	2010-06-30 14:49:48.000000000 +0100
@@ -33,7 +33,8 @@
    the opcodes table.  */
 
 #define UBD     INSN_UNCOND_BRANCH_DELAY
-#define BR      MIPS16_INSN_BRANCH
+#define UBR	MIPS16_INSN_UNCOND_BRANCH
+#define CBR	MIPS16_INSN_COND_BRANCH
 
 #define WR_x	MIPS16_INSN_WRITE_X
 #define WR_y	MIPS16_INSN_WRITE_Y
@@ -85,10 +86,10 @@
 {"addu",    "x,P,V",	0x0800, 0xf800, WR_x|RD_PC,	0,	I1 },
 {"addu",    "x,S,V",	0x0000, 0xf800, WR_x|RD_SP,	0,	I1 },
 {"and",	    "x,y",	0xe80c, 0xf81f, WR_x|RD_x|RD_y,	0,	I1 },
-{"b",	    "q",	0x1000, 0xf800, BR,		0,	I1 },
+{"b",	    "q",	0x1000, 0xf800, UBR,		0,	I1 },
 {"beq",	    "x,y,p",	0, (int) M_BEQ, INSN_MACRO,	0,	I1 },
 {"beq",     "x,U,p",	0, (int) M_BEQ_I, INSN_MACRO,	0,	I1 },
-{"beqz",    "x,p",	0x2000, 0xf800, BR|RD_x,	0,	I1 },
+{"beqz",    "x,p",	0x2000, 0xf800, CBR|RD_x,	0,	I1 },
 {"bge",	    "x,y,p",	0, (int) M_BGE, INSN_MACRO,	0,	I1 },
 {"bge",     "x,8,p",	0, (int) M_BGE_I, INSN_MACRO,	0,	I1 },
 {"bgeu",    "x,y,p",	0, (int) M_BGEU, INSN_MACRO,	0,	I1 },
@@ -107,10 +108,10 @@
 {"bltu",    "x,8,p",	0, (int) M_BLTU_I, INSN_MACRO,	0,	I1 },
 {"bne",	    "x,y,p",	0, (int) M_BNE, INSN_MACRO,	0,	I1 },
 {"bne",     "x,U,p",	0, (int) M_BNE_I, INSN_MACRO,	0,	I1 },
-{"bnez",    "x,p",	0x2800, 0xf800, BR|RD_x,	0,	I1 },
+{"bnez",    "x,p",	0x2800, 0xf800, CBR|RD_x,	0,	I1 },
 {"break",   "6",	0xe805, 0xf81f, TRAP,		0,	I1 },
-{"bteqz",   "p",	0x6000, 0xff00, BR|RD_T,	0,	I1 },
-{"btnez",   "p",	0x6100, 0xff00, BR|RD_T,	0,	I1 },
+{"bteqz",   "p",	0x6000, 0xff00, CBR|RD_T,	0,	I1 },
+{"btnez",   "p",	0x6100, 0xff00, CBR|RD_T,	0,	I1 },
 {"cmpi",    "x,U",	0x7000, 0xf800, WR_T|RD_x,	0,	I1 },
 {"cmp",	    "x,y",	0xe80a, 0xf81f, WR_T|RD_x|RD_y,	0,	I1 },
 {"cmp",     "x,U",	0x7000, 0xf800, WR_T|RD_x,	0,	I1 },
@@ -226,10 +227,10 @@
 {"sw",	    "R,V(S)",	0x6200, 0xff00, RD_31|RD_SP,	0,	I1 },
 {"xor",	    "x,y",	0xe80e, 0xf81f, WR_x|RD_x|RD_y, 0,	I1 },
   /* MIPS16e additions */
-{"jalrc",   "x",	0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0,     I32 },
-{"jalrc",   "R,x",	0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0,     I32 },
-{"jrc",     "x",	0xe880, 0xf8ff, RD_x|TRAP,	0,      I32 },
-{"jrc",     "R",	0xe8a0, 0xffff, RD_31|TRAP,	0,      I32 },
+{"jalrc",   "x",	0xe8c0, 0xf8ff, UBR|WR_31|RD_x|TRAP, 0,     I32 },
+{"jalrc",   "R,x",	0xe8c0, 0xf8ff, UBR|WR_31|RD_x|TRAP, 0,     I32 },
+{"jrc",     "x",	0xe880, 0xf8ff, UBR|RD_x|TRAP,	0,      I32 },
+{"jrc",     "R",	0xe8a0, 0xffff, UBR|RD_31|TRAP,	0,      I32 },
 {"restore", "M",	0x6400, 0xff80, WR_31|RD_SP|WR_SP|TRAP,	0,	I32 },
 {"save",    "m",	0x6480, 0xff80, RD_31|RD_SP|WR_SP|TRAP,	0,	I32 },
 {"sdbbp",   "6",	0xe801, 0xf81f, TRAP,		0,	I32 },


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