From 95008a882803920a0faf672dd4a54edcc6ab66a7 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Wed, 15 May 2019 14:16:33 +0200 Subject: [PATCH] S12Z: New option -mreg-prefix Add a new machine dependent option to set a prefix for register names. gas/ * config/tc-s12z.c (register_prefix): New variable. (md_show_usage, md_parse_option): parse the new option. (lex_reg_name): Scan the prefix if one is set. * doc/c-s12z.texi (S12Z-Opts): Document the new option. * testsuite/gas/s12z/reg-prefix.d: New file. * testsuite/gas/s12z/reg-prefix.s: New file. * testsuite/gas/s12z/s12z.exp: Add them. --- gas/ChangeLog | 10 ++++ gas/config/tc-s12z.c | 49 +++++++++++++--- gas/doc/c-s12z.texi | 86 ++++++++++++++++++++++++++--- gas/testsuite/gas/s12z/reg-prefix.d | 17 ++++++ gas/testsuite/gas/s12z/reg-prefix.s | 6 ++ gas/testsuite/gas/s12z/s12z.exp | 4 ++ 6 files changed, 155 insertions(+), 17 deletions(-) create mode 100644 gas/testsuite/gas/s12z/reg-prefix.d create mode 100644 gas/testsuite/gas/s12z/reg-prefix.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 18b32cad6e..874401416d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2019-05-15 John Darrington + + * config/tc-s12z.c (register_prefix): New variable. (md_show_usage, + md_parse_option): parse the new option. + (lex_reg_name): Scan the prefix if one is set. + * doc/c-s12z.texi (S12Z-Opts): Document the new option. + * testsuite/gas/s12z/reg-prefix.d: New file. + * testsuite/gas/s12z/reg-prefix.s: New file. + * testsuite/gas/s12z/s12z.exp: Add them. + 2019-05-14 John Darrington * doc/as.texi (Machine Dependencies): Fix misaligned menu entry. diff --git a/gas/config/tc-s12z.c b/gas/config/tc-s12z.c index b9c247671d..568f7b593c 100644 --- a/gas/config/tc-s12z.c +++ b/gas/config/tc-s12z.c @@ -32,6 +32,8 @@ const char comment_chars[] = ";"; const char line_comment_chars[] = "#*"; const char line_separator_chars[] = ""; +static char * register_prefix = NULL; + const char EXP_CHARS[] = "eE"; const char FLT_CHARS[] = "dD"; @@ -40,10 +42,12 @@ static char *fail_line_pointer; /* Options and initialization. */ -const char *md_shortopts = "Sm:"; +const char *md_shortopts = ""; struct option md_longopts[] = { + {"mreg-prefix", required_argument, NULL, OPTION_MD_BASE}, + {NULL, no_argument, NULL, 0} }; size_t md_longopts_size = sizeof (md_longopts); @@ -92,8 +96,12 @@ s12z_listing_header (void) } void -md_show_usage (FILE *stream ATTRIBUTE_UNUSED) +md_show_usage (FILE *stream) { + fprintf (stream, + _("\ns12z options:\n" + " -mreg-prefix=PREFIX set a prefix used to indicate register names (default none)" + "\n")); } void @@ -102,9 +110,17 @@ s12z_print_statistics (FILE *file ATTRIBUTE_UNUSED) } int -md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED) +md_parse_option (int c, const char *arg) { - return 0; + switch (c) + { + case OPTION_MD_BASE: + register_prefix = xstrdup (arg); + break; + default: + return 0; + } + return 1; } symbolS * @@ -310,13 +326,30 @@ static bfd_boolean lex_reg_name (uint16_t which, int *reg) { char *p = input_line_pointer; - while (p != 0 && - ((*p >= 'a' && *p <='z') || (*p >= '0' && *p <= '9') || (*p >= 'A' && *p <='Z'))) + + if (p == 0) + return false; + + /* Scan (and ignore) the register prefix. */ + if (register_prefix) + { + int len = strlen (register_prefix); + if (0 == strncmp (register_prefix, p, len)) + p += len; + else + return false; + } + + char *start_of_reg_name = p; + + while ((*p >= 'a' && *p <='z') + || (*p >= '0' && *p <= '9') + || (*p >= 'A' && *p <='Z')) { p++; } - size_t len = p - input_line_pointer; + size_t len = p - start_of_reg_name; if (len <= 0) return false; @@ -327,7 +360,7 @@ lex_reg_name (uint16_t which, int *reg) gas_assert (registers[i].name); if (len == strlen (registers[i].name) - && 0 == strncasecmp (registers[i].name, input_line_pointer, len)) + && 0 == strncasecmp (registers[i].name, start_of_reg_name, len)) { if ((0x1U << i) & which) { diff --git a/gas/doc/c-s12z.texi b/gas/doc/c-s12z.texi index 52a35c9ead..29c0d86a36 100644 --- a/gas/doc/c-s12z.texi +++ b/gas/doc/c-s12z.texi @@ -4,11 +4,11 @@ @ifset GENERIC @page @node S12Z-Dependent -@chapter S12Z Dependent Features +@chapter S12Z Dependent Features @end ifset @ifclear GENERIC @node Machine Dependencies -@chapter S12Z Dependent Features +@chapter S12Z Dependent Features @end ifclear The Freescale S12Z version of @code{@value{AS}} has a few machine @@ -19,7 +19,7 @@ dependent features. * S12Z-Opts:: S12Z Options * S12Z-Syntax:: Syntax * S12Z-Directives:: Assembler Directives -* S12Z-opcodes:: Opcodes +* S12Z-Opcodes:: Opcodes @end menu @node S12Z-Opts @@ -28,9 +28,25 @@ dependent features. @cindex options, S12Z @cindex S12Z options +The S12Z version of @code{@value{AS}} has the following options: + +@cindex @samp{-mreg-prefix=@var{prefix}} option, reg-prefix +You can use the @samp{-mreg-prefix=@var{pfx}} option to indicate +that the assembler expects each register name to be prefixed with the +string @var{pfx}. + +For an explanation of what this means and why it might be needed, +see @ref{Register Notation}. + @node S12Z-Syntax @section Syntax + +@menu +* Register Notation:: How to refer to registers +@end menu + + @cindex S12Z syntax @cindex syntax, S12Z @@ -109,16 +125,21 @@ Thus, they must be within the range [-32768, 32767]. @item Register @samp{@var{reg}} +@cindex register names, S12Z Some instructions accept a register as an operand. -In general, @var{reg} may be a data register (@samp{D0}, @samp{D1} @dots{} -@samp{D7}), the @var{X} register or the @var{Y} register. +In general, @var{reg} may be a +data register (@samp{D0}, @samp{D1} @dots{} @samp{D7}), +the @samp{X} register or the @samp{Y} register. A few instructions accept as an argument the stack pointer register (@samp{S}), and/or the program counter (@samp{P}). Some very special instructions accept arguments which refer to the condition code register. For these arguments the syntax is -@samp{CCR}, @samp{CCH} or @samp{CCL} which refer to the complete condition code register, the condition code register high byte and the condition code register low byte respectively. +@samp{CCR}, @samp{CCH} or @samp{CCL} which refer to the complete +condition code register, the condition code register high byte +and the condition code register low byte respectively. + @item Absolute Direct @samp{@var{symbol}}, or @samp{@var{digits}} @@ -178,8 +199,6 @@ must be one of the data registers @samp{D0}, @samp{D1} @dots{} @samp{D7}. If any of the registers @samp{D2} @dots{} @samp{D5} are specified, then the register value is treated as a signed value. Otherwise it is treated as unsigned. - - @end table For example: @@ -199,12 +218,61 @@ For example: psh cch @end smallexample +@node Register Notation +@subsection Register Notation + +@cindex register notation, S12Z +Without a register prefix (@pxref{S12Z-Opts}), S12Z assembler code is expected in the traditional +format like this: +@smallexample +lea s, (-2,s) +st d2, (0,s) +ld x, symbol +tfr d2, d6 +cmp d6, #1532 +@end smallexample + +@noindent +However, if @code{@value{AS}} is started with (for example) @samp{-mreg-prefix=%} +then all register names must be prefixed with @samp{%} as follows: +@smallexample +lea %s, (-2,%s) +st %d2, (0,%s) +ld %x, symbol +tfr %d2, %d6 +cmp %d6, #1532 +@end smallexample + +The register prefix feature is intended to be used by compilers +to avoid ambiguity between symbols and register names. +Consider the following assembler instruction: +@smallexample +st d0, d1 +@end smallexample +@noindent +This instruction is most likely to +mean ``Store the value in the register D0 into the register D1'' and that is the +default way in which @code{@value{AS}} interprets it. +However it could also be intended to mean +``Store the value in the register D0 into the memory referenced by the symbol +named @samp{d1}''. +If that is what is intended then @code{@value{AS}} must be invoked with +@samp{-mreg-prefix=@var{pfx}} and the code written as +@smallexample +st @var{pfx}d0, d1 +@end smallexample +@noindent +where @var{pfx} is the chosen register prefix. +For this reason, compiler back-ends should choose a register prefix which +cannot be confused with a symbol name. + + @node S12Z-Directives @section Assembler Directives @cindex assembler directives, S12Z -@node S12Z-opcodes +@node S12Z-Opcodes @section Opcodes @cindex S12Z opcodes diff --git a/gas/testsuite/gas/s12z/reg-prefix.d b/gas/testsuite/gas/s12z/reg-prefix.d new file mode 100644 index 0000000000..ed44249d20 --- /dev/null +++ b/gas/testsuite/gas/s12z/reg-prefix.d @@ -0,0 +1,17 @@ +#objdump: -d -r +#name: register prefix +#source: reg-prefix.s --mreg-prefix=% + +tmpdir/reg-prefix.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 01 nop + +00000001 : + 1: c5 bc st d1, d0 + 3: c5 fa 00 00 st d1, d0 + 7: 01 + 5: R_S12Z_OPR .text diff --git a/gas/testsuite/gas/s12z/reg-prefix.s b/gas/testsuite/gas/s12z/reg-prefix.s new file mode 100644 index 0000000000..6f251b5e96 --- /dev/null +++ b/gas/testsuite/gas/s12z/reg-prefix.s @@ -0,0 +1,6 @@ +;;; This test checks that when assembling with --mreg-prefix=% +;;; registers can be distinguished from symbols. + nop +d0: + st %d1, %d0 + st %d1, d0 diff --git a/gas/testsuite/gas/s12z/s12z.exp b/gas/testsuite/gas/s12z/s12z.exp index e8a0744222..cccfc6e549 100644 --- a/gas/testsuite/gas/s12z/s12z.exp +++ b/gas/testsuite/gas/s12z/s12z.exp @@ -138,3 +138,7 @@ run_dump_test st-large-direct run_dump_test st-small-direct run_dump_test imm-dest + +# Miscellaneous + +run_dump_test reg-prefix -- 2.34.1