This is the mail archive of the binutils@sources.redhat.com 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] Re: ia64: @ not allowed to start symbol?


>>> James E Wilson <wilson@specifixinc.com> 31.01.05 21:48:40 >>>
>On Mon, 2005-01-31 at 09:06, Jan Beulich wrote:
>> Is it intentional that one cannot have a symbol starting with @ in
IA64
>> assembly sources? While these may conflict with current or future
pseudo
>> operands, ias permits them.
>
>An oversight.  Gas probably hasn't ever been rigorously checked
against
>post-release Intel Assembly Language manuals.
>
>I see the IAS manual allows any of the special characters "._$@?" to
be
>the first character of a symbol.  "." and "_" are common in unix. 
"$"
>appears in VMS and old K&R C code.  The "@" and "?" have me puzzled
>though.  I don't know why anyone would want or need them as the first
>character of an identifier, though I see that the netware,
>interix, and PE targets allow one or both of them, so it must be a
>Windows convention.
>
>Gas gets both the @ and ? cases wrong, and should be fixed if we want
to
>conform to IAS, or if someone needs them.  We get the other cases
right.

Built and tested on ia64-unknown-linux-gnu.

Jan

gas/
2005-02-08  Jan Beulich  <jbeulich@novell.com>

	* config/tc-ia64.h (LEX_AT): Include LEX_BEGIN_NAME.
	(LEX_QM): Likewise.
	(ia64_parse_name): New third parameter.
	(md_parse_name): Pass third argument.

	* config/tc-ia64.c (pseudo_func): Placeholders use NULL as
name.
	(md_operand): Handling of '@'-prefixed symbols moved from
here...
	(ia64_parse_name): ...to here.

---
/home/jbeulich/src/binutils/mainline/2005-02-08/gas/config/tc-ia64.c	2005-02-02
08:33:18.000000000 +0100
+++ 2005-02-08/gas/config/tc-ia64.c	2005-02-08 17:17:06.885330139
+0100
@@ -514,10 +514,10 @@ pseudo_func[] =
     { "segrel",	PSEUDO_FUNC_RELOC, { 0 } },
     { "tprel",	PSEUDO_FUNC_RELOC, { 0 } },
     { "ltv",	PSEUDO_FUNC_RELOC, { 0 } },
-    { "", 0, { 0 } },	/* placeholder for FUNC_LT_FPTR_RELATIVE */
-    { "", 0, { 0 } },	/* placeholder for FUNC_LT_DTP_MODULE */
-    { "", 0, { 0 } },	/* placeholder for FUNC_LT_DTP_RELATIVE */
-    { "", 0, { 0 } },	/* placeholder for FUNC_LT_TP_RELATIVE */
+    { NULL, 0, { 0 } },	/* placeholder for FUNC_LT_FPTR_RELATIVE
*/
+    { NULL, 0, { 0 } },	/* placeholder for FUNC_LT_DTP_MODULE
*/
+    { NULL, 0, { 0 } },	/* placeholder for FUNC_LT_DTP_RELATIVE
*/
+    { NULL, 0, { 0 } },	/* placeholder for FUNC_LT_TP_RELATIVE
*/
     { "iplt",	PSEUDO_FUNC_RELOC, { 0 } },
 
     /* mbtype4 constants:  */
@@ -7580,16 +7580,101 @@ ia64_optimize_expr (l, op, r)
 }
 
 int
-ia64_parse_name (name, e)
+ia64_parse_name (name, e, pc)
      char *name;
      expressionS *e;
