From cdf899781c7321987a9948e5ca0847e8b38da798 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Mon, 13 Aug 2018 11:33:38 +0000 Subject: [PATCH] S/390: Factor out constant pool ref decomposition gcc/ChangeLog: 2018-08-13 Ilya Leoshkevich * config/s390/s390.c (s390_decompose_constant_pool_ref): New function. (s390_decompose_address): Factor out constant pool ref decomposition. From-SVN: r263504 --- gcc/ChangeLog | 7 ++ gcc/config/s390/s390.c | 155 ++++++++++++++++++----------------------- 2 files changed, 74 insertions(+), 88 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cdd524d8cf2..e4cf0b693a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-08-13 Ilya Leoshkevich + + * 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 * config/nds32/nds32-predicates.c diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index d5511d01192..cc6f3489998 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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 -- 2.30.2