public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Support %higher and %highest in MIPS gas
@ 2001-08-15 14:40 Thiemo Seufer
  2001-08-16  9:25 ` Eric Christopher
  0 siblings, 1 reply; 8+ messages in thread
From: Thiemo Seufer @ 2001-08-15 14:40 UTC (permalink / raw)
  To: binutils

Hi All,

This patch adds support for %higher and %highest to MIPS gas
and makes parsing of all %* more reliable.


Thiemo


2001-08-16  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>


	/gas/ChangeLog
	* config/tc-mips.c (S_EX_*): New enum for my_getSmallExpression()
	return values.
	(mips_ip): Use the new return values instead of characters. Add
	support for %higher and %highest.
	(LP): Remove.
	(RP): Remove.
	(my_getSmallExpression): Make parsing case insensitive and more
	reliable. Add support for %higher and %highest. Further support	to
	parse %gprel and %neg is implemented but currently deactivated.


diff -BurpNX /bigdisk/src/binutils-exclude src-orig/gas/config/tc-mips.c src/gas/config/tc-mips.c
--- src-orig/gas/config/tc-mips.c	Sun Aug 12 13:34:58 2001
+++ src/gas/config/tc-mips.c	Thu Aug 16 02:23:17 2001
@@ -728,6 +734,19 @@ static const char *mips_isa_to_str PARAM
 static const char *mips_cpu_to_str PARAMS ((int));
 static int validate_mips_insn PARAMS ((const struct mips_opcode *));
 
+/* Return values of my_getSmallExpression() */
+
+enum
+{
+  S_EX_NONE = 0,
+  S_EX_LO,
+  S_EX_HI,
+  S_EX_HIGHER,
+  S_EX_HIGHEST,
+  S_EX_GPREL,
+  S_EX_NEG
+};
+
 /* Table and functions used to map between CPU/ISA names, and
    ISA levels, and CPU numbers.  */
 
@@ -7655,14 +7893,18 @@ mips_ip (str, ip)
 	    case 'j':		/* 16 bit signed immediate */
 	      imm_reloc = BFD_RELOC_LO16;
 	      c = my_getSmallExpression (&imm_expr, s);
-	      if (c != '\0')
+	      if (c != S_EX_NONE)
 		{
-		  if (c != 'l')
+		  if (c != S_EX_LO)
 		    {
 		      if (imm_expr.X_op == O_constant)
 			imm_expr.X_add_number =
 			  (imm_expr.X_add_number >> 16) & 0xffff;
-		      else if (c == 'h')
+		      else if (c == S_EX_HIGHEST)
+			  imm_reloc = BFD_RELOC_MIPS_HIGHEST;
+		      else if (c == S_EX_HIGHER)
+			  imm_reloc = BFD_RELOC_MIPS_HIGHER;
+		      else if (c == S_EX_HI)
 			{
 			  imm_reloc = BFD_RELOC_HI16_S;
 			  imm_unmatched_hi = true;
@@ -7675,7 +7917,7 @@ mips_ip (str, ip)
 		}
 	      if (*args == 'i')
 		{
-		  if ((c == '\0' && imm_expr.X_op != O_constant)
+		  if ((c == S_EX_NONE && imm_expr.X_op != O_constant)
 		      || ((imm_expr.X_add_number < 0
 			   || imm_expr.X_add_number >= 0x10000)
 			  && imm_expr.X_op == O_constant))
@@ -7708,7 +7950,7 @@ mips_ip (str, ip)
 		    max = 0x8000;
 		  else
 		    max = 0x10000;
-		  if ((c == '\0' && imm_expr.X_op != O_constant)
+		  if ((c == S_EX_NONE && imm_expr.X_op != O_constant)
 		      || ((imm_expr.X_add_number < -0x8000
 			   || imm_expr.X_add_number >= max)
 			  && imm_expr.X_op == O_constant)
@@ -7742,7 +7984,7 @@ mips_ip (str, ip)
 		 fashion is that the macro function doesn't expect to
 		 see anything which can be handled in a single
 		 constant instruction.  */
-	      if (c == 0
+	      if (c == S_EX_NONE
 		  && (offset_expr.X_op != O_constant
 		      || offset_expr.X_add_number >= 0x8000
 		      || offset_expr.X_add_number < -0x8000)
@@ -7752,7 +7994,7 @@ mips_ip (str, ip)
 			  != S_GET_SEGMENT (offset_expr.X_op_symbol))))
 		break;
 
-	      if (c == 'h' || c == 'H')
+	      if (c == S_EX_HI)
 		{
 		  if (offset_expr.X_op != O_constant)
 		    break;
@@ -7774,12 +8016,14 @@ mips_ip (str, ip)
 	      imm_reloc = BFD_RELOC_LO16;
 	      if (c)
 		{
-		  if (c != 'l')
+		  if (c != S_EX_LO)
 		    {
 		      if (imm_expr.X_op == O_constant)
 			imm_expr.X_add_number =
 			  (imm_expr.X_add_number >> 16) & 0xffff;
-		      else if (c == 'h')
+		      else if (c == S_EX_HIGHEST)
+			  imm_reloc = BFD_RELOC_MIPS_HIGHEST;
+		      else if (c == S_EX_HI)
 			{
 			  imm_reloc = BFD_RELOC_HI16_S;
 			  imm_unmatched_hi = true;
@@ -8581,8 +8825,6 @@ mips16_immed (file, line, type, val, war
     }
 }
 \f
-#define LP '('
-#define RP ')'
 
 static int
 my_getSmallExpression (ep, str)
@@ -8590,85 +8832,144 @@ my_getSmallExpression (ep, str)
      char *str;
 {
   char *sp;
-  int c = 0;
+  char *oldstr = str;
+  int c = S_EX_NONE;
 
   if (*str == ' ')
     str++;
-  if (*str == LP
-      || (*str == '%' &&
-	  ((str[1] == 'h' && str[2] == 'i')
-	   || (str[1] == 'H' && str[2] == 'I')
-	   || (str[1] == 'l' && str[2] == 'o'))
-	  && str[3] == LP))
+  if (*str == '(')
+    c = S_EX_NONE;
+  else if (str[0] == '%'
+	   && tolower(str[1]) == 'l'
+	   && tolower(str[2]) == 'o'
+	   && str[3] == '(')
+    {
+      c = S_EX_LO;
+      str += sizeof ("%lo(") - 2;
+    }
+  else if (str[0] == '%'
+	   && tolower(str[1]) == 'h'
+	   && tolower(str[2]) == 'i'
+	   && str[3] == '(')
+    {
+      c = S_EX_HI;
+      str += sizeof ("%hi(") - 2;
+    }
+  else if (str[0] == '%'
+	   && tolower(str[1]) == 'h'
+	   && tolower(str[2]) == 'i'
+	   && tolower(str[3]) == 'g'
+	   && tolower(str[4]) == 'h'
+	   && tolower(str[5]) == 'e'
+	   && tolower(str[6]) == 'r'
+	   && str[7] == '(')
+    {
+      c = S_EX_HIGHER;
+      str += sizeof ("%higher(") - 2;
+    }
+  else if (str[0] == '%'
+	   && tolower(str[1]) == 'h'
+	   && tolower(str[2]) == 'i'
+	   && tolower(str[3]) == 'g'
+	   && tolower(str[4]) == 'h'
+	   && tolower(str[5]) == 'e'
+	   && tolower(str[6]) == 's'
+	   && tolower(str[7]) == 't'
+	   && str[8] == '(')
     {
-      if (*str == LP)
-	c = 0;
-      else
+      c = S_EX_HIGHEST;
+      str += sizeof ("%highest(") - 2;
+    }
+/* currently unsupported */
+#if 0
+  else if (str[0] == '%'
+	   && tolower(str[1]) == 'g'
+	   && tolower(str[2]) == 'p'
+	   && tolower(str[3]) == 'r'
+	   && tolower(str[4]) == 'e'
+	   && tolower(str[5]) == 'l'
+	   && str[6] == '(')
+    {
+      c = S_EX_GPREL;
+      str += sizeof ("%gprel(") - 2;
+    }
+  else if (str[0] == '%'
+	   && tolower(str[1]) == 'n'
+	   && tolower(str[2]) == 'e'
+	   && tolower(str[3]) == 'g'
+	   && str[4] == '(')
+    {
+      c = S_EX_NEG;
+      str += sizeof ("%neg(") - 2;
+    }
+#endif
+  else
+    {
+      my_getExpression (ep, str);
+      return c;
+    }
+
+  /*
+   * A small expression may be followed by a base register.
+   * Scan to the end of this operand, and then back over a possible
+   * base register.  Then scan the small expression up to that
+   * point.  (Based on code in sparc.c...)
+   */
+  for (sp = str; *sp && *sp != ','; sp++)
+    ;
+  if (sp - 4 >= str && sp[-1] == ')')
+    {
+      if (isdigit ((unsigned char) sp[-2]))
 	{
-	  c = str[1];
-	  str += 3;
+	  for (sp -= 3; sp >= str && isdigit ((unsigned char) *sp); sp--)
+	    ;
+	  if (*sp == '$' && sp > str && sp[-1] == '(')
+	    {
+	      sp--;
+	      goto do_it;
+	    }
 	}
-
-      /*
-       * A small expression may be followed by a base register.
-       * Scan to the end of this operand, and then back over a possible
-       * base register.  Then scan the small expression up to that
-       * point.  (Based on code in sparc.c...)
-       */
-      for (sp = str; *sp && *sp != ','; sp++)
-	;
-      if (sp - 4 >= str && sp[-1] == RP)
-	{
-	  if (isdigit ((unsigned char) sp[-2]))
-	    {
-	      for (sp -= 3; sp >= str && isdigit ((unsigned char) *sp); sp--)
-		;
-	      if (*sp == '$' && sp > str && sp[-1] == LP)
-		{
-		  sp--;
-		  goto do_it;
-		}
-	    }
-	  else if (sp - 5 >= str
-		   && sp[-5] == LP
-		   && sp[-4] == '$'
-		   && ((sp[-3] == 'f' && sp[-2] == 'p')
-		       || (sp[-3] == 's' && sp[-2] == 'p')
-		       || (sp[-3] == 'g' && sp[-2] == 'p')
-		       || (sp[-3] == 'a' && sp[-2] == 't')))
-	    {
-	      sp -= 5;
-	    do_it:
-	      if (sp == str)
+      else if (sp - 5 >= str
+	       && sp[-5] == '('
+	       && sp[-4] == '$'
+	       && ((sp[-3] == 'f' && sp[-2] == 'p')
+		   || (sp[-3] == 's' && sp[-2] == 'p')
+		   || (sp[-3] == 'g' && sp[-2] == 'p')
+		   || (sp[-3] == 'a' && sp[-2] == 't')))
+	{
+	  sp -= 5;
+	do_it:
+	  if (sp == str)
+	    {
+	      /* no expression means zero offset */
+	      if (c != S_EX_NONE)
 		{
-		  /* no expression means zero offset */
-		  if (c)
-		    {
-		      /* %xx(reg) is an error */
-		      ep->X_op = O_absent;
-		      expr_end = str - 3;
-		    }
-		  else
-		    {
-		      ep->X_op = O_constant;
-		      expr_end = sp;
-		    }
-		  ep->X_add_symbol = NULL;
-		  ep->X_op_symbol = NULL;
-		  ep->X_add_number = 0;
+		  /* %xx(reg) is an error */
+		  ep->X_op = O_absent;
+		  expr_end = oldstr;
 		}
 	      else
 		{
-		  *sp = '\0';
-		  my_getExpression (ep, str);
-		  *sp = LP;
+		  ep->X_op = O_constant;
+		  expr_end = sp;
 		}
-	      return c;
+	      ep->X_add_symbol = NULL;
+	      ep->X_op_symbol = NULL;
+	      ep->X_add_number = 0;
+	    }
+	  else
+	    {
+	      *sp = '\0';
+	      my_getExpression (ep, str);
+	      *sp = '(';
 	    }
+	  return c;
 	}
     }
   my_getExpression (ep, str);
-  return c;			/* => %hi or %lo encountered */
+
+  /* => %highest, %higher, %hi, %lo, %gprel, %neg encountered */
+  return c;
 }
 
 static void

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support %higher and %highest in MIPS gas
  2001-08-15 14:40 [PATCH] Support %higher and %highest in MIPS gas Thiemo Seufer
@ 2001-08-16  9:25 ` Eric Christopher
  2001-08-16 10:08   ` Thiemo Seufer
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Christopher @ 2001-08-16  9:25 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

> 2001-08-16  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
> 
> 
> 	/gas/ChangeLog
> 	* config/tc-mips.c (S_EX_*): New enum for my_getSmallExpression()
> 	return values.
> 	(mips_ip): Use the new return values instead of characters. Add
> 	support for %higher and %highest.
> 	(LP): Remove.
> 	(RP): Remove.
> 	(my_getSmallExpression): Make parsing case insensitive and more
> 	reliable. Add support for %higher and %highest. Further support	to
> 	parse %gprel and %neg is implemented but currently deactivated.
> 
> 

New testcases for new functionality?

-eric

-- 
Look out behind you!

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support %higher and %highest in MIPS gas
  2001-08-16  9:25 ` Eric Christopher
