diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1993-10-12 07:58:29 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1993-10-12 07:58:29 -0400 |
commit | d5c724c4e7d07d86cb9d70f712586d992817ff85 (patch) | |
tree | 95f43024f7623c82ba1c0b6c61ee30143c86fc1e /gcc/final.c | |
parent | bfe3c3615affe97ab94036b5274ff51afc485e1c (diff) | |
download | gcc-d5c724c4e7d07d86cb9d70f712586d992817ff85.zip gcc-d5c724c4e7d07d86cb9d70f712586d992817ff85.tar.gz gcc-d5c724c4e7d07d86cb9d70f712586d992817ff85.tar.bz2 |
(dialect_number): New variable.
(init_final): Initialize it.
(output_asm_insn, asm_fprintf): Support ASSEMBLER_DIALECT.
From-SVN: r5744
Diffstat (limited to 'gcc/final.c')
-rw-r--r-- | gcc/final.c | 251 |
1 files changed, 156 insertions, 95 deletions
diff --git a/gcc/final.c b/gcc/final.c index 82077cc..4c19f11 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1,5 +1,5 @@ /* 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. @@ -241,6 +241,12 @@ static int app_on; 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. */ static char *line_note_exists; @@ -287,6 +293,10 @@ init_final (filename) max_block_depth = 20; pending_blocks = (int *) xmalloc (20 * sizeof *pending_blocks); final_sequence = 0; + +#ifdef ASSEMBLER_DIALECT + dialect_number = ASSEMBLER_DIALECT; +#endif } /* Called at end of source file, @@ -2298,7 +2308,7 @@ output_asm_insn (template, operands) rtx *operands; { register char *p; - register int c; + register int c, i; /* An insn may return a null string template in a case where no assembler code is needed. */ @@ -2313,106 +2323,130 @@ output_asm_insn (template, operands) #endif while (c = *p++) - { + switch (c) + { #ifdef ASM_OUTPUT_OPCODE - if (c == '\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 != '%') + case '\n': putc (c, asm_out_file); - else - { - /* %% outputs a single %. */ - if (*p == '%') - { - p++; - putc (c, asm_out_file); - } - /* %= outputs a number which is unique to each insn in the entire - compilation. This is useful for making local labels that are - referred to more than once in a given insn. */ - else if (*p == '=') - { + while ((c = *p) == '\t') + { + putc (c, asm_out_file); + p++; + } + ASM_OUTPUT_OPCODE (asm_out_file, p); + break; +#endif + +#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++; - fprintf (asm_out_file, "%d", insn_counter); - } - /* % followed by a letter and some digits - outputs an operand in a special way depending on the letter. - Letters `acln' are implemented directly. - 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, + } + break; + + case '|': + /* Skip to close brace. */ + while (*p && *p++ != '}') + ; + break; + + case '}': + break; +#endif + + case '%': + /* %% outputs a single %. */ + if (*p == '%') + { + p++; + putc (c, asm_out_file); + } + /* %= outputs a number which is unique to each insn in the entire + compilation. This is useful for making local labels that are + referred to more than once in a given insn. */ + else if (*p == '=') + { + p++; + fprintf (asm_out_file, "%d", insn_counter); + } + /* % followed by a letter and some digits + outputs an operand in a special way depending on the letter. + Letters `acln' are implemented directly. + 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 - "%d", + "%d", #else - "%ld", + "%ld", #endif - - INTVAL (operands[c])); - else - { - putc ('-', asm_out_file); - output_addr_const (asm_out_file, operands[c]); - } - } - else - output_operand (operands[c], letter); - - while ((c = *p) >= '0' && c <= '9') p++; - } - /* % followed by a digit outputs an operand the default way. */ - else if (*p >= '0' && *p <= '9') - { - c = atoi (p); - if (this_is_asm_operands && c >= (unsigned) insn_noperands) - output_operand_lossage ("operand number out of range"); - else - output_operand (operands[c], 0); - while ((c = *p) >= '0' && c <= '9') p++; - } - /* % followed by punctuation: output something for that - punctuation character alone, with no operand. - The PRINT_OPERAND macro decides what is actually done. */ + - INTVAL (operands[c])); + else + { + putc ('-', asm_out_file); + output_addr_const (asm_out_file, operands[c]); + } + } + else + output_operand (operands[c], letter); + + while ((c = *p) >= '0' && c <= '9') p++; + } + /* % followed by a digit outputs an operand the default way. */ + else if (*p >= '0' && *p <= '9') + { + c = atoi (p); + if (this_is_asm_operands && c >= (unsigned) insn_noperands) + output_operand_lossage ("operand number out of range"); + else + output_operand (operands[c], 0); + while ((c = *p) >= '0' && c <= '9') p++; + } + /* % followed by punctuation: output something for that + punctuation character alone, with no operand. + The PRINT_OPERAND macro decides what is actually done. */ #ifdef PRINT_OPERAND_PUNCT_VALID_P - else if (PRINT_OPERAND_PUNCT_VALID_P (*p)) - output_operand (NULL_RTX, *p++); + else if (PRINT_OPERAND_PUNCT_VALID_P (*p)) + output_operand (NULL_RTX, *p++); #endif - else - output_operand_lossage ("invalid %%-code"); - } - } + else + output_operand_lossage ("invalid %%-code"); + break; + + default: + putc (c, asm_out_file); + } if (flag_print_asm_name) { @@ -2640,7 +2674,9 @@ output_addr_const (file, x) %U prints the value of USER_LABEL_PREFIX. %I prints the value of IMMEDIATE_PREFIX. %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 asm_fprintf (va_alist) @@ -2650,6 +2686,7 @@ asm_fprintf (va_alist) FILE *file; char buf[10]; char *p, *q, c; + int i; va_start (argptr); @@ -2660,6 +2697,30 @@ asm_fprintf (va_alist) while (c = *p++) 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 '%': c = *p++; q = &buf[1]; |