Split out do_assembler_dialects.

* final.c [ASSEMBLER_DIALECT](do_assembler_dialects): New
	function to implement assembler dialects.
	(output_asm_insn): Use do_assembler_dialects.
	(asm_fprintf): Likewise.

	* gcc.target/i386/asm-dialect-1.c: New test case.

From-SVN: r189854
This commit is contained in:
Siddhesh Poyarekar 2012-07-25 16:01:17 +00:00 committed by Richard Henderson
parent 5714c34f15
commit d16586194f
4 changed files with 99 additions and 69 deletions

View File

@ -1,3 +1,10 @@
2012-07-25 Siddhesh Poyarekar <siddhesh@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.
2012-07-25 Richard Henderson <rth@redhat.com>
PR bootstrap/54092

View File

@ -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

View File

@ -1,3 +1,7 @@
2012-07-25 Siddhesh Poyarekar <siddhesh@redhat.com>
* gcc.target/i386/asm-dialect-1.c: New test case.
2012-07-25 Kirill Yukhin <kirill.yukhin@intel.com>
Michael Zolotukhin <michael.v.zolotukhin@intel.com>

View File

@ -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;
}