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!