On Wed, 2021-01-27 at 08:58 +0100, Andreas Krebbel wrote:
> On 1/18/21 10:54 PM, Ilya Leoshkevich wrote:
> ...
> 
> > +static rtx_insn *
> > +s390_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs,
> > +               vec<machine_mode> &input_modes,
> > +               vec<const char *> &constraints, vec<rtx> &
> > /*clobbers*/,
> > +               HARD_REG_SET & /*clobbered_regs*/)
> > +{
> > +  if (!TARGET_VXE)
> > +    /* Long doubles are stored in FPR pairs - nothing to do.  */
> > +    return NULL;
> > +
> > +  rtx_insn *after_md_seq = NULL, *after_md_end = NULL;
> > +
> > +  unsigned ninputs = inputs.length ();
> > +  unsigned noutputs = outputs.length ();
> > +  for (unsigned i = 0; i < noutputs; i++)
> > +    {
> > +      if (GET_MODE (outputs[i]) != TFmode)
> > +   /* Not a long double - nothing to do.  */
> > +   continue;
> > +      const char *constraint = constraints[i];
> > +      bool allows_mem, allows_reg, is_inout;
> > +      bool ok = parse_output_constraint (&constraint, i, ninputs,
> > noutputs,
> > +                                    &allows_mem, &allows_reg,
> > &is_inout);
> > +      gcc_assert (ok);
> > +      if (strcmp (constraint, "=f") != 0)
> > +   /* Long double with a constraint other than "=f" - nothing to
> > do.  */
> > +   continue;
> 
> What about other constraint modifiers like & and %? Don't we need to
> handle matching constraints as
> well here?

Oh, right - we need to account for %?!*&# and maybe some others.  I'll
j
ust copy the code from parse_output_constraint() that skips over all
of
them, because I don't think they need any special handling - we just
nee
d to make sure they don't mess up the recognition of "=f".

I don't think we need to explicitly support matching constraints,
because parse_input_constraint() will resolve them for us.  I'll add
a test for this just in case.

Do we make use of multi-alternative constraints on s390?  I think not,
because our instructions are fairly rigid, but maybe I'm missing
something?

...

> > diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
> > index 0e3c31f5d4f..1332a65a1d1 100644
> > --- a/gcc/config/s390/vector.md
> > +++ b/gcc/config/s390/vector.md
> > @@ -616,12 +616,23 @@ (define_insn "*vec_tf_to_v1tf_vr"
> >     vlvgp\t%v0,%1,%N1"
> >    [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRR")])
> >  
> > -(define_insn "*fprx2_to_tf"
> > -  [(set (match_operand:TF               0 "nonimmediate_operand"
> > "=v")
> > -   (subreg:TF (match_operand:FPRX2 1 "general_operand"       "f")
> > 0))]
> > +(define_insn_and_split "fprx2_to_tf"
> > +  [(set (match_operand:TF               0 "nonimmediate_operand"
> > "=v,R")
> > +   (subreg:TF (match_operand:FPRX2 1
> > "general_operand"       "f,f") 0))]
> >    "TARGET_VXE"
> > -  "vmrhg\t%v0,%1,%N1"
> > -  [(set_attr "op_type" "VRR")])
> > +  "@
> > +   vmrhg\t%v0,%1,%N1
> > +   #"
> > +  "!(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))"
> > +  [(set (match_dup 2) (match_dup 3))
> > +   (set (match_dup 4) (match_dup 5))]
> > +{
> > +  operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode,
> > 0);
> > +  operands[3] = simplify_gen_subreg (DFmode, operands[1],
> > FPRX2mode, 0);
> > +  operands[4] = simplify_gen_subreg (DFmode, operands[0], TFmode,
> > 8);
> > +  operands[5] = simplify_gen_subreg (DFmode, operands[1],
> > FPRX2mode, 8);
> > +}
> > +  [(set_attr "op_type" "VRR,*")])
> 
> Splitting an address like this might cause the displacement to
> overflow in the second part. This
> would require an additional reg to make the address valid again.
> Which in turn will be a problem
> after reload. You can use the 'AR' constraint for the memory
> alternative. That way reload will make
> sure the address is offsetable.

Ok, thanks for the hint!

Reply via email to