static const char *s390_branch_condition_mnemonic PARAMS ((rtx, int));
static int check_mode PARAMS ((rtx, enum machine_mode *));
static int general_s_operand PARAMS ((rtx, enum machine_mode, int));
-static int s390_decompose_address PARAMS ((rtx, struct s390_address *, int));
+static int s390_decompose_address PARAMS ((rtx, struct s390_address *));
static int reg_used_in_mem_p PARAMS ((int, rtx));
static int addr_generation_dependency_p PARAMS ((rtx, rtx));
static void s390_split_branches PARAMS ((void));
case MEM:
if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
return 1;
- if (s390_decompose_address (XEXP (op, 0), &addr, FALSE)
+ if (s390_decompose_address (XEXP (op, 0), &addr)
&& !addr.indx)
return 1;
break;
if (GET_CODE (op) != MEM)
return 0;
- if (!s390_decompose_address (XEXP (op, 0), &addr, FALSE))
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
return 0;
if (addr.indx)
register rtx scratch_in;
{
rtx sum1, sum2, scratch;
+ struct s390_address ad;
/* ??? reload apparently does not ensure that the scratch register
and the target do not overlap. We absolutely require this to be
sum1 = find_replacement (&XEXP (src, 0));
sum2 = find_replacement (&XEXP (src, 1));
- /* Accept already valid addresses. */
+ /* Accept already strictly valid addresses. */
src = gen_rtx_PLUS (Pmode, sum1, sum2);
- if (s390_decompose_address (src, NULL, 1))
+ if (s390_decompose_address (src, &ad)
+ && (!ad.base || REG_OK_FOR_BASE_STRICT_P (ad.base))
+ && (!ad.indx || REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
{
src = legitimize_la_operand (src);
emit_insn (gen_rtx_SET (VOIDmode, target, src));
/* Decompose a RTL expression ADDR for a memory address into
- its components, returned in OUT. The boolean STRICT
- specifies whether strict register checking applies.
+ its components, returned in OUT.
+
Returns 0 if ADDR is not a valid memory address, nonzero
otherwise. If OUT is NULL, don't return the components,
but check for validity only.
canonical form so that they will be recognized. */
static int
-s390_decompose_address (addr, out, strict)
+s390_decompose_address (addr, out)
register rtx addr;
struct s390_address *out;
- int strict;
{
rtx base = NULL_RTX;
rtx indx = NULL_RTX;
if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
return FALSE;
- if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
- || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
- return FALSE;
-
if (REGNO (base) == BASE_REGISTER
|| REGNO (base) == STACK_POINTER_REGNUM
|| REGNO (base) == FRAME_POINTER_REGNUM
if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
return FALSE;
- if ((strict && ! REG_OK_FOR_BASE_STRICT_P (indx))
- || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (indx)))
- return FALSE;
-
if (REGNO (indx) == BASE_REGISTER
|| REGNO (indx) == STACK_POINTER_REGNUM
|| REGNO (indx) == FRAME_POINTER_REGNUM
register rtx addr;
int strict;
{
- return s390_decompose_address (addr, NULL, strict);
+ struct s390_address ad;
+ if (!s390_decompose_address (addr, &ad))
+ return FALSE;
+
+ if (strict)
+ {
+ if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
+ return FALSE;
+ if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
+ return FALSE;
+ }
+ else
+ {
+ if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
+ return FALSE;
+ if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
+ return FALSE;
+ }
+
+ return TRUE;
}
/* Return 1 if OP is a valid operand for the LA instruction.
register rtx op;
{
struct s390_address addr;
- if (!s390_decompose_address (op, &addr, FALSE))
+ if (!s390_decompose_address (op, &addr))
return FALSE;
if (TARGET_64BIT || addr.pointer)
register rtx op;
{
struct s390_address addr;
- if (!s390_decompose_address (op, &addr, FALSE))
+ if (!s390_decompose_address (op, &addr))
abort ();
if (TARGET_64BIT || addr.pointer)
{
struct s390_address ad;
- if (!s390_decompose_address (addr, &ad, TRUE))
+ if (!s390_decompose_address (addr, &ad)
+ || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
+ || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
output_operand_lossage ("Cannot decompose address.");
if (ad.disp)
struct s390_address ad;
if (GET_CODE (x) != MEM
- || !s390_decompose_address (XEXP (x, 0), &ad, TRUE)
+ || !s390_decompose_address (XEXP (x, 0), &ad)
+ || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
|| ad.indx)
abort ();
struct s390_address ad;
if (GET_CODE (x) != MEM
- || !s390_decompose_address (XEXP (x, 0), &ad, TRUE)
+ || !s390_decompose_address (XEXP (x, 0), &ad)
+ || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
|| ad.indx)
abort ();