@ 2001-08-16 10:08   ` Thiemo Seufer
  2001-08-16 10:19     ` Eric Christopher
  0 siblings, 1 reply; 8+ messages in thread
From: Thiemo Seufer @ 2001-08-16 10:08 UTC (permalink / raw)
  To: binutils

Eric Christopher wrote:
> 
> > 2001-08-16  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
> > 
> > 
> > 	/gas/ChangeLog
> > 	* config/tc-mips.c (S_EX_*): New enum for my_getSmallExpression()
> > 	return values.
> > 	(mips_ip): Use the new return values instead of characters. Add
> > 	support for %higher and %highest.
> > 	(LP): Remove.
> > 	(RP): Remove.
> > 	(my_getSmallExpression): Make parsing case insensitive and more
> > 	reliable. Add support for %higher and %highest. Further support	to
> > 	parse %gprel and %neg is implemented but currently deactivated.
> > 
> > 
> 
> New testcases for new functionality?

Currently not, because this patch lets gas parse %higher and %highest,
but actually using this requires handling of R_MIPS_HIGHER and
R_MIPS_HIGHEST relocations which is not available in gas yet.
On the other hand, the easiest way to test these relocations is via
%higher and %highest.
On the third hand, too large patches are a bad thing.

I plan to add testcases together with the relocation support.


Thiemo

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support %higher and %highest in MIPS gas
  2001-08-16 10:08   ` Thiemo Seufer
@ 2001-08-16 10:19     ` Eric Christopher
  2001-08-16 10:28       ` Thiemo Seufer
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Christopher @ 2001-08-16 10:19 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

> 
> Currently not, because this patch lets gas parse %higher and %highest,
> but actually using this requires handling of R_MIPS_HIGHER and
> R_MIPS_HIGHEST relocations which is not available in gas yet.
> On the other hand, the easiest way to test these relocations is via
> %higher and %highest.
> On the third hand, too large patches are a bad thing.
> 
> I plan to add testcases together with the relocation support.
> 

Ok.  Why don't you just do all of this together then?

-eric

-- 
Look out behind you!

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support %higher and %highest in MIPS gas
  2001-08-16 10:19     ` Eric Christopher
@ 2001-08-16 10:28       ` Thiemo Seufer
  2001-08-16 10:29         ` Eric Christopher
  0 siblings, 1 reply; 8+ messages in thread
From: Thiemo Seufer @ 2001-08-16 10:28 UTC (permalink / raw)
  To: Eric Christopher; +Cc: binutils

Eric Christopher wrote:
> 
> > 
> > Currently not, because this patch lets gas parse %higher and %highest,
> > but actually using this requires handling of R_MIPS_HIGHER and
> > R_MIPS_HIGHEST relocations which is not available in gas yet.
> > On the other hand, the easiest way to test these relocations is via
> > %higher and %highest.
> > On the third hand, too large patches are a bad thing.
> > 
> > I plan to add testcases together with the relocation support.
> > 
> 
> Ok.  Why don't you just do all of this together then?

