This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] New ia64 @slotcount pseudo func (3rd try)
- From: Douglas B Rupp <rupp at gnat dot com>
- To: Nick Clifton <nickc at redhat dot com>, Alan Modra <amodra at bigpond dot net dot au>, Jan Beulich <JBeulich at novell dot com>
- Cc: Richard Henderson <rth at redhat dot com>, binutils at sourceware dot org, Tristan Gingold <gingold at adacore dot com>
- Date: Wed, 04 Nov 2009 11:50:28 -0800
- Subject: [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;