S12Z: New option -mreg-prefix
authorJohn Darrington <john@darrington.wattle.id.au>
Wed, 15 May 2019 12:16:33 +0000 (14:16 +0200)
committerJohn Darrington <john@darrington.wattle.id.au>
Wed, 15 May 2019 14:25:18 +0000 (16:25 +0200)
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
gas/config/tc-s12z.c
gas/doc/c-s12z.texi
gas/testsuite/gas/s12z/reg-prefix.d [new file with mode: 0644]
gas/testsuite/gas/s12z/reg-prefix.s [new file with mode: 0644]
gas/testsuite/gas/s12z/s12z.exp

index 18b32cad6ea23efa89e94596e14cf085a57f2465..874401416ddfe295254a6e53294afa2f9f2a81e3 100644 (file)
@@ -1,3 +1,13 @@
+2019-05-15  John Darrington <john@darrington.wattle.id.au>
+
+       * 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 <john@darrington.wattle.id.au>
 
        * doc/as.texi (Machine Dependencies): Fix misaligned menu entry.
index b9c247671d6c2782ea0b9353811dd7a6c9b1387c..568f7b593caf357add7b1ac8bda4f448cf80c439 100644 (file)
@@ -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;
 \f
 /* 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;
 }
 \f
 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)
            {
index 52a35c9ead0659c3a438d4bf10181bfd636e43e9..29c0d86a366cfabe2b3204cb3f3221826c106548 100644 (file)
@@ -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 (file)
index 0000000..ed44249
--- /dev/null
@@ -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 <d0-0x1>:
+   0:  01              nop
+
+00000001 <d0>:
+   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 (file)
index 0000000..6f251b5
--- /dev/null
@@ -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
index e8a074422278c5007b40db30654cc505822be87f..cccfc6e5490d936bb70ddc37fc8e7de137f04618 100644 (file)
@@ -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