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 /gcc/config/sh | |
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
Diffstat (limited to 'gcc/config/sh')
-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 |
3 files changed, 45 insertions, 126 deletions
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 |