+     char *pc;
 {
   struct const_desc *cdesc;
   struct dynreg *dr = 0;
   unsigned int regnum;
+  unsigned int idx;
   struct symbol *sym;
   char *end;
 
+  if (*name == '@')
+    {
+      enum pseudo_type pseudo_type = PSEUDO_FUNC_NONE;
+
+      /* Find what relocation pseudo-function we're dealing with.  */
+      for (idx = 0; idx < NELEMS (pseudo_func); ++idx)
+	if (pseudo_func[idx].name
+	    && pseudo_func[idx].name[0] == name[1]
+	    && strcmp (pseudo_func[idx].name + 1, name + 2) == 0)
+	  {
+	    pseudo_type = pseudo_func[idx].type;
+	    break;
+	  }
+      switch (pseudo_type)
+	{
+	case PSEUDO_FUNC_RELOC:
+	  end = input_line_pointer;
+	  if (*pc != '(')
+	    {
+	      as_bad ("Expected '('");
+	      goto done;
+	    }
+	  /* Skip '('.  */
+	  ++input_line_pointer;
+	  expression (e);
+	  if (*input_line_pointer != ')')
+	    {
+	      as_bad ("Missing ')'");
+	      goto done;
+	    }
+	  /* Skip ')'.  */
+	  ++input_line_pointer;
+	  if (e->X_op != O_symbol)
+	    {
+	      if (e->X_op != O_pseudo_fixup)
+		{
+		  as_bad ("Not a symbolic expression");
+		  goto done;
+		}
+	      if (idx != FUNC_LT_RELATIVE)
+		{
+		  as_bad ("Illegal combination of relocation
functions");
+		  goto done;
+		}
+	      switch (S_GET_VALUE (e->X_op_symbol))
+		{
+		case FUNC_FPTR_RELATIVE:
+		  idx = FUNC_LT_FPTR_RELATIVE; break;
+		case FUNC_DTP_MODULE:
+		  idx = FUNC_LT_DTP_MODULE; break;
+		case FUNC_DTP_RELATIVE:
+		  idx = FUNC_LT_DTP_RELATIVE; break;
+		case FUNC_TP_RELATIVE:
+		  idx = FUNC_LT_TP_RELATIVE; break;
+		default:
+		  as_bad ("Illegal combination of relocation
functions");
+		  goto done;
+		}
+	    }
+	  /* Make sure gas doesn't get rid of local symbols that are
used
+	     in relocs.  */
+	  e->X_op = O_pseudo_fixup;
+	  e->X_op_symbol = pseudo_func[idx].u.sym;
+	  break;
+
+	case PSEUDO_FUNC_CONST:
+	  e->X_op = O_constant;
+	  e->X_add_number = pseudo_func[idx].u.ival;
+	  break;
+
+	case PSEUDO_FUNC_REG:
+	  e->X_op = O_register;
+	  e->X_add_number = pseudo_func[idx].u.ival;
+	  break;
+
+	default:
+	  return 0;
+	}
+    done:
+      *pc = *input_line_pointer;
+      return 1;
+    }
+
   /* first see if NAME is a known register name:  */
   sym = hash_find (md.reg_hash, name);
   if (sym)
@@ -10415,104 +10500,14 @@ void
 md_operand (e)
      expressionS *e;
 {
-  enum pseudo_type pseudo_type;
-  const char *name;
-  size_t len;
-  int ch, i;
-
   switch (*input_line_pointer)
     {
-    case '@':
-      /* Find what relocation pseudo-function we're dealing with.  */
-      pseudo_type = 0;
-      ch = *++input_line_pointer;
-      for (i = 0; i < NELEMS (pseudo_func); ++i)
-	if (pseudo_func[i].name && pseudo_func[i].name[0] == ch)
-	  {
-	    len = strlen (pseudo_func[i].name);
-	    if (strncmp (pseudo_func[i].name + 1,
-			 input_line_pointer + 1, len - 1) == 0
-		&& !is_part_of_name (input_line_pointer[len]))
-	      {
-		input_line_pointer += len;
-		pseudo_type = pseudo_func[i].type;
-		break;
-	      }
-	  }
-      switch (pseudo_type)
-	{
-	case PSEUDO_FUNC_RELOC:
-	  SKIP_WHITESPACE ();
-	  if (*input_line_pointer != '(')
-	    {
-	      as_bad ("Expected '('");
-	      goto err;
-	    }
-	  /* Skip '('.  */
-	  ++input_line_pointer;
-	  expression (e);
-	  if (*input_line_pointer++ != ')')
-	    {
-	      as_bad ("Missing ')'");
-	      goto err;
-	    }
-	  if (e->X_op != O_symbol)
-	    {
-	      if (e->X_op != O_pseudo_fixup)
-		{
-		  as_bad ("Not a symbolic expression");
-		  goto err;
-		}
-	      if (i != FUNC_LT_RELATIVE)
-		{
-		  as_bad ("Illegal combination of relocation
functions");
-		  goto err;
-		}
-	      switch (S_GET_VALUE (e->X_op_symbol))
-		{
-		case FUNC_FPTR_RELATIVE:
-		  i = FUNC_LT_FPTR_RELATIVE; break;
-		case FUNC_DTP_MODULE:
-		  i = FUNC_LT_DTP_MODULE; break;
-		case FUNC_DTP_RELATIVE:
-		  i = FUNC_LT_DTP_RELATIVE; break;
-		case FUNC_TP_RELATIVE:
-		  i = FUNC_LT_TP_RELATIVE; break;
-		default:
-		  as_bad ("Illegal combination of relocation
functions");
-		  goto err;
-		}
-	    }
-	  /* Make sure gas doesn't get rid of local symbols that are
used
-	     in relocs.  */
-	  e->X_op = O_pseudo_fixup;
-	  e->X_op_symbol = pseudo_func[i].u.sym;
-	  break;
-
-	case PSEUDO_FUNC_CONST:
-	  e->X_op = O_constant;
-	  e->X_add_number = pseudo_func[i].u.ival;
-	  break;
-
-	case PSEUDO_FUNC_REG:
-	  e->X_op = O_register;
-	  e->X_add_number = pseudo_func[i].u.ival;
-	  break;
-
-	default:
-	  name = input_line_pointer - 1;
-	  get_symbol_end ();
-	  as_bad ("Unknown pseudo function `%s'", name);
-	  goto err;
-	}
-      break;
-
     case '[':
       ++input_line_pointer;
       expression (e);
       if (*input_line_pointer != ']')
 	{
-	  as_bad ("Closing bracket misssing");
+	  as_bad ("Closing bracket missing");
 	  goto err;
 	}
       else
---
/home/jbeulich/src/binutils/mainline/2005-02-08/gas/config/tc-ia64.h	2004-07-22
11:48:34.000000000 +0200
+++ 2005-02-08/gas/config/tc-ia64.h	2005-02-08 17:18:42.795485214
+0100
@@ -74,8 +74,8 @@ extern const char *ia64_target_format PA
 #define NEED_INDEX_OPERATOR		/* [ ] is index operator */
 
 #define QUOTES_IN_INSN			/* allow `string
"foo;bar"' */
-#define LEX_AT		LEX_NAME	/* allow `@' inside name
*/
-#define LEX_QM		LEX_NAME	/* allow `?' inside name
*/
+#define LEX_AT		(LEX_NAME|LEX_BEGIN_NAME) /* allow `@'
inside name */
+#define LEX_QM		(LEX_NAME|LEX_BEGIN_NAME) /* allow `?'
inside name */
 #define LEX_HASH	LEX_END_NAME	/* allow `#' ending a name */
 
 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
@@ -94,7 +94,7 @@ extern void ia64_frob_label PARAMS((stru
 extern int ia64_frob_symbol PARAMS((struct symbol *sym));
 #endif
 extern void ia64_flush_pending_output PARAMS((void));
-extern int ia64_parse_name (char *name, expressionS *e);
+extern int ia64_parse_name PARAMS((char *name, expressionS *e, char
*pc));
 extern int ia64_optimize_expr PARAMS((expressionS *l, operatorT op,
 				      expressionS *r));
 extern void ia64_cons_align PARAMS((int));
@@ -125,7 +125,7 @@ extern void ia64_convert_frag (fragS *);
 #define tc_frob_symbol(s,p)		p |= ia64_frob_symbol (s)
 #endif /* TE_HPUX */
 #define md_flush_pending_output()	ia64_flush_pending_output ()
-#define md_parse_name(s,e,c)		ia64_parse_name (s, e)
+#define md_parse_name(s,e,c)		ia64_parse_name (s, e, c)
 #define
tc_canonicalize_symbol_name(s)	ia64_canonicalize_symbol_name
(s)
 #define
tc_canonicalize_section_name(s)	ia64_canonicalize_symbol_name
(s)
 #define md_optimize_expr(l,o,r)		ia64_optimize_expr (l,
o, r)

Attachment: binutils-mainline-ia64-lex-at-qm.patch
Description: Text document


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