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]

[committed] Add a new operand type for MIPS JALX


Until now we've used the same operand type, "a", for both JAL and JALX.
That made sense for the standard encoding and for MIPS16, but is a bit
more of a stretch for microMIPS, where the two instructions have different
shifts and therefore different ranges.

This patch adds new operand types for JALX.  It also fixes the inverted
logic in the microMIPS code:

		  /* For gdb disassembler, force odd address on jalx.  */
		  if (info->flavour == bfd_target_unknown_flavour
		      && strcmp (op->name, "jalx") == 0)

since in that case the ISA bit should be preserved when the instruction
_isn't_ JALX.  Since this had gone unnoticed for a while, I was wondering
whether GDB still cared, but Maciej confirmed that it does (thanks).

I'll leave fixing the branch ISA bit until the main rewrite patch,
where the test is made in one place.

Again, this looks less ugly after the rewrite...

Applied.

Richard


include/opcode/
	* mips.h: Document "+i".

opcodes/
	* mips-opc.c (mips_builtin_opcodes): Use "+i" rather than "a" for
	"jalx".
	* mips16-opc.c (mips16_opcodes): Likewise.
	* micromips-opc.c (micromips_opcodes): Likewise.
	* mips-dis.c (print_insn_args, print_mips16_insn_arg)
	(print_insn_mips16): Handle "+i".
	(print_insn_micromips): Likewise.  Conditionally preserve the
	ISA bit for "a" but not for "+i".

gas/
	* config/tc-mips.c (validate_mips_insn, validate_micromips_insn):
	(mips_ip, mips16_ip): Handle "+i".

Index: include/opcode/mips.h
===================================================================
--- include/opcode/mips.h	2013-07-01 19:22:52.689357775 +0100
+++ include/opcode/mips.h	2013-07-01 19:29:27.337536933 +0100
@@ -379,6 +379,7 @@ struct mips_opcode
    "<" 5 bit shift amount (OP_*_SHAMT)
    ">" shift amount between 32 and 63, stored after subtracting 32 (OP_*_SHAMT)
    "a" 26 bit target address (OP_*_TARGET)
+   "+i" likewise, but flips bit 0
    "b" 5 bit base register (OP_*_RS)
    "c" 10 bit breakpoint code (OP_*_CODE)
    "d" 5 bit destination register specifier (OP_*_RD)
@@ -539,7 +540,7 @@ struct mips_opcode
    following), for quick reference when adding more:
    "1234"
    "ABCEFGHIJPQSXZ"
-   "abcjpstxz"
+   "abcijpstxz"
 */
 
 /* These are the bits which may be set in the pinfo field of an
@@ -1383,6 +1384,7 @@ #define MIPS16OP_SH_IMM6	5
    "Y" 5 bit MIPS register (MIPS16OP_*_REG32R)
    "6" 6 bit unsigned break code (MIPS16OP_*_IMM6)
    "a" 26 bit jump address
+   "i" likewise, but flips bit 0
    "e" 11 bit extension value
    "l" register list for entry instruction
    "L" register list for exit instruction
@@ -1741,6 +1743,7 @@ #define MICROMIPSOP_MASK_EVAOFFSET	0x1ff
    "|" 4-bit trap code (MICROMIPSOP_*_TRAP)
    "~" 12-bit signed offset (MICROMIPSOP_*_OFFSET12)
    "a" 26-bit target address (MICROMIPSOP_*_TARGET)
+   "+i" likewise, but flips bit 0
    "b" 5-bit base register (MICROMIPSOP_*_RS)
    "c" 10-bit higher breakpoint code (MICROMIPSOP_*_CODE)
    "d" 5-bit destination register specifier (MICROMIPSOP_*_RD)
@@ -1846,10 +1849,10 @@ #define MICROMIPSOP_MASK_EVAOFFSET	0x1ff
 
    Extension character sequences used so far ("+" followed by the
    following), for quick reference when adding more:
-   "j"
    ""
-   "ABCEFGHI"
    ""
+   "ABCEFGHI"
+   "ij"
 
    Extension character sequences used so far ("m" followed by the
    following), for quick reference when adding more:
Index: opcodes/mips-opc.c
===================================================================
--- opcodes/mips-opc.c	2013-07-01 19:17:23.797696361 +0100
+++ opcodes/mips-opc.c	2013-07-01 19:29:27.339536949 +0100
@@ -852,7 +852,7 @@ const struct mips_opcode mips_builtin_op
    assembler, but will never match user input (because the line above
    will match first).  */
 {"jal",     "a",	0x0c000000, 0xfc000000,	UBD|WR_31,		0,		I1	},
