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
This commit is contained in:
Alexandre Oliva 2000-11-23 06:37:23 +00:00 committed by Alexandre Oliva
parent 43c0563453
commit 422be3c3cc
7 changed files with 90 additions and 139 deletions

View File

@ -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.

View File

@ -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");
}
}

View File

@ -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;

View File

@ -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

View File

@ -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");
}
}

View File

@ -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

View File

@ -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: