This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: H' hex constants
> Is there a specification for this syntax ?
I asked, there isn't, it's more of a generic functionality that other
assemblers tend to support. OTOH I looked up the syntax for our own
character constants and it also doesn't talk about what happens when
they're adjacent to other symbol characters (like H'5), so we can
claim it's undocumented on our end too ;-)
> What about sequences like:
>
> FGH'1234't
> H'deadbeef't
> '\H'
>
> How are these supposed to be handled ?
Old way:
FGH49234116
H100eadbeef116
72
New way:
FG0x1234116
0xdeadbeef116
72
> > However, the current code will take something like H'1234 and replace
> > the '1 with 0x30 (48), resulting in a symbol called H49234.
>
> You lost me there. Isn't the code supposed to change H'1234 into 0x1234
> ? And if you are replacing the two characters '1 with just one byte -
> 0x30 - shouldn't the resulting string be one byte shorter, ie: H0234 ?
The current code (info gas -> syntax -> constants -> characters ->
chars) indicates that a single quote followed by a character denotes
the ASCII value of that character. The code in the preprocessor
states that it's replaced by a string representation of the numeric
ASCII value of that character. Thus, H'1234 is replaced by H49234 -
"H" "49" "234".
In the obvious use cases it just works:
.byte 'X, 'c, 10, 0
.byte 88, 99, 10, 0
But in unusual cases it doesn't quite do what you expect:
.long entry_'R
.long entry_82
> Presumably this feature would be enabled on a per-target basis, so that
> existing ports which do not need to support the syntax would not be
> affected by the change ?
How about this? It requires the target to enable the code at compile
time, and the user to enable it at runtime. A sample target change
for m32c is included. It's a simple patch (good) that's harmless
unless invoked (also good) and works as expected in the normal use
case (good). It doesn't gracefully handle syntax errors though (bad),
but I suspect it's no worse than the surprise the user gets when they
use H'00 without this patch. Perhaps an additional warning for single
quotes following symbol chars would be useful?
Index: as.h
===================================================================
RCS file: /cvs/src/src/gas/as.h,v
retrieving revision 1.59
diff -p -U3 -r1.59 as.h
--- as.h 17 Oct 2007 16:45:54 -0000 1.59
+++ as.h 15 Jul 2008 02:37:46 -0000
@@ -615,6 +615,10 @@ int generic_force_reloc (struct fix *);
#endif
#include "listing.h"
+#ifdef H_TICK_HEX
+extern int enable_h_tick_hex;
+#endif
+
#ifdef TC_M68K
/* True if we are assembling in m68k MRI mode. */
COMMON int flag_m68k_mri;
Index: app.c
===================================================================
RCS file: /cvs/src/src/gas/app.c,v
retrieving revision 1.46
diff -p -U3 -r1.46 app.c
--- app.c 17 Jun 2008 16:01:28 -0000 1.46
+++ app.c 15 Jul 2008 02:37:46 -0000
@@ -34,6 +34,10 @@
#endif
#endif
+#ifdef H_TICK_HEX
+int enable_h_tick_hex = 0;
+#endif
+
#ifdef TC_M68K
/* Whether we are scrubbing in m68k MRI mode. This is different from
flag_m68k_mri, because the two flags will be affected by the .mri
@@ -78,6 +82,9 @@ static const char symbol_chars[] =
#define LEX_IS_DOUBLEBAR_1ST 13
#endif
#define LEX_IS_PARALLEL_SEPARATOR 14
+#ifdef H_TICK_HEX
+#define LEX_IS_H 15
+#endif
#define IS_SYMBOL_COMPONENT(c) (lex[c] == LEX_IS_SYMBOL_COMPONENT)
#define IS_WHITESPACE(c) (lex[c] == LEX_IS_WHITESPACE)
#define IS_LINE_SEPARATOR(c) (lex[c] == LEX_IS_LINE_SEPARATOR)
@@ -190,6 +197,14 @@ do_scrub_begin (int m68k_mri ATTRIBUTE_U
/* Must do this is we want VLIW instruction with "->" or "<-". */
lex['-'] = LEX_IS_SYMBOL_COMPONENT;
#endif
+
+#ifdef H_TICK_HEX
+ if (enable_h_tick_hex)
+ {
+ lex['h'] = LEX_IS_H;
+ lex['H'] = LEX_IS_H;
+ }
+#endif
}
/* Saved state of the scrubber. */
@@ -1254,6 +1269,26 @@ do_scrub_chars (int (*get) (char *, int)
PUT ('\n');
break;
+ case LEX_IS_H:
+#ifdef H_TICK_HEX
+ /* Look for strings like H'[0-9A-Fa-f] and if found, replace
+ the H' with 0x to make them gas-style hex characters. */
+ if (enable_h_tick_hex)
+ {
+ char quot;
+
+ quot = GET ();
+ if (quot == '\'')
+ {
+ UNGET ('x');
+ ch = '0';
+ }
+ else
+ UNGET (quot);
+ }
+ /* FALL THROUGH */
+#endif
+
case LEX_IS_SYMBOL_COMPONENT:
if (state == 10)
{
Index: config/tc-m32c.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m32c.h,v
retrieving revision 1.5
diff -p -U3 -r1.5 config/tc-m32c.h
--- config/tc-m32c.h 3 Jul 2007 11:01:04 -0000 1.5
+++ config/tc-m32c.h 15 Jul 2008 02:37:46 -0000
@@ -86,3 +86,5 @@ extern long md_pcrel_from_section PARAMS
#define TC_START_LABEL(character, i_l_p) \
((character) != ':' ? 0 : (character = m32c_is_colon_insn (s)) ? 0 : ((character = ':'), 1))
extern char m32c_is_colon_insn PARAMS ((char *));
+
+#define H_TICK_HEX 1
Index: config/tc-m32c.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m32c.c,v
retrieving revision 1.15
diff -p -U3 -r1.15 config/tc-m32c.c
--- config/tc-m32c.c 17 Oct 2007 16:45:55 -0000 1.15
+++ config/tc-m32c.c 15 Jul 2008 02:37:46 -0000
@@ -68,12 +68,14 @@ const char * md_shortopts = M32C_SHORTOP
#define OPTION_CPU_M16C (OPTION_MD_BASE)
#define OPTION_CPU_M32C (OPTION_MD_BASE + 1)
#define OPTION_LINKRELAX (OPTION_MD_BASE + 2)
+#define OPTION_H_TICK_HEX (OPTION_MD_BASE + 3)
struct option md_longopts[] =
{
{ "m16c", no_argument, NULL, OPTION_CPU_M16C },
{ "m32c", no_argument, NULL, OPTION_CPU_M32C },
{ "relax", no_argument, NULL, OPTION_LINKRELAX },
+ { "h-tick-hex", no_argument, NULL, OPTION_H_TICK_HEX },
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);
@@ -125,6 +127,10 @@ md_parse_option (int c, char * arg ATTRI
m32c_relax = 1;
break;
+ case OPTION_H_TICK_HEX:
+ enable_h_tick_hex = 1;
+ break;
+
default:
return 0;
}