On Wed, May 3, 2017 at 9:38 AM, Daniel Santos <[email protected]> wrote:
> On 05/03/2017 01:10 AM, Uros Bizjak wrote:
>>
>> The order of subexpressions of parallel in general does not matter.
>
>
> Thanks, this makes things much clearer.
>
>>> Also, I'm wondering if there's anything wrong with calling ix86_gen_leave
>>> ()
>>> and plucking the insns out of the generated parallel insn and moving that
>>> into my own parallel rather than generating them in my own function. I
>>> guess all the matters is what is cleanest.
>>
>> Hm... I'd rather see subexpressions generated "by hand".
>
>
> OK. While we're on the topic, are you OK with my changes to ix86_emit_leave
> to generate the notes or would you prefer those by hand as well?
I think they are OK. We are effectively emitting a leave here.
> Also, are these predicates what you had in mind? (I haven't actually tested
> them just yet.)
Yes, these look good to me.
Uros.
> (define_predicate "save_multiple"
> (match_code "parallel")
> {
> const unsigned len = XVECLEN (op, 0);
> unsigned i;
>
> /* Starting from end of vector, count register saves. */
> for (i = 0; i < len; ++i)
> {
> rtx src, dest, addr;
> rtx e = XVECEXP (op, 0, len - 1 - i);
>
> if (GET_CODE (e) != SET)
> break;
>
> src = SET_SRC (e);
> dest = SET_DEST (e);
>
> if (!REG_P (src) || !MEM_P (dest))
> break;
>
> addr = XEXP (dest, 0);
>
> /* Good if dest address is in RAX. */
> if (REG_P (addr) && REGNO (addr) == AX_REG)
> continue;
>
> /* Good if dest address is offset of RAX. */
> if (GET_CODE (addr) == PLUS
> && REG_P (XEXP (addr, 0))
> && REGNO (XEXP (addr, 0)) == AX_REG)
> continue;
>
> break;
> }
> return (i >= 12 && i <= 18);
> })
>
>
> (define_predicate "restore_multiple"
> (match_code "parallel")
> {
> const unsigned len = XVECLEN (op, 0);
> unsigned i;
>
> /* Starting from end of vector, count register restores. */
> for (i = 0; i < len; ++i)
> {
> rtx src, dest, addr;
> rtx e = XVECEXP (op, 0, len - 1 - i);
>
> if (GET_CODE (e) != SET)
> break;
>
> src = SET_SRC (e);
> dest = SET_DEST (e);
>
> if (!MEM_P (src) || !REG_P (dest))
> break;
>
> addr = XEXP (src, 0);
>
> /* Good if src address is in RSI. */
> if (REG_P (addr) && REGNO (addr) == SI_REG)
> continue;
>
> /* Good if src address is offset of RSI. */
> if (GET_CODE (addr) == PLUS
> && REG_P (XEXP (addr, 0))
> && REGNO (XEXP (addr, 0)) == SI_REG)
> continue;
>
> break;
> }
> return (i >= 12 && i <= 18);
> })
>
>
> Thanks,
> Daniel
>