diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2000-11-23 06:37:23 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2000-11-23 06:37:23 +0000 |
commit | 422be3c3ccc0a941ea3a0a40c339322681b28b2b (patch) | |
tree | 5c0256af6368b27411a55e15e137d7e09aea0433 | |
parent | 43c05634539cbdb4162ac6e067891e8f01ac2f62 (diff) | |
download | gcc-422be3c3ccc0a941ea3a0a40c339322681b28b2b.zip gcc-422be3c3ccc0a941ea3a0a40c339322681b28b2b.tar.gz gcc-422be3c3ccc0a941ea3a0a40c339322681b28b2b.tar.bz2 |
final.c (output_addr_const): Simplify.
* final.c (output_addr_const) [LABEL_REF]: Simplify.
[MINUS]: Enclose non-CONST_INTs in parentheses.
[default]: Try OUTPUT_ADDR_CONST_EXTRA.
* tm.texi (OUTPUT_ADDR_CONST_EXTRA): Document it.
* varasm.c (decode_rtx_const) [CONST]: If it's not something
PLUS or MINUS a CONST_INT, use the whole CONST with offset 0
instead of abort()ing.
* sh.c (output_pic_addr_const): Removed. Fixed all callers.
* sh.h (OUTPUT_ADDR_CONST_EXTRA): New. Handle the UNSPECs
formerly handled in output_pic_addr_const.
* sh.md (sym_label2reg, symPLT_label2reg): Enclose UNSPEC
operands of MINUS in CONSTs so that decode_rtx_const() will
accept them.
From-SVN: r37691
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 118 | ||||
-rw-r--r-- | gcc/config/sh/sh.h | 38 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 15 | ||||
-rw-r--r-- | gcc/final.c | 17 | ||||
-rw-r--r-- | gcc/tm.texi | 12 | ||||
-rw-r--r-- | gcc/varasm.c | 13 |
7 files changed, 90 insertions, 139 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3bb689c..7c7411c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +Thu Nov 23 04:33:33 2000 Alexandre Oliva <aoliva@redhat.com> + + * final.c (output_addr_const) [LABEL_REF]: Simplify. + [MINUS]: Enclose non-CONST_INTs in parentheses. + [default]: Try OUTPUT_ADDR_CONST_EXTRA. + * tm.texi (OUTPUT_ADDR_CONST_EXTRA): Document it. + * varasm.c (decode_rtx_const) [CONST]: If it's not something + PLUS or MINUS a CONST_INT, use the whole CONST with offset 0 + instead of abort()ing. + * sh.c (output_pic_addr_const): Removed. Fixed all callers. + * sh.h (OUTPUT_ADDR_CONST_EXTRA): New. Handle the UNSPECs + formerly handled in output_pic_addr_const. + * sh.md (sym_label2reg, symPLT_label2reg): Enclose UNSPEC + operands of MINUS in CONSTs so that decode_rtx_const() will + accept them. + Thu Nov 23 04:10:30 2000 Alexandre Oliva <aoliva@redhat.com> * config/sh/sh.md (mova_const): New pattern. diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index e41ae32..7f3fdd3 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -202,7 +202,7 @@ print_operand_address (stream, x) break; default: - output_pic_addr_const (stream, x); + output_addr_const (stream, x); break; } } @@ -5334,119 +5334,3 @@ legitimize_pic_address (orig, mode, reg) } return orig; } - -/* Like output_addr_const(), but recognize PIC unspecs and special - expressions. */ -void -output_pic_addr_const (file, x) - FILE *file; - rtx x; -{ - char buf[256]; - - switch (GET_CODE (x)) - { - case PC: - if (flag_pic) - putc ('.', file); - else - abort (); - break; - - case SYMBOL_REF: - assemble_name (file, XSTR (x, 0)); - break; - - case LABEL_REF: - x = XEXP (x, 0); - /* FALLTHRU */ - case CODE_LABEL: - ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); - assemble_name (asm_out_file, buf); - break; - - case CONST: - output_pic_addr_const (file, XEXP (x, 0)); - break; - - case CONST_INT: - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); - break; - - case CONST_DOUBLE: - if (GET_MODE (x) == VOIDmode) - { - /* We can use %d if the number is <32 bits and positive. */ - if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0) - fprintf (file, "0x%lx%08lx", - (unsigned long) CONST_DOUBLE_HIGH (x), - (unsigned long) CONST_DOUBLE_LOW (x)); - else - fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x)); - } - else - /* We can't handle floating point constants; - PRINT_OPERAND must handle them. */ - output_operand_lossage ("floating constant misused"); - break; - - case PLUS: - /* Some assemblers need integer constants to appear first. */ - if (GET_CODE (XEXP (x, 0)) == CONST_INT) - { - output_pic_addr_const (file, XEXP (x, 0)); - fprintf (file, "+"); - output_pic_addr_const (file, XEXP (x, 1)); - } - else if (GET_CODE (XEXP (x, 1)) == CONST_INT - || GET_CODE (XEXP (x, 0)) == PC) - { - output_pic_addr_const (file, XEXP (x, 1)); - fprintf (file, "+"); - output_pic_addr_const (file, XEXP (x, 0)); - } - else - abort (); - break; - - case MINUS: - output_pic_addr_const (file, XEXP (x, 0)); - fprintf (file, "-"); - if (GET_CODE (XEXP (x, 1)) == CONST) - { - putc ('(', file); - output_pic_addr_const (file, XEXP (x, 1)); - putc (')', file); - } - else - output_pic_addr_const (file, XEXP (x, 1)); - break; - - case UNSPEC: - if ((XVECLEN (x, 0)) > 3) - abort (); - output_pic_addr_const (file, XVECEXP (x, 0, 0)); - switch (XINT (x, 1)) - { - case 6: - /* GLOBAL_OFFSET_TABLE or local symbols, no suffix. */ - break; - case 7: - fputs ("@GOT", file); - break; - case 8: - fputs ("@GOTOFF", file); - break; - case 9: - fputs ("@PLT", file); - break; - default: - output_operand_lossage ("invalid UNSPEC as operand"); - break; - } - break; - - default: - output_operand_lossage ("invalid expression as operand"); - } -} diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 5dfd213..5476d14 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -2072,12 +2072,12 @@ do { char dstr[30]; \ #define ASM_OUTPUT_INT(STREAM, EXP) \ (fprintf ((STREAM), "\t.long\t"), \ - output_pic_addr_const ((STREAM), (EXP)), \ + output_addr_const ((STREAM), (EXP)), \ fputc ('\n', (STREAM))) #define ASM_OUTPUT_SHORT(STREAM, EXP) \ (fprintf ((STREAM), "\t.short\t"), \ - output_pic_addr_const ((STREAM), (EXP)), \ + output_addr_const ((STREAM), (EXP)), \ fputc ('\n', (STREAM))) #define ASM_OUTPUT_CHAR(STREAM, EXP) \ @@ -2157,6 +2157,40 @@ do { char dstr[30]; \ #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \ ((CHAR) == '.' || (CHAR) == '#' || (CHAR) == '@' || (CHAR) == ',' \ || (CHAR) == '$') + +/* Recognize machine-specific patterns that may appear within + constants. Used for PIC-specific UNSPECs. */ +#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \ + do \ + if (flag_pic && GET_CODE (X) == UNSPEC && XVECLEN ((X), 0) == 1) \ + { \ + switch (XINT ((X), 1)) \ + { \ + case UNSPEC_PIC: \ + /* GLOBAL_OFFSET_TABLE or local symbols, no suffix. */ \ + output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ + break; \ + case UNSPEC_GOT: \ + output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ + fputs ("@GOT", (STREAM)); \ + break; \ + case UNSPEC_GOTOFF: \ + output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ + fputs ("@GOTOFF", (STREAM)); \ + break; \ + case UNSPEC_PLT: \ + output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ + fputs ("@PLT", (STREAM)); \ + break; \ + default: \ + goto FAIL; \ + } \ + break; \ + } \ + else \ + goto FAIL; \ + while (0) + extern struct rtx_def *sh_compare_op0; extern struct rtx_def *sh_compare_op1; diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 34649e0..549c7e7 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -3596,7 +3596,7 @@ (define_expand "sym_label2reg" [(set (match_operand:SI 0 "" "") (const (minus:SI - (unspec [(match_operand:SI 1 "" "")] UNSPEC_PIC) + (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_PIC)) (const (plus:SI (unspec [(label_ref (match_operand:SI 2 "" ""))] UNSPEC_PIC) @@ -3629,12 +3629,13 @@ (define_expand "symPLT_label2reg" [(set (match_operand:SI 0 "" "") (const (minus:SI - (plus:SI (pc) - (unspec [(match_operand:SI 1 "" "")] UNSPEC_PLT)) - (const - (plus:SI - (unspec [(label_ref (match_operand:SI 2 "" ""))] UNSPEC_PIC) - (const_int 2)))))) + (const (plus:SI + (unspec [(match_operand:SI 1 "" "")] UNSPEC_PLT) + (pc))) + (const (plus:SI + (unspec [(label_ref (match_operand:SI 2 "" ""))] + UNSPEC_PIC) + (const_int 2)))))) (use (match_dup 3))] ;; Even though the PIC register is not really used by the call ;; sequence in which this is expanded, the PLT code assumes the PIC diff --git a/gcc/final.c b/gcc/final.c index c83f722..46c09ee 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -3677,10 +3677,8 @@ output_addr_const (file, x) break; case LABEL_REF: - ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0))); - assemble_name (file, buf); - break; - + x = XEXP (x, 0); + /* Fall through. */ case CODE_LABEL: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); assemble_name (file, buf); @@ -3741,8 +3739,9 @@ output_addr_const (file, x) output_addr_const (file, XEXP (x, 0)); fprintf (file, "-"); - if (GET_CODE (XEXP (x, 1)) == CONST_INT - && INTVAL (XEXP (x, 1)) < 0) + if ((GET_CODE (XEXP (x, 1)) == CONST_INT + && INTVAL (XEXP (x, 1)) < 0) + || GET_CODE (XEXP (x, 1)) != CONST_INT) { fprintf (file, "%s", ASM_OPEN_PAREN); output_addr_const (file, XEXP (x, 1)); @@ -3758,6 +3757,12 @@ output_addr_const (file, x) break; default: +#ifdef OUTPUT_ADDR_CONST_EXTRA + OUTPUT_ADDR_CONST_EXTRA (file, x, fail); + break; + + fail: +#endif output_operand_lossage ("invalid expression as operand"); } } diff --git a/gcc/tm.texi b/gcc/tm.texi index 9f443b6..4752d93 100644 --- a/gcc/tm.texi +++ b/gcc/tm.texi @@ -5500,6 +5500,18 @@ would be identical to repeatedly calling the macro corresponding to a size of @code{UNITS_PER_WORD}, once for each word, you need not define the macro. +@findex OUTPUT_ADDR_CONST_EXTRA +@item OUTPUT_ADDR_CONST_EXTRA (@var{stream}, @var{x}, @var{fail}) +A C statement to recognize @var{rtx} patterns that +@code{output_addr_const} can't deal with, and output assembly code to +@var{stream} corresponding to the pattern @var{x}. This may be used to +allow machine-dependent @code{UNSPEC}s to appear within constants. + +If @code{OUTPUT_ADDR_CONST_EXTRA} fails to recognize a pattern, it must +@code{goto fail}, so that a standard error message is printed. If it +prints an error message itself, by calling, for example, +@code{output_operand_lossage}, it may just complete normally. + @findex ASM_OUTPUT_BYTE @item ASM_OUTPUT_BYTE (@var{stream}, @var{value}) A C statement to output to the stdio stream @var{stream} an assembler diff --git a/gcc/varasm.c b/gcc/varasm.c index e9925bf..009b65f 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -3486,22 +3486,21 @@ decode_rtx_const (mode, x, value) case CONST: x = XEXP (x, 0); - if (GET_CODE (x) == PLUS) + if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT) { value->un.addr.base = XEXP (x, 0); - if (GET_CODE (XEXP (x, 1)) != CONST_INT) - abort (); value->un.addr.offset = INTVAL (XEXP (x, 1)); } - else if (GET_CODE (x) == MINUS) + else if (GET_CODE (x) == MINUS && GET_CODE (XEXP (x, 1)) == CONST_INT) { value->un.addr.base = XEXP (x, 0); - if (GET_CODE (XEXP (x, 1)) != CONST_INT) - abort (); value->un.addr.offset = - INTVAL (XEXP (x, 1)); } else - abort (); + { + value->un.addr.base = x; + value->un.addr.offset = 0; + } break; default: |