Because of the "large patch" sentence, which applies also to most
of the other patches I've posted recently. These patches already
were part of a larger one which was regarded as unmanageable.


Thiemo

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support %higher and %highest in MIPS gas
  2001-08-16 10:28       ` Thiemo Seufer
@ 2001-08-16 10:29         ` Eric Christopher
  2001-08-16 10:43           ` Thiemo Seufer
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Christopher @ 2001-08-16 10:29 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

> 
> Because of the "large patch" sentence, which applies also to most
> of the other patches I've posted recently. These patches already
> were part of a larger one which was regarded as unmanageable.
> 

In this case I'd like it to all work. It's fine if the patch is large,
as long as it only does one thing like "support %higher and %highest".

-eric

-- 
Look out behind you!

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support %higher and %highest in MIPS gas
  2001-08-16 10:29         ` Eric Christopher
@ 2001-08-16 10:43           ` Thiemo Seufer
  2001-08-16 10:45             ` Eric Christopher
  0 siblings, 1 reply; 8+ messages in thread
From: Thiemo Seufer @ 2001-08-16 10:43 UTC (permalink / raw)
  To: Eric Christopher; +Cc: binutils

Eric Christopher wrote:
> 
> > 
> > Because of the "large patch" sentence, which applies also to most
> > of the other patches I've posted recently. These patches already
> > were part of a larger one which was regarded as unmanageable.
> > 
> 
> In this case I'd like it to all work. It's fine if the patch is large,
> as long as it only does one thing like "support %higher and %highest".

