From: Jeffrey A Law Date: Fri, 24 Oct 1997 19:18:29 +0000 (+0000) Subject: mn10300.c (symbolic_operand, [...]): New functions. X-Git-Tag: releases/egcs-1.0.0~252 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e9ad457396dc3779f36332630b5b02755f611cb8;p=thirdparty%2Fgcc.git mn10300.c (symbolic_operand, [...]): New functions. * mn10300.c (symbolic_operand, legitimize_address): New functions. * mn10300.h (LEGITIMIZE_ADDRESS): Call legitimize_address. (GO_IF_LEGITIMATE_ADDRESS): Don't allow base + symbolic. From-SVN: r16158 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 272e137d7893..f4b287557a58 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Fri Oct 24 13:19:40 1997 Jeffrey A Law (law@cygnus.com) + + * mn10300.c (symbolic_operand, legitimize_address): New functions. + * mn10300.h (LEGITIMIZE_ADDRESS): Call legitimize_address. + (GO_IF_LEGITIMATE_ADDRESS): Don't allow base + symbolic. + Thu Oct 23 09:35:12 1997 Jeffrey A Law (law@cygnus.com) * version.c: Bump for snapshot. diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index e5559212b076..8bb5371ad738 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -989,3 +989,72 @@ impossible_plus_operand (op, mode) return 0; } + +/* Return 1 if X contains a symbolic expression. We know these + expressions will have one of a few well defined forms, so + we need only check those forms. */ +int +symbolic_operand (op, mode) + register rtx op; + enum machine_mode mode; +{ + switch (GET_CODE (op)) + { + case SYMBOL_REF: + case LABEL_REF: + return 1; + case CONST: + op = XEXP (op, 0); + return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF + || GET_CODE (XEXP (op, 0)) == LABEL_REF) + && GET_CODE (XEXP (op, 1)) == CONST_INT); + default: + return 0; + } +} + +/* Try machine dependent ways of modifying an illegitimate address + to be legitimate. If we find one, return the new valid address. + This macro is used in only one place: `memory_address' in explow.c. + + OLDX is the address as it was before break_out_memory_refs was called. + In some cases it is useful to look at this to decide what needs to be done. + + MODE and WIN are passed so that this macro can use + GO_IF_LEGITIMATE_ADDRESS. + + Normally it is always safe for this macro to do nothing. It exists to + recognize opportunities to optimize the output. + + But on a few ports with segmented architectures and indexed addressing + (mn10300, hppa) it is used to rewrite certain problematical addresses. */ +rtx +legitimize_address (x, oldx, mode) + rtx x; + rtx oldx; + enum machine_mode mode; +{ + /* Uh-oh. We might have an address for x[n-100000]. This needs + special handling to avoid creating an indexed memory address + with x-100000 as the base. */ + if (GET_CODE (x) == PLUS + && symbolic_operand (XEXP (x, 1), VOIDmode)) + { + /* Ugly. We modify things here so that the address offset specified + by the index expression is computed first, then added to x to form + the entire address. */ + + rtx regx1, regx2, regy1, regy2, y; + + /* Strip off any CONST. */ + y = XEXP (x, 1); + if (GET_CODE (y) == CONST) + y = XEXP (y, 0); + + regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0)); + regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0)); + regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0)); + regx1 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode, regx1, regy2)); + return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1)); + } +} diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index 88065a2ece3e..32016067b2e4 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -661,7 +661,7 @@ extern struct rtx_def *mn10300_builtin_saveregs (); base = XEXP (X, 1), index = XEXP (X, 0); \ if (base != 0 && index != 0) \ { \ - if (CONSTANT_ADDRESS_P (index)) \ + if (GET_CODE (index) == CONST_INT) \ goto ADDR; \ if (REG_P (index) \ && REG_OK_FOR_INDEX_P (index) \ @@ -685,7 +685,12 @@ extern struct rtx_def *mn10300_builtin_saveregs (); It is always safe for this macro to do nothing. It exists to recognize opportunities to optimize the output. */ -#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) {} +extern struct rtx_def *legitimize_address (); +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ +{ rtx orig_x = (X); \ + (X) = legitimize_address (X, OLDX, MODE); \ + if ((X) != orig_x && memory_address_p (MODE, X)) \ + goto WIN; } /* Go to LABEL if ADDR (a legitimate address expression) has an effect that depends on the machine mode it is used for. */ @@ -998,3 +1003,4 @@ extern int impossible_plus_operand (); extern enum reg_class secondary_reload_class (); extern int initial_offset (); extern char *output_tst (); +int symbolic_operand ();