On Wed, May 3, 2017 at 9:38 AM, Daniel Santos <daniel.san...@pobox.com> 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 >