Commit d5c724c4 by Richard Kenner

(dialect_number): New variable.

(init_final): Initialize it.
(output_asm_insn, asm_fprintf): Support ASSEMBLER_DIALECT.

From-SVN: r5744
parent bfe3c361
/* Convert RTL to assembler code and output it, for GNU compiler. /* Convert RTL to assembler code and output it, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -241,6 +241,12 @@ static int app_on; ...@@ -241,6 +241,12 @@ static int app_on;
rtx final_sequence; rtx final_sequence;
#ifdef ASSEMBLER_DIALECT
/* Number of the assembler dialect to use, starting at 0. */
static int dialect_number;
#endif
/* Indexed by line number, nonzero if there is a note for that line. */ /* Indexed by line number, nonzero if there is a note for that line. */
static char *line_note_exists; static char *line_note_exists;
...@@ -287,6 +293,10 @@ init_final (filename) ...@@ -287,6 +293,10 @@ init_final (filename)
max_block_depth = 20; max_block_depth = 20;
pending_blocks = (int *) xmalloc (20 * sizeof *pending_blocks); pending_blocks = (int *) xmalloc (20 * sizeof *pending_blocks);
final_sequence = 0; final_sequence = 0;
#ifdef ASSEMBLER_DIALECT
dialect_number = ASSEMBLER_DIALECT;
#endif
} }
/* Called at end of source file, /* Called at end of source file,
...@@ -2298,7 +2308,7 @@ output_asm_insn (template, operands) ...@@ -2298,7 +2308,7 @@ output_asm_insn (template, operands)
rtx *operands; rtx *operands;
{ {
register char *p; register char *p;
register int c; register int c, i;
/* An insn may return a null string template /* An insn may return a null string template
in a case where no assembler code is needed. */ in a case where no assembler code is needed. */
...@@ -2313,106 +2323,130 @@ output_asm_insn (template, operands) ...@@ -2313,106 +2323,130 @@ output_asm_insn (template, operands)
#endif #endif
while (c = *p++) while (c = *p++)
{ switch (c)
{
#ifdef ASM_OUTPUT_OPCODE #ifdef ASM_OUTPUT_OPCODE
if (c == '\n') case '\n':
{
putc (c, asm_out_file);
while ((c = *p) == '\t')
{
putc (c, asm_out_file);
p++;
}
ASM_OUTPUT_OPCODE (asm_out_file, p);
}
else
#endif
if (c != '%')
putc (c, asm_out_file); putc (c, asm_out_file);
else while ((c = *p) == '\t')
{ {
/* %% outputs a single %. */ putc (c, asm_out_file);
if (*p == '%') p++;
{ }
p++; ASM_OUTPUT_OPCODE (asm_out_file, p);
putc (c, asm_out_file); break;
} #endif
/* %= outputs a number which is unique to each insn in the entire
compilation. This is useful for making local labels that are #ifdef ASSEMBLER_DIALECT
referred to more than once in a given insn. */ case '{':
else if (*p == '=') /* 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++; p++;
fprintf (asm_out_file, "%d", insn_counter); }
} break;
/* % followed by a letter and some digits
outputs an operand in a special way depending on the letter. case '|':
Letters `acln' are implemented directly. /* Skip to close brace. */
Other letters are passed to `output_operand' so that while (*p && *p++ != '}')
the PRINT_OPERAND macro can define them. */ ;
else if ((*p >= 'a' && *p <= 'z') break;
|| (*p >= 'A' && *p <= 'Z'))
{ case '}':
int letter = *p++; break;
c = atoi (p); #endif
if (! (*p >= '0' && *p <= '9')) case '%':
output_operand_lossage ("operand number missing after %-letter"); /* %% outputs a single %. */
else if (this_is_asm_operands && c >= (unsigned) insn_noperands) if (*p == '%')
output_operand_lossage ("operand number out of range"); {
else if (letter == 'l') p++;
output_asm_label (operands[c]); putc (c, asm_out_file);
else if (letter == 'a') }
output_address (operands[c]); /* %= outputs a number which is unique to each insn in the entire
else if (letter == 'c') compilation. This is useful for making local labels that are
{ referred to more than once in a given insn. */
if (CONSTANT_ADDRESS_P (operands[c])) else if (*p == '=')
output_addr_const (asm_out_file, operands[c]); {
else p++;
output_operand (operands[c], 'c'); fprintf (asm_out_file, "%d", insn_counter);
} }
else if (letter == 'n') /* % followed by a letter and some digits
{ outputs an operand in a special way depending on the letter.
if (GET_CODE (operands[c]) == CONST_INT) Letters `acln' are implemented directly.
fprintf (asm_out_file, Other letters are passed to `output_operand' so that
the PRINT_OPERAND macro can define them. */
else if ((*p >= 'a' && *p <= 'z')
|| (*p >= 'A' && *p <= 'Z'))
{
int letter = *p++;
c = atoi (p);
if (! (*p >= '0' && *p <= '9'))
output_operand_lossage ("operand number missing after %-letter");
else if (this_is_asm_operands && c >= (unsigned) insn_noperands)
output_operand_lossage ("operand number out of range");
else if (letter == 'l')
output_asm_label (operands[c]);
else if (letter == 'a')
output_address (operands[c]);
else if (letter == 'c')
{
if (CONSTANT_ADDRESS_P (operands[c]))
output_addr_const (asm_out_file, operands[c]);
else
output_operand (operands[c], 'c');
}
else if (letter == 'n')
{
if (GET_CODE (operands[c]) == CONST_INT)
fprintf (asm_out_file,
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
"%d", "%d",
#else #else
"%ld", "%ld",
#endif #endif
- INTVAL (operands[c])); - INTVAL (operands[c]));
else else
{ {
putc ('-', asm_out_file); putc ('-', asm_out_file);
output_addr_const (asm_out_file, operands[c]); output_addr_const (asm_out_file, operands[c]);
} }
} }
else else
output_operand (operands[c], letter); output_operand (operands[c], letter);
while ((c = *p) >= '0' && c <= '9') p++; while ((c = *p) >= '0' && c <= '9') p++;
} }
/* % followed by a digit outputs an operand the default way. */ /* % followed by a digit outputs an operand the default way. */
else if (*p >= '0' && *p <= '9') else if (*p >= '0' && *p <= '9')
{ {
c = atoi (p); c = atoi (p);
if (this_is_asm_operands && c >= (unsigned) insn_noperands) if (this_is_asm_operands && c >= (unsigned) insn_noperands)
output_operand_lossage ("operand number out of range"); output_operand_lossage ("operand number out of range");
else else
output_operand (operands[c], 0); output_operand (operands[c], 0);
while ((c = *p) >= '0' && c <= '9') p++; while ((c = *p) >= '0' && c <= '9') p++;
} }
/* % followed by punctuation: output something for that /* % followed by punctuation: output something for that
punctuation character alone, with no operand. punctuation character alone, with no operand.
The PRINT_OPERAND macro decides what is actually done. */ The PRINT_OPERAND macro decides what is actually done. */
#ifdef PRINT_OPERAND_PUNCT_VALID_P #ifdef PRINT_OPERAND_PUNCT_VALID_P
else if (PRINT_OPERAND_PUNCT_VALID_P (*p)) else if (PRINT_OPERAND_PUNCT_VALID_P (*p))
output_operand (NULL_RTX, *p++); output_operand (NULL_RTX, *p++);
#endif #endif
else else
output_operand_lossage ("invalid %%-code"); output_operand_lossage ("invalid %%-code");
} break;
}
default:
putc (c, asm_out_file);
}
if (flag_print_asm_name) if (flag_print_asm_name)
{ {
...@@ -2640,7 +2674,9 @@ output_addr_const (file, x) ...@@ -2640,7 +2674,9 @@ output_addr_const (file, x)
%U prints the value of USER_LABEL_PREFIX. %U prints the value of USER_LABEL_PREFIX.
%I prints the value of IMMEDIATE_PREFIX. %I prints the value of IMMEDIATE_PREFIX.
%O runs ASM_OUTPUT_OPCODE to transform what follows in the string. %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
Also supported are %d, %x, %s, %e, %f, %g and %%. */ Also supported are %d, %x, %s, %e, %f, %g and %%.
We handle alternate assembler dialects here, just like output_asm_insn. */
void void
asm_fprintf (va_alist) asm_fprintf (va_alist)
...@@ -2650,6 +2686,7 @@ asm_fprintf (va_alist) ...@@ -2650,6 +2686,7 @@ asm_fprintf (va_alist)
FILE *file; FILE *file;
char buf[10]; char buf[10];
char *p, *q, c; char *p, *q, c;
int i;
va_start (argptr); va_start (argptr);
...@@ -2660,6 +2697,30 @@ asm_fprintf (va_alist) ...@@ -2660,6 +2697,30 @@ asm_fprintf (va_alist)
while (c = *p++) while (c = *p++)
switch (c) switch (c)
{ {
#ifdef ASSEMBLER_DIALECT
case '{':
/* 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 '}':
break;
#endif
case '%': case '%':
c = *p++; c = *p++;
q = &buf[1]; q = &buf[1];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment