x86: handle SVR4 escaped binary operators
authorJan Beulich <jbeulich@suse.com>
Mon, 20 Jul 2020 06:57:18 +0000 (08:57 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 20 Jul 2020 06:57:18 +0000 (08:57 +0200)
PR gas/4572

When / is a comment character, its use as binary "divide" operator needs
escaping by a backslash. Besides the scrubber needing to support this
(addressed in an earlier change), there are also a few provisions needed
in target specific operator handling.

As the spec calls for % and * to also be escaped because of being
"overloaded", also recognize these, despite the overloading there not
really preventing their use as operators in most (%) or all (*) cases,
given the way how the rest of the assembler works.

To bring source and testsuite in line, also drop the TE_I386AIX part of
the respective conditional, as i?86-*-aix* support had been removed a
while ago.

gas/ChangeLog
gas/config/tc-i386-intel.c
gas/config/tc-i386.c
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/svr4.d [new file with mode: 0644]
gas/testsuite/gas/i386/svr4.s [new file with mode: 0644]

index 67fabb9eabb161474638daeab3b5bbde6ed891ea..2aed48f181d39b8133966a7a7bd29982d32d708d 100644 (file)
@@ -1,3 +1,15 @@
+2020-07-20  Jan Beulich  <jbeulich@suse.com>
+
+       PR gas/4572
+       * config/tc-i386.c (i386_comment_chars): Drop TE_I386AIX from
+       conditional around it.
+       (md_begin): Insert backslash into operand_chars[] when slash is
+       a comment character.
+       * config/tc-i386-intel.c (i386_operator): Recognize \/, \%, and
+       \* as operators when / may be a comment character.
+       * testsuite/gas/i386/svr4.s, testsuite/gas/i386/svr4.d: New.
+       * testsuite/gas/i386/i386.exp: Run new test.
+
 2020-07-20  Jan Beulich  <jbeulich@suse.com>
 
        PR gas/4572
index b326d30fff7d3f71df78f7147383c3161fb64565..a98771bfef17ce7bd4d7d29f07d79a9266c3fbb2 100644 (file)
@@ -123,6 +123,16 @@ operatorT i386_operator (const char *name, unsigned int operands, char *pc)
 {
   unsigned int j;
 
+#ifdef SVR4_COMMENT_CHARS
+  if (!name && operands == 2 && *input_line_pointer == '\\')
+    switch (input_line_pointer[1])
+      {
+      case '/': input_line_pointer += 2; return O_divide;
+      case '%': input_line_pointer += 2; return O_modulus;
+      case '*': input_line_pointer += 2; return O_multiply;
+      }
+#endif
+
   if (!intel_syntax)
     return O_absent;
 
index 5b0a014eaab39ba5276ced2049e7d6b0b498f22a..9ab841383c5fad93dd1f31a6a042f2f5f18b911b 100644 (file)
@@ -480,13 +480,12 @@ const char extra_symbol_chars[] = "*%-([{}"
 #endif
        ;
 
-#if (defined (TE_I386AIX)                              \
-     || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))        \
-        && !defined (TE_GNU)                           \
-        && !defined (TE_LINUX)                         \
-        && !defined (TE_FreeBSD)                       \
-        && !defined (TE_DragonFly)                     \
-        && !defined (TE_NetBSD)))
+#if ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))    \
+     && !defined (TE_GNU)                              \
+     && !defined (TE_LINUX)                            \
+     && !defined (TE_FreeBSD)                          \
+     && !defined (TE_DragonFly)                                \
+     && !defined (TE_NetBSD))
 /* This array holds the chars that always start a comment.  If the
    pre-processor is disabled, these aren't very useful.  The option
    --divide will remove '/' from this list.  */
@@ -3116,6 +3115,10 @@ md_begin (void)
            mnemonic_chars[c] = c;
            operand_chars[c] = c;
          }
+#ifdef SVR4_COMMENT_CHARS
+       else if (c == '\\' && strchr (i386_comment_chars, '/'))
+         operand_chars[c] = c;
+#endif
 
        if (ISALPHA (c) || ISDIGIT (c))
          identifier_chars[c] = c;
index f4017322cb596e61ca0f917de6897339a951e0bb..a91ad798660cbb762d606bed66beb9ebc7ccf268 100644 (file)
@@ -692,6 +692,14 @@ if [expr [istarget "i*86-*-*"] || [istarget "x86_64-*-*"]] then {
        run_dump_test "dw2-compressed-1"
        run_dump_test "dw2-compressed-3a"
        run_dump_test "dw2-compressed-3b"
+
+       if {![istarget "*-*-dragonfly*"]
+           && ![istarget "*-*-gnu*"]
+           && ![istarget "*-*-freebsd*"]
+           && ![istarget "*-*-linux*"]
+           && ![istarget "*-*-netbsd*"]} then {
+           run_dump_test "svr4"
+       }
     }
 }
 
diff --git a/gas/testsuite/gas/i386/svr4.d b/gas/testsuite/gas/i386/svr4.d
new file mode 100644 (file)
index 0000000..3a46354
--- /dev/null
@@ -0,0 +1,24 @@
+#objdump: -dtw
+#name: SVR4 comment char escape handling
+
+.*: +file format .*
+
+SYMBOL TABLE:
+0+00 .* \.text[        ]+0+ \.text
+0+00 .* \.data[        ]+0+ \.data
+0+00 .* \.bss[         ]+0+ \.bss
+0+00 .* \.text[        ]+0+ svr4
+0+04 .* \*ABS\*[       ]+0+ a
+0+03 .* \*ABS\*[       ]+0+ b
+0+4c .* \*ABS\*[       ]+0+ c
+
+Disassembly of section .text:
+
+0+0 <svr4>:
+[       ]*[0-9a-f]+:[   ]+b0 07[        ]+mov    \$0x7,%al
+[       ]*[0-9a-f]+:[   ]+b0 01[        ]+mov    \$0x1,%al
+[       ]*[0-9a-f]+:[   ]+b0 1e[        ]+mov    \$0x1e,%al
+[       ]*[0-9a-f]+:[   ]+b0 05[        ]+mov    \$0x5,%al
+[       ]*[0-9a-f]+:[   ]+b0 02[        ]+mov    \$0x2,%al
+[       ]*[0-9a-f]+:[   ]+b0 33[        ]+mov    \$0x33,%al
+#pass
diff --git a/gas/testsuite/gas/i386/svr4.s b/gas/testsuite/gas/i386/svr4.s
new file mode 100644 (file)
index 0000000..4565e01
--- /dev/null
@@ -0,0 +1,31 @@
+       .text
+
+       .if 1 / 2
+       .else
+       .error
+       .endif
+
+       .if 1 \/ 2
+       .error
+       .endif
+
+       .if 4 \% 2
+       .error
+       .endif
+
+       .if 1 \* 0
+       .error
+       .endif
+
+svr4:
+       mov     $(15 \/ 2), %al
+       mov     $(15 \% 2), %al
+       mov     $(15 \* 2), %al
+
+       .byte   0xb0, 17 \/ 3
+       .byte   0xb0, 17 \% 3
+       .byte   0xb0, 17 \* 3
+
+       .equiv  a, 19 \/ 4
+       .equiv  b, 19 \% 4
+       .equiv  c, 19 \* 4