aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-i386.c49
-rw-r--r--gas/testsuite/gas/i386/i386.exp1
-rw-r--r--gas/testsuite/gas/i386/separator.d27
-rw-r--r--gas/testsuite/gas/i386/separator.s41
4 files changed, 99 insertions, 19 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 109fb7e..68c35fb 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -7957,6 +7957,8 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
while (1)
{
+ const char *split;
+
mnem_p = mnemonic;
/* Pseudo-prefixes start with an opening figure brace. */
if ((*mnem_p = *l) == '{')
@@ -7981,9 +7983,10 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
}
l++;
}
- /* Pseudo-prefixes end with a closing figure brace. */
- if (*mnemonic == '{' && is_space_char (*l))
+ split = l;
+ if (is_space_char (*l))
++l;
+ /* Pseudo-prefixes end with a closing figure brace. */
if (*mnemonic == '{' && *l == '}')
{
*mnem_p++ = *l++;
@@ -7991,12 +7994,10 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
goto too_long;
*mnem_p = '\0';
- /* Point l at the closing brace if there's no other separator. */
- if (*l != END_OF_INSN && !is_space_char (*l)
- && *l != PREFIX_SEPARATOR)
- --l;
+ if (is_space_char (*l))
+ ++l;
}
- else if (!is_space_char (*l)
+ else if (l == split
&& *l != END_OF_INSN
&& (intel_syntax
|| (*l != PREFIX_SEPARATOR && *l != ',')))
@@ -8004,7 +8005,7 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
if (mode != parse_all)
break;
as_bad (_("invalid character %s in mnemonic"),
- output_invalid (*l));
+ output_invalid (*split));
return NULL;
}
if (token_start == l)
@@ -8020,7 +8021,6 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
op_lookup (mnemonic);
if (*l != END_OF_INSN
- && (!is_space_char (*l) || l[1] != END_OF_INSN)
&& current_templates.start
&& current_templates.start->opcode_modifier.isprefix)
{
@@ -8142,7 +8142,10 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
}
}
/* Skip past PREFIX_SEPARATOR and reset token_start. */
- token_start = ++l;
+ l += (!intel_syntax && *l == PREFIX_SEPARATOR);
+ if (is_space_char (*l))
+ ++l;
+ token_start = l;
}
else
break;
@@ -8234,8 +8237,7 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
}
/* For compatibility reasons accept MOVSD and CMPSD without
operands even in AT&T mode. */
- else if (*l == END_OF_INSN
- || (is_space_char (*l) && l[1] == END_OF_INSN))
+ else if (*l == END_OF_INSN)
{
mnem_p[-1] = '\0';
op_lookup (mnemonic);
@@ -8277,8 +8279,9 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
l += length;
}
- if (current_templates.start->opcode_modifier.jump == JUMP
- || current_templates.start->opcode_modifier.jump == JUMP_BYTE)
+ if ((current_templates.start->opcode_modifier.jump == JUMP
+ || current_templates.start->opcode_modifier.jump == JUMP_BYTE)
+ && *l == ',')
{
/* Check for a branch hint. We allow ",pt" and ",pn" for
predict taken and predict not taken respectively.
@@ -8286,21 +8289,29 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
and jcxz insns (JumpByte) for current Pentium4 chips. They
may work in the future and it doesn't hurt to accept them
now. */
- if (l[0] == ',' && l[1] == 'p')
+ token_start = l++;
+ if (is_space_char (*l))
+ ++l;
+ if (TOLOWER (*l) == 'p' && ISALPHA (l[1])
+ && (l[2] == END_OF_INSN || is_space_char (l[2])))
{
- if (l[2] == 't')
+ if (TOLOWER (l[1]) == 't')
{
if (!add_prefix (DS_PREFIX_OPCODE))
return NULL;
- l += 3;
+ l += 2;
}
- else if (l[2] == 'n')
+ else if (TOLOWER (l[1]) == 'n')
{
if (!add_prefix (CS_PREFIX_OPCODE))
return NULL;
- l += 3;
+ l += 2;
}
+ else
+ l = token_start;
}
+ else
+ l = token_start;
}
/* Any other comma loses. */
if (*l == ',')
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index facb4ed..bf9cb26 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -106,6 +106,7 @@ if [gas_32_check] then {
run_list_test "equ-2" "-al"
run_list_test "equ-bad"
run_dump_test "curly"
+ run_dump_test "separator"
run_dump_test "divide"
run_dump_test "quoted"
run_dump_test "quoted2"
diff --git a/gas/testsuite/gas/i386/separator.d b/gas/testsuite/gas/i386/separator.d
new file mode 100644
index 0000000..712215a
--- /dev/null
+++ b/gas/testsuite/gas/i386/separator.d
@@ -0,0 +1,27 @@
+#objdump: -dw
+#name: whitespace around special separators
+
+.*: +file format .*
+
+Disassembly of section \.text:
+
+0+ <separators>:
+[ ]*[a-f0-9]+: 3e 72 fd + j[cb],pt .*
+[ ]*[a-f0-9]+: 3e 72 fd + j[cb],pt .*
+[ ]*[a-f0-9]+: 3e 72 fd + j[cb],pt .*
+[ ]*[a-f0-9]+: 3e 72 fd + j[cb],pt .*
+[ ]*[a-f0-9]+: 3e 72 fd + j[cb],pt .*
+[ ]*[a-f0-9]+: 3e 0f 82 f9 ff ff ff j[cb],pt .*
+[ ]*[a-f0-9]+: 3e 0f 82 f9 ff ff ff j[cb],pt .*
+[ ]*[a-f0-9]+: 3e 0f 82 f9 ff ff ff j[cb],pt .*
+[ ]*[a-f0-9]+: 3e 0f 82 f9 ff ff ff j[cb],pt .*
+[ ]*[a-f0-9]+: 65 f7 d8 + gs neg %eax
+[ ]*[a-f0-9]+: 65 f7 d8 + gs neg %eax
+[ ]*[a-f0-9]+: 65 f7 d8 + gs neg %eax
+[ ]*[a-f0-9]+: 65 f7 d8 + gs neg %eax
+[ ]*[a-f0-9]+: 65 f7 d8 + gs neg %eax
+[ ]*[a-f0-9]+: 65 f7 d8 + gs neg %eax
+[ ]*[a-f0-9]+: 65 f7 d8 + gs neg %eax
+[ ]*[a-f0-9]+: 65 f7 d8 + gs neg %eax
+[ ]*[a-f0-9]+: 65 f7 d8 + gs neg %eax
+#pass
diff --git a/gas/testsuite/gas/i386/separator.s b/gas/testsuite/gas/i386/separator.s
new file mode 100644
index 0000000..edac073
--- /dev/null
+++ b/gas/testsuite/gas/i386/separator.s
@@ -0,0 +1,41 @@
+ .text
+separators:
+ jc,pt .
+ jc ,pt .
+ jc, pt .
+ jc , pt .
+ jc/**/,/**/pt .
+
+ {disp32} jc,pt .
+ {disp32} jc ,pt .
+ {disp32} jc, pt .
+ {disp32} jc , pt .
+
+ # Which block to use depends on whether / starts a comment.
+ .ifeq 1/2
+
+ gs/neg %eax
+ gs /neg %eax
+ gs/ neg %eax
+ gs / neg %eax
+ gs/**///**/neg %eax
+
+ {disp32} gs/neg %eax
+ {disp32} gs /neg %eax
+ {disp32} gs/ neg %eax
+ {disp32} gs / neg %eax
+
+ .else
+
+ gs\neg %eax
+ gs \neg %eax
+ gs\ neg %eax
+ gs \ neg %eax
+ gs/**/\/**/neg %eax
+
+ {disp32} gs\neg %eax
+ {disp32} gs \neg %eax
+ {disp32} gs\ neg %eax
+ {disp32} gs \ neg %eax
+
+ .endif