-{"jalx",    "a",	0x74000000, 0xfc000000, UBD|WR_31,		0,		I1	},
+{"jalx",    "+i",	0x74000000, 0xfc000000, UBD|WR_31,		0,		I1	},
 {"la",      "t,A(b)",	0,    (int) M_LA_AB,	INSN_MACRO,		0,		I1	},
 {"laa",     "d,(b),t",	0x7000049f, 0xfc0007ff, LDD|SM|WR_d|RD_t|RD_b,	0,		IOCT2	},
 {"laad",    "d,(b),t",	0x700004df, 0xfc0007ff, LDD|SM|WR_d|RD_t|RD_b,	0,		IOCT2	},
Index: opcodes/mips16-opc.c
===================================================================
--- opcodes/mips16-opc.c	2013-07-01 19:17:23.797696361 +0100
+++ opcodes/mips16-opc.c	2013-07-01 19:29:27.340536957 +0100
@@ -167,7 +167,7 @@ const struct mips_opcode mips16_opcodes[
 {"jal",     "x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
 {"jal",     "R,x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
 {"jal",	    "a",	0x1800, 0xfc00, UBD|WR_31,	0,	I1 },
-{"jalx",    "a",	0x1c00, 0xfc00, UBD|WR_31,	0,	I1 },
+{"jalx",    "i",	0x1c00, 0xfc00, UBD|WR_31,	0,	I1 },
 {"jr",	    "x",	0xe800, 0xf8ff, UBD|RD_x,	0,	I1 },
 {"jr",	    "R",	0xe820, 0xffff, UBD|RD_31,	0,	I1 },
 {"j",	    "x",	0xe800, 0xf8ff, UBD|RD_x,	0,	I1 },
Index: opcodes/micromips-opc.c
===================================================================
--- opcodes/micromips-opc.c	2013-07-01 19:22:52.690357783 +0100
+++ opcodes/micromips-opc.c	2013-07-01 19:29:27.338536941 +0100
@@ -587,7 +587,7 @@ const struct mips_opcode micromips_opcod
 {"jals",    "s",	0,    (int) M_JALS_1,	INSN_MACRO,		0,		I1	},
 {"jals",    "a",	0,    (int) M_JALS_A,	INSN_MACRO,		0,		I1	},
 {"jals",    "a",	0x74000000, 0xfc000000,	UBD|WR_31,		BD16,		I1	},
-{"jalx",    "a",	0xf0000000, 0xfc000000,	UBD|WR_31,		BD32,		I1	},
+{"jalx",    "+i",	0xf0000000, 0xfc000000,	UBD|WR_31,		BD32,		I1	},
 {"la",      "t,A(b)",	0,    (int) M_LA_AB,	INSN_MACRO,		0,		I1	},
 {"lb",      "t,o(b)",	0x1c000000, 0xfc000000,	RD_b|WR_t,		0,		I1	},
 {"lb",      "t,A(b)",	0,    (int) M_LB_AB,	INSN_MACRO,		0,		I1	},
Index: opcodes/mips-dis.c
===================================================================
--- opcodes/mips-dis.c	2013-07-01 19:22:52.692357799 +0100
+++ opcodes/mips-dis.c	2013-07-01 19:29:27.347537013 +0100
@@ -1105,6 +1105,15 @@ #define GET_OP_S(insn, field) \
 	      infprintf (is, "%s", mips_fpr_names[GET_OP (l, FZ)]);
 	      break;
 
+	    case 'i': /* JALX destination */
+	      info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
+			      | (GET_OP (l, TARGET) << 2));
+	      /* For gdb disassembler, force odd address on jalx.  */
+	      if (info->flavour == bfd_target_unknown_flavour)
+		info->target |= 1;
+	      (*info->print_address_func) (info->target, info);
+	      break;
+
 	    case 'j':	/* 9-bit signed offset in bit 7.  */
 	      infprintf (is, "%d", GET_OP_S (l, EVAOFFSET));
 	      break;
@@ -1229,10 +1238,6 @@ #define GET_OP_S(insn, field) \
 	case 'a':
 	  info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
 			  | (GET_OP (l, TARGET) << 2));
-	  /* For gdb disassembler, force odd address on jalx.  */
-	  if (info->flavour == bfd_target_unknown_flavour
-	      && strcmp (opp->name, "jalx") == 0)
-	    info->target |= 1;
 	  (*info->print_address_func) (info->target, info);
 	  break;
 
@@ -1874,13 +1879,12 @@ #define GET_OP_S(insn, field) \
       break;
 
     case 'a':
+    case 'i':
       {
-	int jalx = l & 0x400;
-
 	if (! use_extend)
 	  extend = 0;
 	l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
-	if (!jalx && info->flavour == bfd_target_unknown_flavour)
+	if (type == 'a' && info->flavour == bfd_target_unknown_flavour)
 	  /* For gdb disassembler, maintain odd address.  */
 	  l |= 1;
       }
@@ -2147,7 +2151,7 @@ print_insn_mips16 (bfd_vma memaddr, stru
 	{
 	  const char *s;
 
-	  if (strchr (op->args, 'a') != NULL)
+	  if (op->args[0] == 'a' || op->args[0] == 'i')
 	    {
 	      if (use_extend)
 		{
@@ -2422,15 +2426,10 @@ #define GET_OP_S(insn, field) \
 		  break;
 
 		case 'a':
-		  if (strcmp (op->name, "jalx") == 0)
-		    info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff)
-				    | (GET_OP (insn, TARGET) << 2));
-		  else
-		    info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff)
-				    | (GET_OP (insn, TARGET) << 1));
-		  /* For gdb disassembler, force odd address on jalx.  */
-		  if (info->flavour == bfd_target_unknown_flavour
-		      && strcmp (op->name, "jalx") == 0)
+		  info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff)
+				  | (GET_OP (insn, TARGET) << 1));
+		  /* For gdb disassembler, maintain odd address.  */
+		  if (info->flavour == bfd_target_unknown_flavour)
 		    info->target |= 1;
 		  (*info->print_address_func) (info->target, info);
 		  break;
