From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id B16CC3858C54 for ; Wed, 15 Nov 2023 13:15:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B16CC3858C54 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linux.ibm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B16CC3858C54 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700054134; cv=none; b=XYopMdKUQI02y9hMl4fIfk5eVUFR6Cz8o8w6xNe+Ra/pTwmZZ0u4/JCmy0pKy01JIHojPvRHMxwKnIYHvC3fPiQxdMGUX1zb+vrzWhgxQ4FgAkSrSUNxWLj7L7WNDHqrUoq384w3UDYY/uY0ZF/PBckWUGG73b6M3XRD5SNnB2U= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700054134; c=relaxed/simple; bh=GvRjoh9baYPIbQbw8O28UGMCbV5iEGPUOe8ug9UC9YM=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=P/hvm7aCkZgpocJOf7vIeAH6Xj6Y/b3LOf+DNlZmn6W/9a/pLHDqbYxrrqVhDuuwStRCBlGn0NuEyrNGNx8/Y1VTvCE4SkCbNSdLc6f7VgQc5mccINnc7WSDZgxs5WY8/4P9hVy+aaTxZVb4RvQJ+p0C3MTX/AGDD+x0ZRW5WFY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3AFDEvCi014506 for ; Wed, 15 Nov 2023 13:15:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : subject : date : message-id : mime-version : content-transfer-encoding; s=pp1; bh=viIj93z7lZEqM3srwXUB1RpEVMmUWylVYqugn8OKaNY=; b=StUMv8IjbM8hNKqlUWbTxoBvhtIocR9Nb8b7fK7RmPhn12waIbeG/BlZ+3j1Bc6EJ2UP 4q1GF4NH53DUJBlNDL2cZb/oVJxTqVI6wPpv+1zkruIvSiQRhw5TBRLsoEQYFILisWA4 oto//hoT2+yN0p2wHU7a9dDSuJg+nZ9PsnV6SsmGdJ2uqzqaotfq2SRt0DY4OBy4hIit 8NwdnSFAL1auNCGpPeIdHYjD3EzsE0po4mLWkeXSCQXL9Ckc+xBBpCBl/dTgpyOscAe+ LIqQRU6XRWRT8zHN9mTiq9YxnfLxnIs09ClvaC/NWBbJgFv3XbIR3+g1h+ggzZxqSk+U gw== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3ucxq0r0rx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 15 Nov 2023 13:15:31 +0000 Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 3AFCYElW007904 for ; Wed, 15 Nov 2023 13:15:30 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 3uap5k6w0f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 15 Nov 2023 13:15:30 +0000 Received: from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com [10.20.54.103]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 3AFDFRup8847930 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 15 Nov 2023 13:15:27 GMT Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9DCB720043; Wed, 15 Nov 2023 13:15:27 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7F88B20040; Wed, 15 Nov 2023 13:15:27 +0000 (GMT) Received: from li-3a824ecc-34fe-11b2-a85c-eae455c7d911.ibm.com (unknown [9.152.222.38]) by smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTP; Wed, 15 Nov 2023 13:15:27 +0000 (GMT) From: Juergen Christ To: krebbel@linux.ibm.com, gcc-patches@gcc.gnu.org Subject: [PATCH] s390: implement flags output Date: Wed, 15 Nov 2023 14:15:25 +0100 Message-Id: <20231115131525.26166-1-jchrist@linux.ibm.com> X-Mailer: git-send-email 2.39.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-GUID: ipw6Tb9nEMHc5DR2d661W6m8IBu5yOPA X-Proofpoint-ORIG-GUID: ipw6Tb9nEMHc5DR2d661W6m8IBu5yOPA X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-15_12,2023-11-15_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 clxscore=1015 impostorscore=0 priorityscore=1501 mlxlogscore=780 adultscore=0 phishscore=0 bulkscore=0 mlxscore=0 spamscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311150102 X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Implement flags output for inline assemblies. Only use one output constraint that captures the whole condition code. No breakout into different condition codes is allowed. Also, only one condition code variable is allowed. Add further logic to canonicalize various cases where we combine different cases of possible condition codes. Bootstrapped and tested on s390. OK for mainline? gcc/ChangeLog: * config/s390/s390-c.cc (s390_cpu_cpp_builtins): Define __GCC_ASM_FLAG_OUTPUTS__. * config/s390/s390.cc (s390_canonicalize_comparison): More UNSPEC_CC_TO_INT cases. (s390_md_asm_adjust): Implement flags output. * config/s390/s390.md (ccstore4): Allow mask operands. * doc/extend.texi: Document flags output. gcc/testsuite/ChangeLog: * gcc.target/s390/ccor.c: New test. Signed-off-by: Juergen Christ --- gcc/config/s390/s390-c.cc | 1 + gcc/config/s390/s390.cc | 139 ++++++++++++++++++++++++++- gcc/config/s390/s390.md | 8 +- gcc/doc/extend.texi | 5 + gcc/testsuite/gcc.target/s390/ccor.c | 88 +++++++++++++++++ 5 files changed, 232 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/ccor.c diff --git a/gcc/config/s390/s390-c.cc b/gcc/config/s390/s390-c.cc index 269f4f8e978d..c126e6d323d7 100644 --- a/gcc/config/s390/s390-c.cc +++ b/gcc/config/s390/s390-c.cc @@ -409,6 +409,7 @@ s390_cpu_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__LONG_DOUBLE_128__"); cl_target_option_save (&opts, &global_options, &global_options_set); s390_cpu_cpp_builtins_internal (pfile, &opts, NULL); + cpp_define (pfile, "__GCC_ASM_FLAG_OUTPUTS__"); } #if S390_USE_TARGET_ATTRIBUTE diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 61c5f88de8af..a19dd7849b84 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -1877,6 +1877,97 @@ s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1, *code = new_code; } } + /* Remove UNSPEC_CC_TO_INT from connectives. This happens for + checks against multiple condition codes. */ + if (GET_CODE (*op0) == AND + && GET_CODE (XEXP (*op0, 0)) == UNSPEC + && XINT (XEXP (*op0, 0), 1) == UNSPEC_CC_TO_INT + && XVECLEN (XEXP (*op0, 0), 0) == 1 + && REGNO (XVECEXP (XEXP (*op0, 0), 0, 0)) == CC_REGNUM + && CONST_INT_P (XEXP (*op0, 1)) + && CONST_INT_P (*op1) + && INTVAL (XEXP (*op0, 1)) == -3 + && *code == EQ) + { + if (INTVAL (*op1) == 0) + { + /* case cc == 0 || cc = 2 => mask = 0xa */ + *op0 = XVECEXP (XEXP (*op0, 0), 0, 0); + *op1 = gen_rtx_CONST_INT (VOIDmode, 0xa); + } + else if (INTVAL (*op1) == 1) + { + /* case cc == 1 || cc == 3 => mask = 0x5 */ + *op0 = XVECEXP (XEXP (*op0, 0), 0, 0); + *op1 = gen_rtx_CONST_INT (VOIDmode, 0x5); + } + } + if (GET_CODE (*op0) == PLUS + && GET_CODE (XEXP (*op0, 0)) == UNSPEC + && XINT (XEXP (*op0, 0), 1) == UNSPEC_CC_TO_INT + && XVECLEN (XEXP (*op0, 0), 0) == 1 + && REGNO (XVECEXP (XEXP (*op0, 0), 0, 0)) == CC_REGNUM + && CONST_INT_P (XEXP (*op0, 1)) + && CONST_INT_P (*op1) + && (*code == LEU || *code == GTU)) + { + if (INTVAL (*op1) == 1) + { + if (INTVAL (XEXP (*op0, 1)) == -1) + { + /* case cc == 1 || cc == 2 => mask = 0x6 */ + *op0 = XVECEXP (XEXP (*op0, 0), 0, 0); + *op1 = gen_rtx_CONST_INT (VOIDmode, 0x6); + *code = *code == GTU ? NE : EQ; + } + else if (INTVAL (XEXP (*op0, 1)) == -2) + { + /* case cc == 2 || cc == 3 => mask = 0x3 */ + *op0 = XVECEXP (XEXP (*op0, 0), 0, 0); + *op1 = gen_rtx_CONST_INT (VOIDmode, 0x3); + *code = *code == GTU ? NE : EQ; + } + } + else if (INTVAL (*op1) == 2 + && INTVAL (XEXP (*op0, 1)) == -1) + { + /* case cc == 1 || cc == 2 || cc == 3 => mask = 0x7 */ + *op0 = XVECEXP (XEXP (*op0, 0), 0, 0); + *op1 = gen_rtx_CONST_INT (VOIDmode, 0x7); + *code = *code == GTU ? NE : EQ; + } + } + else if (*code == LEU || *code == GTU) + { + if (GET_CODE (*op0) == UNSPEC + && XINT (*op0, 1) == UNSPEC_CC_TO_INT + && XVECLEN (*op0, 0) == 1 + && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM + && CONST_INT_P (*op1)) + { + if (INTVAL (*op1) == 1) + { + /* case cc == 0 || cc == 1 => mask = 0xc */ + *op0 = XVECEXP (*op0, 0, 0); + *op1 = gen_rtx_CONST_INT (VOIDmode, 0xc); + *code = *code == GTU ? NE : EQ; + } + else if (INTVAL (*op1) == 2) + { + /* case cc == 0 || cc == 1 || cc == 2 => mask = 0xd */ + *op0 = XVECEXP (*op0, 0, 0); + *op1 = gen_rtx_CONST_INT (VOIDmode, 0xd); + *code = *code == GTU ? NE : EQ; + } + else if (INTVAL (*op1) == 3) + { + /* always true */ + *op0 = const0_rtx; + *op1 = const0_rtx; + *code = *code == GTU ? NE : EQ; + } + } + } /* Simplify cascaded EQ, NE with const0_rtx. */ if ((*code == NE || *code == EQ) @@ -17428,22 +17519,60 @@ static rtx_insn * s390_md_asm_adjust (vec &outputs, vec &inputs, vec &input_modes, vec &constraints, vec & /*clobbers*/, - HARD_REG_SET & /*clobbered_regs*/, location_t /*loc*/) + HARD_REG_SET &clobbered_regs, location_t loc) { - 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; + bool saw_cc = false; unsigned ninputs = inputs.length (); unsigned noutputs = outputs.length (); for (unsigned i = 0; i < noutputs; i++) { + const char *constraint = constraints[i]; + if (strncmp(constraint, "=@cc", 4) == 0) + { + if (constraint[4] != 0) + { + error_at (loc, "invalid cc output constraint: %qs", constraint); + continue; + } + if (saw_cc) + { + error_at (loc, "multiple cc output constraints not supported"); + continue; + } + if (TEST_HARD_REG_BIT(clobbered_regs, CC_REGNUM)) + { + error_at (loc, "% specifier for cc output conflicts with % clobber list"); + continue; + } + rtx dest = outputs[i]; + if (GET_MODE(dest) != SImode) + { + error ("invalid type for cc output constraint"); + continue; + } + saw_cc = true; + constraints[i] = "=c"; + outputs[i] = gen_rtx_REG (CCRAWmode, CC_REGNUM); + + push_to_sequence2 (after_md_seq, after_md_end); + emit_insn (gen_rtx_SET (dest, + gen_rtx_UNSPEC (SImode, + gen_rtvec (1, outputs[i]), + UNSPEC_CC_TO_INT))); + after_md_seq = get_insns (); + after_md_end = get_last_insn (); + end_sequence (); + continue; + } + if (!TARGET_VXE) + /* Long doubles are stored in FPR pairs - nothing to do. */ + continue; 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); diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 3e53a217d837..e432b2f708d7 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -6948,7 +6948,7 @@ [(set (match_operand:SI 0 "register_operand" "") (match_operator:SI 1 "s390_eqne_operator" [(match_operand 2 "cc_reg_operand") - (match_operand 3 "const0_operand")])) + (match_operand 3 "const_mask_operand")])) (clobber (reg:CC CC_REGNUM))])] "" "machine_mode mode = GET_MODE (operands[2]); @@ -6957,15 +6957,15 @@ rtx cond, ite; if (GET_CODE (operands[1]) == NE) - cond = gen_rtx_NE (VOIDmode, operands[2], const0_rtx); + cond = gen_rtx_NE (VOIDmode, operands[2], operands[3]); else - cond = gen_rtx_EQ (VOIDmode, operands[2], const0_rtx); + cond = gen_rtx_EQ (VOIDmode, operands[2], operands[3]); ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx); emit_insn (gen_rtx_SET (operands[0], ite)); } else { - if (mode != CCZ1mode) + if (mode != CCZ1mode || operands[3] != const0_rtx) FAIL; emit_insn (gen_sne (operands[0], operands[2])); if (GET_CODE (operands[1]) == EQ) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a3db9423ce66..1b1468fc1a5f 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -10788,6 +10788,11 @@ sign flag set ``not'' @var{flag}, or inverted versions of those above @end table +@item s390 +The flag output constraint for s390 is @samp{=@@cc}. Only one such +constraint is allowed. The variable has to be stored in a @samp{int} +variable. + @end table @anchor{InputOperands} diff --git a/gcc/testsuite/gcc.target/s390/ccor.c b/gcc/testsuite/gcc.target/s390/ccor.c new file mode 100644 index 000000000000..31f30f60314e --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/ccor.c @@ -0,0 +1,88 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +#define GENFUN1(C) \ + int foo_ ##C(int x) \ + { \ + int cc; \ + asm volatile ("ahi %[x],42\n" \ + : [x] "+d"(x), "=@cc" (cc)); \ + return cc == C ? 42 : 0; \ + } + +#define GENFUN2(C1,C2) \ + int foo_ ##C1##C2(int x) \ + { \ + int cc; \ + asm volatile ("ahi %[x],42\n" \ + : [x] "+d"(x), "=@cc" (cc)); \ + return cc == C1 || cc == C2 ? 42 : 0; \ + } + +#define GENFUN3(C1,C2,C3) \ + int foo_ ##C1##C2##C3(int x) \ + { \ + int cc; \ + asm volatile ("ahi %[x],42\n" \ + : [x] "+d"(x), "=@cc" (cc)); \ + return cc == C1 || cc == C2 || cc == C3 ? 42 : 0; \ + } + +GENFUN1(0) + +/* { dg-final { scan-assembler {locrne} } } */ + +GENFUN1(1) + +/* { dg-final { scan-assembler {locrnl} } } */ + +GENFUN1(2) + +/* { dg-final { scan-assembler {locrnh} } } */ + +GENFUN1(3) + +/* { dg-final { scan-assembler {locrno} } } */ + +GENFUN2(0,1) + +/* { dg-final { scan-assembler {locrnle} } } */ + +GENFUN2(0,2) + +/* { dg-final { scan-assembler {locrhe} } } */ + +GENFUN2(0,3) + +/* currently unoptimized */ + +GENFUN2(1,2) + +/* { dg-final { scan-assembler {locrnlh} } } */ + +GENFUN2(1,3) + +/* { dg-final { scan-assembler {locrnhe} } } */ + +GENFUN2(2,3) + +/* { dg-final { scan-assembler {locrle} } } */ + +GENFUN3(0,1,2) + +/* { dg-final { scan-assembler {locrh} } } */ + +GENFUN3(0,1,3) + +/* currently unoptimized */ + +GENFUN3(0,2,3) + +/* currently unoptimized */ + +GENFUN3(1,2,3) + +/* { dg-final { scan-assembler {locre} } } */ + +/* for the unoptimized cases, we get an ipm */ +/* { dg-final { scan-assembler-times {ipm} 3 } } */ -- 2.39.3