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:
parent
5714c34f15
commit
d16586194f
4 changed files with 99 additions and 69 deletions
|
@ -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
|
||||
|
|
142
gcc/final.c
142
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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
15
gcc/testsuite/gcc.target/i386/asm-dialect-1.c
Normal file
15
gcc/testsuite/gcc.target/i386/asm-dialect-1.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue