S/390: Factor out constant pool ref decomposition

gcc/ChangeLog:

2018-08-13  Ilya Leoshkevich  <iii@linux.ibm.com>

	* config/s390/s390.c (s390_decompose_constant_pool_ref):
        New function.
	(s390_decompose_address): Factor out constant pool ref
        decomposition.

From-SVN: r263504
This commit is contained in:
Ilya Leoshkevich 2018-08-13 11:33:38 +00:00 committed by Andreas Krebbel
parent 5a3b69f94b
commit cdf899781c
2 changed files with 74 additions and 88 deletions

View file

@ -1,3 +1,10 @@
2018-08-13 Ilya Leoshkevich <iii@linux.ibm.com>
* config/s390/s390.c (s390_decompose_constant_pool_ref):
New function.
(s390_decompose_address): Factor out constant pool ref
decomposition.
2018-08-12 Chung-Ju Wu <jasonwucj@gmail.com>
* config/nds32/nds32-predicates.c

View file

@ -2748,6 +2748,67 @@ s390_short_displacement (rtx disp)
return false;
}
/* Attempts to split `ref', which should be either UNSPEC_LTREF or
UNSPEC_LTREL_BASE, into (base + `disp'). In case pool base is not known,
caller-provided `pool_base' is used. If successful, also determines the
following characteristics of `ref': `is_ptr' - whether it can be an
LA argument, `is_base_ptr' - whether the resulting base is a well-known
base register (stack/frame pointer, etc), `is_pool_ptr` - whether it is
considered a literal pool pointer for purposes of avoiding two different
literal pool pointers per insn during or after reload (`B' constraint). */
static bool
s390_decompose_constant_pool_ref (rtx *ref, rtx *disp, bool *is_ptr,
bool *is_base_ptr, bool *is_pool_ptr,
rtx pool_base)
{
if (!*ref)
return true;
if (GET_CODE (*ref) == UNSPEC)
switch (XINT (*ref, 1))
{
case UNSPEC_LTREF:
if (!*disp)
*disp = gen_rtx_UNSPEC (Pmode,
gen_rtvec (1, XVECEXP (*ref, 0, 0)),
UNSPEC_LTREL_OFFSET);
else
return false;
*ref = XVECEXP (*ref, 0, 1);
break;
case UNSPEC_LTREL_BASE:
if (XVECLEN (*ref, 0) == 1)
*ref = pool_base, *is_pool_ptr = true;
else
*ref = XVECEXP (*ref, 0, 1);
break;
default:
return false;
}
if (!REG_P (*ref) || GET_MODE (*ref) != Pmode)
return false;
if (REGNO (*ref) == STACK_POINTER_REGNUM
|| REGNO (*ref) == FRAME_POINTER_REGNUM
|| ((reload_completed || reload_in_progress)
&& frame_pointer_needed
&& REGNO (*ref) == HARD_FRAME_POINTER_REGNUM)
|| REGNO (*ref) == ARG_POINTER_REGNUM
|| (flag_pic
&& REGNO (*ref) == PIC_OFFSET_TABLE_REGNUM))
*is_ptr = *is_base_ptr = true;
if ((reload_completed || reload_in_progress)
&& *ref == cfun->machine->base_reg)
*is_ptr = *is_base_ptr = *is_pool_ptr = true;
return true;
}
/* Decompose a RTL expression ADDR for a memory address into
its components, returned in OUT.
@ -2859,96 +2920,14 @@ s390_decompose_address (rtx addr, struct s390_address *out)
}
/* Validate base register. */
if (base)
{
if (GET_CODE (base) == UNSPEC)
switch (XINT (base, 1))
{
case UNSPEC_LTREF:
if (!disp)
disp = gen_rtx_UNSPEC (Pmode,
gen_rtvec (1, XVECEXP (base, 0, 0)),
UNSPEC_LTREL_OFFSET);
else
return false;
base = XVECEXP (base, 0, 1);
break;
case UNSPEC_LTREL_BASE:
if (XVECLEN (base, 0) == 1)
base = fake_pool_base, literal_pool = true;
else
base = XVECEXP (base, 0, 1);
break;
default:
return false;
}
if (!REG_P (base) || GET_MODE (base) != Pmode)
return false;
if (REGNO (base) == STACK_POINTER_REGNUM
|| REGNO (base) == FRAME_POINTER_REGNUM
|| ((reload_completed || reload_in_progress)
&& frame_pointer_needed
&& REGNO (base) == HARD_FRAME_POINTER_REGNUM)
|| REGNO (base) == ARG_POINTER_REGNUM
|| (flag_pic
&& REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
pointer = base_ptr = true;
if ((reload_completed || reload_in_progress)
&& base == cfun->machine->base_reg)
pointer = base_ptr = literal_pool = true;
}
if (!s390_decompose_constant_pool_ref (&base, &disp, &pointer, &base_ptr,
&literal_pool, fake_pool_base))
return false;
/* Validate index register. */
if (indx)
{
if (GET_CODE (indx) == UNSPEC)
switch (XINT (indx, 1))
{
case UNSPEC_LTREF:
if (!disp)
disp = gen_rtx_UNSPEC (Pmode,
gen_rtvec (1, XVECEXP (indx, 0, 0)),
UNSPEC_LTREL_OFFSET);
else
return false;
indx = XVECEXP (indx, 0, 1);
break;
case UNSPEC_LTREL_BASE:
if (XVECLEN (indx, 0) == 1)
indx = fake_pool_base, literal_pool = true;
else
indx = XVECEXP (indx, 0, 1);
break;
default:
return false;
}
if (!REG_P (indx) || GET_MODE (indx) != Pmode)
return false;
if (REGNO (indx) == STACK_POINTER_REGNUM
|| REGNO (indx) == FRAME_POINTER_REGNUM
|| ((reload_completed || reload_in_progress)
&& frame_pointer_needed
&& REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
|| REGNO (indx) == ARG_POINTER_REGNUM
|| (flag_pic
&& REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
pointer = indx_ptr = true;
if ((reload_completed || reload_in_progress)
&& indx == cfun->machine->base_reg)
pointer = indx_ptr = literal_pool = true;
}
if (!s390_decompose_constant_pool_ref (&indx, &disp, &pointer, &indx_ptr,
&literal_pool, fake_pool_base))
return false;
/* Prefer to use pointer as base, not index. */
if (base && indx && !base_ptr