@@ -2658,6 +2657,12 @@ #define GET_OP_S(insn, field) \
 		      infprintf (is, "0x%x", msbd + 1);
 		      break;
 
+		    case 'i':
+		      info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff)
+				      | (GET_OP (insn, TARGET) << 2));
+		      (*info->print_address_func) (info->target, info);
+		      break;
+
 		    case 'j':   /* 9-bit signed offset in bit 0. */
 		      delta = GET_OP_S (insn, EVAOFFSET);
 		      infprintf (is, "%d", delta);
Index: gas/config/tc-mips.c
===================================================================
--- gas/config/tc-mips.c	2013-07-01 19:23:48.448807235 +0100
+++ gas/config/tc-mips.c	2013-07-01 19:29:27.346537005 +0100
@@ -10910,6 +10910,7 @@ #define USE_BITS(mask,shift)	(used_bits
 	  case 'a': USE_BITS (OP_MASK_OFFSET_A,	OP_SH_OFFSET_A); break;
 	  case 'b': USE_BITS (OP_MASK_OFFSET_B,	OP_SH_OFFSET_B); break;
 	  case 'c': USE_BITS (OP_MASK_OFFSET_C,	OP_SH_OFFSET_C); break;
+	  case 'i': USE_BITS (OP_MASK_TARGET,	OP_SH_TARGET);	break;
 	  case 'j': USE_BITS (OP_MASK_EVAOFFSET, OP_SH_EVAOFFSET); break;
 
 	  default:
@@ -11071,6 +11072,7 @@ #define USE_BITS(field) \
 	  case 'F': USE_BITS (INSMSB);	break;
 	  case 'G': USE_BITS (EXTMSBD);	break;
 	  case 'H': USE_BITS (EXTMSBD);	break;
+	  case 'i': USE_BITS (TARGET);	break;
 	  case 'j': USE_BITS (EVAOFFSET);	break;
 	  default:
 	    as_bad (_("Internal error: bad mips opcode "
@@ -12173,6 +12175,9 @@ mips_ip (char *str, struct mips_cl_insn
 		  INSERT_OPERAND (0, FZ, *ip, regno);
 		  continue;
 
+		case 'i':
+		  goto jump;
+
 		case 'j':
 		  {
 		    int shift = 8;
@@ -13031,6 +13036,7 @@ mips_ip (char *str, struct mips_cl_insn
 	      continue;
 
 	    case 'a':		/* 26-bit address.  */
+	    jump:
 	      *offset_reloc = BFD_RELOC_MIPS_JMP;
 	      my_getExpression (&offset_expr, s);
 	      s = expr_end;
@@ -14279,6 +14285,7 @@ mips16_ip (char *str, struct mips_cl_ins
 	      continue;
 
 	    case 'a':		/* 26 bit address */
+	    case 'i':
 	      my_getExpression (&offset_expr, s);
 	      s = expr_end;
 	      *offset_reloc = BFD_RELOC_MIPS16_JMP;


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