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] New ia64 @slotcount pseudo func (3rd try)



There's been alot of comments on this patch and I appreciate everyone's time in making them. I tried to address all the new concerns, except for the use of ',' vs '-' in the expression arguments. IMO is looks fine either way, and the Gcc side of the patch has been approved with '-'. If someone feels strongly about the issue, I can always resubmit the Gcc patch.



2009-11-04  Douglas B Rupp  <rupp@gnat.com>

	* gas/config/tc-ia64.c (PSEUDO_FUNC_EXPR): New pseudo_func type. 
	(@slotcount): New pseudo func of type EXPR.
	(ia64_parse_name): Implement @slotcount.

--- gas/config/tc-ia64.c	2009-10-06 22:13:53.000000000 -0700
+++ gas/config/tc-ia64.c	2009-11-04 11:19:52.286974547 -0800
@@ -545,7 +545,8 @@ static struct
 	PSEUDO_FUNC_RELOC,
 	PSEUDO_FUNC_CONST,
 	PSEUDO_FUNC_REG,
-	PSEUDO_FUNC_FLOAT
+	PSEUDO_FUNC_FLOAT,
+	PSEUDO_FUNC_EXPR
       }
     type;
     union
@@ -576,6 +577,11 @@ pseudo_func[] =
     { NULL, 0, { 0 } },	/* placeholder for FUNC_LT_TP_RELATIVE */
     { "iplt",	PSEUDO_FUNC_RELOC, { 0 } },
 
+#ifdef TE_VMS
+    /* expression pseudo functions:  */
+    { "slotcount", PSEUDO_FUNC_EXPR, { 0 } },
+#endif
+
     /* mbtype4 constants:  */
     { "alt",	PSEUDO_FUNC_CONST, { 0xa } },
     { "brcst",	PSEUDO_FUNC_CONST, { 0x0 } },
@@ -7779,6 +7785,93 @@ ia64_parse_name (char *name, expressionS
 	  *nextcharP = *input_line_pointer;
 	  break;
 
+#ifdef TE_VMS
+	case PSEUDO_FUNC_EXPR:
+	  if (*nextcharP != '(')
+	    {
+	      as_bad (_("Expected '('"));
+	      break;
+	    }
+	  /* Skip '('.  */
+	  *input_line_pointer++ = '(';
+
+	  /* Whitespace normally has been removed already here let's be
+	     paranoid, e.g. this function could be invoked from inside GDB.  */
+	  SKIP_WHITESPACE ();
+
+	  /* The only expression pseudo func at this time is @slotcount
+	     which takes an expression like (beg-end), where
+	     beg and end are addresses, and figures out how many
+	     Itanium instruction slots separate the addresses.  The value
+	     is needed for a couple of VMS debugger attributes relating to
+	     prologue and epilogue size.  */
+
+	  {
+	    char *name;
+	    char c;
+	    symbolS *symbolPend, *symbolPbeg;
+	    int end, beg, val;
+	    bfd_vma frag_off;
+
+	    name = input_line_pointer;
+	    c = get_symbol_end ();
+	    symbolPend = symbol_find (name);
+	    *input_line_pointer = c;
+
+	    SKIP_WHITESPACE ();
+	    if (*input_line_pointer++ != '-')
+	    {
+	      c = *--input_line_pointer;
+	      *input_line_pointer = '\0';
+	      as_bad (_("expected \"-\" after \"%s\" found \"%c\""), name, c);
+	      *input_line_pointer++ = c;
+	      *nextcharP = *input_line_pointer;
+	      return 0;
+	    }
+	    SKIP_WHITESPACE ();
+
+	    name = input_line_pointer;
+	    c = get_symbol_end ();
+	    symbolPbeg = symbol_find (name);
+	    *input_line_pointer = c;
+
+	    if (symbolPend == NULL
+	        || symbolPbeg == NULL
+	        || !S_IS_DEFINED (symbolPend)
+	        || !S_IS_DEFINED (symbolPbeg)
+	        || S_GET_SEGMENT (symbolPend) != S_GET_SEGMENT (symbolPbeg)
+	        || !frag_offset_fixed_p (symbol_get_frag (symbolPend),
+				         symbol_get_frag (symbolPbeg),
+				         &frag_off))
+	      {
+        	as_bad ("invalid @slotcount expression");
+	        *nextcharP = *input_line_pointer;
+	        return 0;
+	      }
+
+	    /* Calculate the number of instruction slots between the two
+	       labels. Adjust for frag_off, at this stage of assembly, symbol
+	       values are offsets within their frags.  The two symbols may be
+	       in different frags.  */
+	    end = S_GET_VALUE (symbolPend) - frag_off;
+	    beg = S_GET_VALUE (symbolPbeg);
+
+	    val = (((end & -16) - (beg & -16)) / 16 * 3)
+		  + (end & 15)
+		  - (beg & 15);
+
+	    e->X_op = O_constant;
+	    e->X_add_number = val;
+	  }
+
+	  SKIP_WHITESPACE ();
+	  if (*input_line_pointer != ')')
+	    as_bad (_("Missing ')'"));
+
+	  *nextcharP = *++input_line_pointer;
+	  break;
+#endif
+
 	case PSEUDO_FUNC_CONST:
 	  e->X_op = O_constant;
 	  e->X_add_number = pseudo_func[idx].u.ival;

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