On Wed, 25 Jul 2012 08:31:14 -0700, Richard wrote:
* gcc.dg/asm-dialect-1.c: New test case.
... except this should go in gcc.target/i386/ without the { target }
qualifier.
Thanks, here's the updated version.
Regards,
Siddhesh
gcc/ChangeLog:
2012-07-25 Siddhesh Poyarekar siddh...@redhat.com
* final.c [ASSEMBLER_DIALECT](do_assembler_dialects): New
function to implement assembler dialects.
(output_asm_insn): Use do_assembler_dialects.
(asm_fprintf): Likewise.
testsuite/ChangeLog:
2012-07-25 Siddhesh Poyarekar siddh...@redhat.com
* gcc.target/i386/asm-dialect-1.c: New test case.
diff --git a/gcc/final.c b/gcc/final.c
index 7db0471..095d608 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -3338,6 +3338,72 @@ output_asm_operand_names (rtx *operands, int *oporder, int nops)
}
}
+#ifdef ASSEMBLER_DIALECT
+/* Helper function to parse assembler dialects in the asm string.
+ This is called from output_asm_insn and asm_fprintf. */
+static const char *
+do_assembler_dialects (const char *p, int *dialect)
+{
+ char c = *(p - 1);
+
+ switch (c)
+{
+case '{':
+ {
+int i;
+
+if (*dialect)
+ output_operand_lossage (nested assembly dialect alternatives);
+else
+ *dialect = 1;
+
+/* If we want the first dialect, do nothing. Otherwise, skip
+ DIALECT_NUMBER of strings ending with '|'. */
+for (i = 0; i dialect_number; i++)
+ {
+while (*p *p != '}' *p++ != '|')
+ ;
+if (*p == '}')
+ break;
+ }
+
+if (*p == '\0')
+ output_operand_lossage (unterminated assembly dialect alternative);
+ }
+ break;
+
+case '|':
+ if (*dialect)
+{
+ /* Skip to close brace. */
+ do
+{
+ if (*p == '\0')
+ {
+ output_operand_lossage (unterminated assembly dialect alternative);
+ break;
+ }
+}
+ while (*p++ != '}');
+ *dialect = 0;
+}
+ else
+putc (c, asm_out_file);
+ break;
+
+case '}':
+ if (! *dialect)
+putc (c, asm_out_file);
+ *dialect = 0;
+ break;
+default:
+ gcc_unreachable ();
+}
+
+ return p;
+}
+#endif
+
/* Output text from TEMPLATE to the assembler output file,
obeying %-directions to substitute operands taken from
the vector OPERANDS.
@@ -3404,54 +3470,9 @@ output_asm_insn (const char *templ, rtx *operands)
#ifdef ASSEMBLER_DIALECT
case '{':
- {
- int i;
-
- if (dialect)
- output_operand_lossage (nested assembly dialect alternatives);
- else
- dialect = 1;
-
- /* If we want the first dialect, do nothing. Otherwise, skip
- DIALECT_NUMBER of strings ending with '|'. */
- for (i = 0; i dialect_number; i++)
- {
- while (*p *p != '}' *p++ != '|')
- ;
- if (*p == '}')
- break;
- if (*p == '|')
- p++;
- }
-
- if (*p == '\0')
- output_operand_lossage (unterminated assembly dialect alternative);
- }
- break;
-
- case '|':
- if (dialect)
- {
- /* Skip to close brace. */
- do
- {
- if (*p == '\0')
- {
- output_operand_lossage (unterminated assembly dialect alternative);
- break;
- }
- }
- while (*p++ != '}');
- dialect = 0;
- }
- else
- putc (c, asm_out_file);
- break;
-
case '}':
- if (! dialect)
- putc (c, asm_out_file);
- dialect = 0;
+ case '|':
+ p = do_assembler_dialects (p, dialect);
break;
#endif
@@ -3910,6 +3931,9 @@ asm_fprintf (FILE *file, const char *p, ...)
{
char buf[10];
char *q, c;
+#ifdef ASSEMBLER_DIALECT
+ int dialect = 0;
+#endif
va_list argptr;
va_start (argptr, p);
@@ -3921,29 +3945,9 @@ asm_fprintf (FILE *file, const char *p, ...)
{
#ifdef ASSEMBLER_DIALECT
case '{':
- {
- int i;
-
- /* If we want the first dialect, do nothing. Otherwise, skip
- DIALECT_NUMBER of strings ending with '|'. */
- for (i = 0; i dialect_number; i++)
- {
- while (*p *p++ != '|')
- ;
-
- if (*p == '|')
- p++;
- }
- }
- break;
-
- case '|':
- /* Skip to close brace. */
- while (*p *p++ != '}')
- ;
- break;
-
case '}':
+ case '|':
+ p = do_assembler_dialects (p, dialect);
break;
#endif
diff --git a/gcc/testsuite/gcc.target/i386/asm-dialect-1.c b/gcc/testsuite/gcc.target/i386/asm-dialect-1.c
new file mode 100644
index 000..a53d2e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/asm-dialect-1.c
@@ -0,0 +1,15 @@
+/* { dg-options -masm=intel } */
+
+extern void abort (void);
+
+int
+main (void)
+{
+ int f = 0;
+ asm ({movl $42, %%eax | mov eax, 42} : :);
+ asm ({movl $41, %0||mov %0, 43} : =r(f));
+ if (f != 42)
+abort ();
+
+ return 0;
+}