Such a patch will invariably need to do much more than that, a title
might be "Add support for ABI 64 assembly". It won't have the locality
of the current one.


Thiemo

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support %higher and %highest in MIPS gas
  2001-08-16 10:43           ` Thiemo Seufer
@ 2001-08-16 10:45             ` Eric Christopher
  0 siblings, 0 replies; 8+ messages in thread
From: Eric Christopher @ 2001-08-16 10:45 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

> > In this case I'd like it to all work. It's fine if the patch is large,
> > as long as it only does one thing like "support %higher and %highest".
> 
> Such a patch will invariably need to do much more than that, a title
> might be "Add support for ABI 64 assembly". It won't have the locality
> of the current one.
> 

Guh. If this makes it easier for you then go ahead - if it makes it
easier for me then definitely go ahead ;)

-eric

-- 
Look out behind you!

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2001-08-16 10:45 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-15 14:40 [PATCH] Support %higher and %highest in MIPS gas Thiemo Seufer
2001-08-16  9:25 ` Eric Christopher
2001-08-16 10:08   ` Thiemo Seufer
2001-08-16 10:19     ` Eric Christopher
2001-08-16 10:28       ` Thiemo Seufer
2001-08-16 10:29         ` Eric Christopher
2001-08-16 10:43           ` Thiemo Seufer
2001-08-16 10:45             ` Eric Christopher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).