| Message ID | patch-20449-tamar@arm.com |
|---|---|
| State | New |
| Headers |
Return-Path: <gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id A776D4BA5436 for <patchwork@sourceware.org>; Wed, 8 Apr 2026 08:20:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A776D4BA5436 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=YHVzjkiC; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=YHVzjkiC X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from DUZPR83CU001.outbound.protection.outlook.com (mail-northeuropeazon11012058.outbound.protection.outlook.com [52.101.66.58]) by sourceware.org (Postfix) with ESMTPS id 966D24BA5436 for <gcc-patches@gcc.gnu.org>; Wed, 8 Apr 2026 08:19:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 966D24BA5436 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 966D24BA5436 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=52.101.66.58 ARC-Seal: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1775636379; cv=pass; b=LavYJsnJl7s58b/XeTU7hAaUFDgdkSXd/oTLoyhjklNY1ozcyFpmSWrDWVUMthqLg/gJhB8nrdt1Np4a/tkzmJdn4uhpqH3CJIfrSaRY1bfP5hocApX4cuYoTXHJNG1buqgm0V+RJFYbFFYf1C+5lqArqikpZDKCOPdr4orN7J0= ARC-Message-Signature: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1775636379; c=relaxed/simple; bh=8LSzYI1R6K3jTAm58rbVo6g5rQ1JtceH2pDm751v3T0=; h=DKIM-Signature:DKIM-Signature:Date:From:To:Subject:Message-ID: MIME-Version; b=CRiE7NXxagUy0o40IveRhcWR0aCrXK5RcFi44o6x9SixNKmoeBlISejEy1tHZcWbejZc06TURFzfCmGuu8X0pRVEGaK+wv0YOx/Jf6r5Y66n5C0HXK4wPJUiIlmae6sAU6g7tzWJTqS4PxztQ2DIgxqHzFiqWg2uj6tJ+/PVUdw= ARC-Authentication-Results: i=3; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 966D24BA5436 ARC-Seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=t1FYElTUOeYllKb7+0Ibm2ZgDJgegTB9Zi+bRHJyy0KT2yIiK/W32oQS6vET1aAUZqx1MSnQqcg6j8kWI2zvvqFukaVwsDtgKWedA50uuzLKw+RkM5MmeWfAo1rIqQtL6X+Hy7+U2YTPoWiUqCPjIlKslQwrzG3LGCSuMVNV2rxphwoyOZYl/jqb0tZkMeIh75Y0k0dmMz4eohq6SIUH05kHWkbl4VTEcUtr+osk3IyjI58NrsTI6fP1Hc4H9+TTiqjgYsKuYT5EcREpMb7MCfUDNcCuDd/kxZ6K08VIVMbUNphCJsAZLr5/N2RxeeyzcGhpYHKzFAtUGBqLfYRb0w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=g6CNMEP1jR2FEEikZZ7YN+q3gDNZ9ljDpuXD84otWnY=; b=w8YXeSFGY7LuviILqObJHVeU4DEh66Phaz6+UgJOv2hh26QQDm90k5u9qpL8IFC64fvHhjGjh8nivA7iXsdLC6djOTAWPY4Wa1MHsT3Ie2r/CWNijvBPGE8vicUuIE4XcK7mnO5v9Uyil/ALbsA++UC8c2FLYz0pIajC4u9eOrdsL0xEr/EkXpsUuRTPGmglVXGSQUAJzBqhPbAZpeW1tQVPZeRqPIinWlQWLbQpc3xaFaXarezgcQUJGTp5H5SgjFauRstdZDavaRQIkBMW2kWd9FpvkJwDOioLlXi2ZtEFAmJcBgMc7+q63wgqiG5q4TrjCcCV8svt9w5xpT8BCQ== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com]) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=g6CNMEP1jR2FEEikZZ7YN+q3gDNZ9ljDpuXD84otWnY=; b=YHVzjkiC1s+8Ha+z+eqHt72IfkYiL2AoagbuN1U0wO+CgLuOPoNxDfF4OxJRw9jOE3ftnNnJx+VYwJKYZGAy20xFriPhcDU13M1dVSt8SDZLeyZNMq73cM3lVM9EJ0SrDhc9i/q8IdidwBhvqnZbQ+y2I3oh7Z/jkBI70pAm2O0= Received: from DU2P250CA0030.EURP250.PROD.OUTLOOK.COM (2603:10a6:10:231::35) by AS8PR08MB7743.eurprd08.prod.outlook.com (2603:10a6:20b:524::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17; Wed, 8 Apr 2026 08:19:29 +0000 Received: from DB5PEPF00014B98.eurprd02.prod.outlook.com (2603:10a6:10:231:cafe::b4) by DU2P250CA0030.outlook.office365.com (2603:10a6:10:231::35) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9769.32 via Frontend Transport; Wed, 8 Apr 2026 08:19:26 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 4.158.2.129) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=arm.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 4.158.2.129 as permitted sender) receiver=protection.outlook.com; client-ip=4.158.2.129; helo=outbound-uk1.az.dlp.m.darktrace.com; pr=C Received: from outbound-uk1.az.dlp.m.darktrace.com (4.158.2.129) by DB5PEPF00014B98.mail.protection.outlook.com (10.167.8.165) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9769.17 via Frontend Transport; Wed, 8 Apr 2026 08:19:27 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Jdv8ZEakRpauKdjxJCC+5OjkqCs6p4mHSwQ3C/2PoNgJ7O2Y5eoaCC/02oabLGlLsrq/yidHOtpRG3FaQy9w8ae5U4Kb64wFJD9PiWbTz/LvjbUOXA1hdoFNYuSSzNb1L1HKevyEP0qRJaef+ZEbg6NklDH5UUExDxTuFfMzABJgyPFoeNrMiJwS4cR8oJcyYHpP3w6rfl13i3YnfUdJldtXdvTd89wucAuQMqagOyTi6hfYa0n3LQVpr2Bc8yreb6U9vJ5TweOPnYgJWoMMDtzGGZQMg4Ik7K9zXVk0rrhEBYw4V2VQi5tF0gGuxR0SigJOt58M3delYYcKRv6nxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=g6CNMEP1jR2FEEikZZ7YN+q3gDNZ9ljDpuXD84otWnY=; b=vaObbgl8zQtYd4CFbSkvwDLuOuNdQSiN4lRL25szEluSdEwKZH0/dDLYWCkWNkTQO54Lk7/NocJ5zkJyPNfqebjE2dwf7BoS+NT2ta8RA+oHopXO3iUpM3ZHwCfClowKH+BXKnY7aY8pqAg1vlWusuj5MK87Ie3I1rj6RtM2LHLuTbWTcvNEOHcLc5zY4EvM7UNPy34I40/2GhKju/hbssefl6IHKCYogpf6DsbQT0fOBqiuDOvbhpWFyc4OHngWmGwDXkCrjGzeqU8c4yiPU4MnSjuJgMtri/8fYI4NZKdU6uE1TbhZ9eDaMI3jdKThaflHdMPo6YgcVU+fLYMtFQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=g6CNMEP1jR2FEEikZZ7YN+q3gDNZ9ljDpuXD84otWnY=; b=YHVzjkiC1s+8Ha+z+eqHt72IfkYiL2AoagbuN1U0wO+CgLuOPoNxDfF4OxJRw9jOE3ftnNnJx+VYwJKYZGAy20xFriPhcDU13M1dVSt8SDZLeyZNMq73cM3lVM9EJ0SrDhc9i/q8IdidwBhvqnZbQ+y2I3oh7Z/jkBI70pAm2O0= Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from VI0PR08MB10392.eurprd08.prod.outlook.com (2603:10a6:800:210::10) by DB9PR08MB8626.eurprd08.prod.outlook.com (2603:10a6:10:3d2::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17; Wed, 8 Apr 2026 08:18:22 +0000 Received: from VI0PR08MB10392.eurprd08.prod.outlook.com ([fe80::cd7c:e19a:2072:75cc]) by VI0PR08MB10392.eurprd08.prod.outlook.com ([fe80::cd7c:e19a:2072:75cc%4]) with mapi id 15.20.9769.014; Wed, 8 Apr 2026 08:18:21 +0000 Date: Wed, 8 Apr 2026 09:18:19 +0100 From: Tamar Christina <tamar.christina@arm.com> To: gcc-patches@gcc.gnu.org Cc: nd@arm.com, rguenther@suse.de, jeffreyalaw@gmail.com, rdapp.gcc@gmail.com, ktkachov@nvidia.com, richard.earnshaw@arm.com Subject: [PATCH 1/2][RFC][GCC 17][middle-end: Supporting multi character string formatters Message-ID: <patch-20449-tamar@arm.com> Content-Type: multipart/mixed; boundary="cZpxLGRPvr7wu1Ql" Content-Disposition: inline X-ClientProxiedBy: PR1P264CA0146.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:346::11) To VI0PR08MB10392.eurprd08.prod.outlook.com (2603:10a6:800:210::10) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: VI0PR08MB10392:EE_|DB9PR08MB8626:EE_|DB5PEPF00014B98:EE_|AS8PR08MB7743:EE_ X-MS-Office365-Filtering-Correlation-Id: 83e02fbe-175f-4bdf-f7c2-08de95478d29 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; ARA:13230040|6049299003|376014|1800799024|366016|4053099003|56012099003|18002099003; X-Microsoft-Antispam-Message-Info-Original: 2YTkkpH/1jS2zK6/ldoiK06dptAT7lG4Y6z1rKhfUkcw2LW3NSRDt22UjHYW3NiMWhuCHDc9csyfpdOm8Q29+yqkfUlz7dRJCf9NiNzeuA5FzuYCSaA2uQMAwo5CrpLWSMT8s6vaPRcxtOhnIgeu3TVsyuUuyEn1H49vOTxUa9whsK6g0FrUPnFi1LqNW7ElShreOqO2//oC10Zo9cQFxmNKpQ4e/3kUH5yTx1NC+N0GagpxvN8PPzV9sdGc+GdBaTFirOmODdfsMDoyVmgA8axCEifaFO5j8XOKcKDzY0k13Nw/IPrWLx243GFWy6VjcX+CAMkSM4uNYPH4yfn5h4YhcGqUpPoV8JbvrjZI3k/J2V+QHTAZNY/Z43y84UmvPgsCnnwEYgyXlIUAYOyQLHojKQynXyKgjkB6oaCccsNakxNB57UWe9cxN6Ir+cSPhgXBKnKyL9c1rz1LAf3NZ+0DSqTBa++iAP5yzebdPz9DV2GflTxUQAZcPSC1IF3Ia5RRPkGYH/3zivKgY8yTXD6mkF2mvIVw+WOpP0aKsGrjx+OhWkLoyZ9PwrHSQH8khau3U65yiXhnduY4sLSJ8s+ZsxBp94SPsdWpmRFQiJLeQ0PXhKE0v3T56t6iOVPZLml2+pGi6L+CANVlzj/PLCPsZc3A3u0sDZXLatjnOM7x4pJa31jr7k3/eUQI5xIqp4Eq9zIxhcl185hiHaBwIjNkFr7t6R5EdqFl+x5bYEY= X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI0PR08MB10392.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(6049299003)(376014)(1800799024)(366016)(4053099003)(56012099003)(18002099003); DIR:OUT; SFP:1101; X-Exchange-RoutingPolicyChecked: DG1AH+A5oECSpYw91TVs3rVm1euwXDiL2bE3TuF7EsysctZKVoTOf6Ysd52gb8Caw07AQJued0Pnz6fKqK51yT4BSHXxj6V6fadpELmX6mNEcdJP8shGF2lb8/iwppgSWyRvbwTEPhqGOeKvTu8i7yWNWmfPEU5UseVknQL2FZXRoRtK64QtX2N6RORQ+7BDJbFeugVbPztNJ8JvycPwvfPSHCz+80VMbfmpdW5JZYJxWa/K63BL/VaoEMZ76jYDQOXSucV7LCW5WHT4uYJQKnRfIhE2Ixmswe7tXKd1CN0PevSu4UWiHSD7XyJ8S51wFYElvLa5ruEr06pYCcQhbg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB8626 X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: DB5PEPF00014B98.eurprd02.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 87bbc577-0072-4d65-dd41-08de95476559 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|1800799024|82310400026|36860700016|14060799003|6049299003|35042699022|4053099003|56012099003|18002099003; X-Microsoft-Antispam-Message-Info: Z9RPN7cZ1d/IBZhmwEfNfF1qfrOXgzavAXVQSC8TFVBT85SHLMT7FHEgM3fniUDqjhkRNHEhuc6T/AB8yKvKK9O0UW8t8ysIyDmryCovxMu0TRc/go7QcFJePtZ/6Ek6fGtvx7KNOedZi8rLDLSlSwawsNyYxYo0IAFy+ZALhfe4b5jI5t48P6aDM5S91iAfJ9kdOMu3II/krOhDEnPzGJK6buV21BzyvXhSFi/SCwoyEn2mOKQnuEgkHF8A2E5c5AgDzxevemc9oS6RAGoY0BVod2fcsMMlYBd6PLi9DyIq3sxOI8o/0WDduX5FwvDySH98msRAfQumWCFwQ4qSoCpBfIOzqvGIxjFFkMAgb/88iSIUl1tsWa6NdN+Yh91mk3mGb6NJeb8jFp5MVIP9olom57dXPJ91H1K9qbjZ/oY2k137m8RxaXmvpvEOYhB5kqTjBYYIec+EMMEn20KFXKRwU/albMieKh8vJU035vLWFhizsqSk8TP3AbQ/A0nMz/m9BdyFQ7I6j2rQtXfAWdE/BRYZ6D1Xzvv8/63E1JPAkmqH5clLjCl2g5sXuOoTcOQ5JrUvQzSc0sEVYXFZrBAsk1g9lyD+BoL+Sbw5Om1G1uYL8V9hm9zSnlVTvNT9TcpjddDnCZZJZRKbGf2S9wvjo8J8eaRQYQJqzZp2ZYoBsGkDJKKsefrIdJoEke436tjX6XRx2PEiw2LwFQukzwK0t9gkJLricR/uyuMi4yQslxxsnDH0khUvnbJj32usobCoAKRsCtHhKxvPo+l42w== X-Forefront-Antispam-Report: CIP:4.158.2.129; CTRY:GB; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:outbound-uk1.az.dlp.m.darktrace.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(376014)(1800799024)(82310400026)(36860700016)(14060799003)(6049299003)(35042699022)(4053099003)(56012099003)(18002099003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: vfBg93k9wDJP4F31OIK6gvIJK0iU7skkG0I8vfEuczTp+WyZ6mmO6oijY2dyJTlKP9kUa+43/PS9SuRoops3z5MpQwkAsd1P4d/AvciPikjv9Y09VIYg+/EuVlzopjx8+RWfJNGrNpgLErzt9fUHVLdGBuK2LSqxOkWN93P+ovdCp5DUvbA/h968SFJ801Y9KrKmeyN3yJuN7CxXppQv2uIUghnYoOWtjGQ6B7ygoWr6pb8rbAvj5zz3MLKDPYDCjEt5pBxRkt7TgFPXp3MBKTJBVQbPn+f6Dyv9qer4Cmsxf0QVYh9ZYfRi83Bw/CAEywYLkl9lPSH6NjlvxRLOdIVT7efxiLvBL/8+vuipoZpASM1mxbBB3ta1gfBbhiklmKHGGN9s9LnjgK+x63pNAm8QiRni9LfskkhLTNAIyp+qZV31XQwMrTQJp4QoK1/M X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Apr 2026 08:19:27.5634 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 83e02fbe-175f-4bdf-f7c2-08de95478d29 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[4.158.2.129]; Helo=[outbound-uk1.az.dlp.m.darktrace.com] X-MS-Exchange-CrossTenant-AuthSource: DB5PEPF00014B98.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB7743 X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FORGED_SPF_HELO, GIT_PATCH_0, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org |
| Series |
[1/2,RFC,17] [middle-end: Supporting multi character string formatters
|
|
Commit Message
Tamar Christina
April 8, 2026, 8:18 a.m. UTC
Today asm print operands are required to be single characters. This means we're
quite limited in the number of them we can have and they are threated as white
gold in many backends.
This causes us to have to do some hack solutions in the backends for instance to
support some SME operations just to avoid new print operands.
This patch extends the parsers to support multiple token operands and extends
the print_operand target hook to pass a pointer to the buffer being read so the
backend can consume as many tokens as it needs.
As a consequence backends are completely free to choose how their multi letter
operands look like.
There will need to be a mechanical change in all targets doing
int code = p ? (unsigned char)**p : 0;
to support this new interface.
There is one restriction in that whatever the backends choose should not overlap
with assembler dialect support. This means that %{, &|, %} are reserved.
I am wondering however if there is apetite to try to see if we can standardise
on a syntax for multi character operands or whether we shouldn't try.
One possible way is to do what we do for constraints, where you specify a letter
to start the multi letter parsing and a fixed number of character to parse.
However this is annoying as it still makes us make cryptic names.
In the AArch64 example patch I chose %[..] so e.g. %[SME_VC]0 but I don't quite
like it. I could do instead %SME_VC:0? i.e. if the character following the
current one isn't a digit, consume until a : is found.
Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
Thoughts?
Thanks,
Tamar
gcc/ChangeLog:
* target.def (print_operand): Modify with new pointer.
* targhooks.cc (default_print_operand): Update using pointer.
* targhooks.h (default_print_operand): Likewise.
* config/aarch64/aarch64.cc (aarch64_print_operand): Update
* final.cc (output_asm_insn): Update to new target hook format.
(output_operand): Likewise.
* output.h (output_operand): Likewise.
---
--
Comments
On 08/04/2026 09:18, Tamar Christina wrote: > Today asm print operands are required to be single characters. This means we're > quite limited in the number of them we can have and they are threated as white > gold in many backends. > > This causes us to have to do some hack solutions in the backends for instance to > support some SME operations just to avoid new print operands. > > This patch extends the parsers to support multiple token operands and extends > the print_operand target hook to pass a pointer to the buffer being read so the > backend can consume as many tokens as it needs. > > As a consequence backends are completely free to choose how their multi letter > operands look like. > > There will need to be a mechanical change in all targets doing > > int code = p ? (unsigned char)**p : 0; > > to support this new interface. > > There is one restriction in that whatever the backends choose should not overlap > with assembler dialect support. This means that %{, &|, %} are reserved. > > I am wondering however if there is apetite to try to see if we can standardise > on a syntax for multi character operands or whether we shouldn't try. > > One possible way is to do what we do for constraints, where you specify a letter > to start the multi letter parsing and a fixed number of character to parse. > > However this is annoying as it still makes us make cryptic names. > > In the AArch64 example patch I chose %[..] so e.g. %[SME_VC]0 but I don't quite > like it. I could do instead %SME_VC:0? i.e. if the character following the > current one isn't a digit, consume until a : is found. > > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. > This would be a nice improvement. We currently have an int for the code, but only use a limited set of ascii values with that. Did you consider having a mapping function that could read the extended formats and convert it to an int code for the extended values? That would mean you wouldn't need to touch backends that haven't added the parsing hook and would provide separation between reading a string code and the backend processing of the value: the default hook would simply read a char as before. Something like: else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned char) *p)) - output_operand (NULL_RTX, *p++); + output_operand (NULL_RTX, targetm.asm_out.print_operand_punct_code (&p); else ... Any code above, say, 255 could be used by a backend. What's more, most existing code that passes a hard-coded letter wouldn't need changing at all. R. > Thoughts? > > Thanks, > Tamar > > gcc/ChangeLog: > > * target.def (print_operand): Modify with new pointer. > * targhooks.cc (default_print_operand): Update using pointer. > * targhooks.h (default_print_operand): Likewise. > * config/aarch64/aarch64.cc (aarch64_print_operand): Update > * final.cc (output_asm_insn): Update to new target hook format. > (output_operand): Likewise. > * output.h (output_operand): Likewise. > > --- > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > index 1902a4ee9fa34a1f00e654760d0759af1d6cf432..1bf54641f581e90bb629d2fcd2f0d32a2c9474f9 100644 > --- a/gcc/config/aarch64/aarch64.cc > +++ b/gcc/config/aarch64/aarch64.cc > @@ -13009,9 +13009,10 @@ sizetochar (int size) > 'z': Output address of a typical LDP or STP. */ > > static void > -aarch64_print_operand (FILE *f, rtx x, int code) > +aarch64_print_operand (FILE *f, rtx x, const char * const *p) > { > rtx elt; > + int code = p ? (unsigned char)**p : 0; > switch (code) > { > case 'c': > diff --git a/gcc/final.cc b/gcc/final.cc > index b5e8c6e2efde01417370e7dea5456ba108b866ed..fcb8877f8814c4594f3a4ddc0da03e631653caf4 100644 > --- a/gcc/final.cc > +++ b/gcc/final.cc > @@ -3508,6 +3508,7 @@ output_asm_insn (const char *templ, rtx *operands) > the TARGET_PRINT_OPERAND hook can define them. */ > else if (ISALPHA (*p)) > { > + const char *p_init = p; > int letter = *p++; > unsigned long opnum; > char *endptr; > @@ -3535,7 +3536,7 @@ output_asm_insn (const char *templ, rtx *operands) > if (letter2 == 'c' || CONSTANT_ADDRESS_P (operands[opnum])) > output_addr_const (asm_out_file, operands[opnum]); > else > - output_operand (operands[opnum], 'c'); > + output_operand (operands[opnum], &p_init); > } > else if (letter == 'n') > { > @@ -3549,7 +3550,7 @@ output_asm_insn (const char *templ, rtx *operands) > } > } > else > - output_operand (operands[opnum], letter); > + output_operand (operands[opnum], &p_init); > > if (!opoutput[opnum]) > oporder[ops++] = opnum; > @@ -3585,7 +3586,10 @@ output_asm_insn (const char *templ, rtx *operands) > punctuation character alone, with no operand. The > TARGET_PRINT_OPERAND hook decides what is actually done. */ > else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned char) *p)) > - output_operand (NULL_RTX, *p++); > + { > + const char *ptr = p++; > + output_operand (NULL_RTX, &ptr); > + } > else > output_operand_lossage ("invalid %%-code"); > break; > @@ -3651,7 +3655,7 @@ mark_symbol_refs_as_used (rtx x) > by TARGET_PRINT_OPERAND. */ > > void > -output_operand (rtx x, int code ATTRIBUTE_UNUSED) > +output_operand (rtx x, const char * const *p ATTRIBUTE_UNUSED) > { > if (x && GET_CODE (x) == SUBREG) > x = alter_subreg (&x, true); > @@ -3660,7 +3664,7 @@ output_operand (rtx x, int code ATTRIBUTE_UNUSED) > if (!targetm.no_register_allocation) > gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER); > > - targetm.asm_out.print_operand (asm_out_file, x, code); > + targetm.asm_out.print_operand (asm_out_file, x, p); > > if (x == NULL_RTX) > return; > diff --git a/gcc/output.h b/gcc/output.h > index 1f628ea2371aeca006d686e521a04d4f7ddb6e2d..101f4f8ed14808f37ab455e2cb9e68a3edd237f3 100644 > --- a/gcc/output.h > +++ b/gcc/output.h > @@ -79,7 +79,7 @@ extern rtx_insn *final_scan_insn (rtx_insn *, FILE *, int, int, int *); > extern rtx alter_subreg (rtx *, bool); > > /* Print an operand using machine-dependent assembler syntax. */ > -extern void output_operand (rtx, int); > +extern void output_operand (rtx, const char * const *); > > /* Report inconsistency between the assembler template and the operands. > In an `asm', it's the user's fault; otherwise, the compiler's fault. */ > diff --git a/gcc/target.def b/gcc/target.def > index 206c94f8749ba8f242229d36da0049826c342502..793f64da9c0abb4ca470e6e9be0cd5eb1a859886 100644 > --- a/gcc/target.def > +++ b/gcc/target.def > @@ -892,7 +892,7 @@ return @code{true}.", > DEFHOOK_UNDOC > (print_operand, > "", > - void, (FILE *file, rtx x, int code), > + void, (FILE *file, rtx x, const char * const * p), > default_print_operand) > > /* Emit a machine-specific memory address. */ > diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc > index 5f1eac75122c9cc945012a02426784f6c2584328..63cefae50f8854992b3fb7d5ad8a32cf9511208a 100644 > --- a/gcc/targhooks.cc > +++ b/gcc/targhooks.cc > @@ -390,7 +390,7 @@ hook_callee_copies_named (cumulative_args_t, const function_arg_info &arg) > > void > default_print_operand (FILE *stream ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, > - int code ATTRIBUTE_UNUSED) > + const char * const *p ATTRIBUTE_UNUSED) > { > #ifdef PRINT_OPERAND > PRINT_OPERAND (stream, x, code); > diff --git a/gcc/targhooks.h b/gcc/targhooks.h > index 9582233e69fee1b56ab9d2f2573707621f9837ff..3031e08e84e7f1401d0fd08bf8e16c37f78c98c9 100644 > --- a/gcc/targhooks.h > +++ b/gcc/targhooks.h > @@ -74,7 +74,7 @@ extern bool hook_pass_by_reference_must_pass_in_stack > extern bool hook_callee_copies_named > (cumulative_args_t ca, const function_arg_info &); > > -extern void default_print_operand (FILE *, rtx, int); > +extern void default_print_operand (FILE *, rtx, const char * const *); > extern void default_print_operand_address (FILE *, machine_mode, rtx); > extern bool default_print_operand_punct_valid_p (unsigned char); > extern tree default_mangle_assembler_name (const char *); > >
On Wed, 8 Apr 2026, Richard Earnshaw (foss) wrote: > On 08/04/2026 09:18, Tamar Christina wrote: > > Today asm print operands are required to be single characters. This means we're > > quite limited in the number of them we can have and they are threated as white > > gold in many backends. > > > > This causes us to have to do some hack solutions in the backends for instance to > > support some SME operations just to avoid new print operands. > > > > This patch extends the parsers to support multiple token operands and extends > > the print_operand target hook to pass a pointer to the buffer being read so the > > backend can consume as many tokens as it needs. > > > > As a consequence backends are completely free to choose how their multi letter > > operands look like. > > > > There will need to be a mechanical change in all targets doing > > > > int code = p ? (unsigned char)**p : 0; > > > > to support this new interface. > > > > There is one restriction in that whatever the backends choose should not overlap > > with assembler dialect support. This means that %{, &|, %} are reserved. > > > > I am wondering however if there is apetite to try to see if we can standardise > > on a syntax for multi character operands or whether we shouldn't try. > > > > One possible way is to do what we do for constraints, where you specify a letter > > to start the multi letter parsing and a fixed number of character to parse. > > > > However this is annoying as it still makes us make cryptic names. > > > > In the AArch64 example patch I chose %[..] so e.g. %[SME_VC]0 but I don't quite > > like it. I could do instead %SME_VC:0? i.e. if the character following the > > current one isn't a digit, consume until a : is found. > > > > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. > > > > This would be a nice improvement. > > We currently have an int for the code, but only use a limited set of ascii values with that. Did you consider having a mapping function that could read the extended formats and convert it to an int code for the extended values? That would mean you wouldn't need to touch backends that haven't added the parsing hook and would provide separation between reading a string code and the backend processing of the value: the default hook would simply read a char as before. > > Something like: > else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned char) *p)) > - output_operand (NULL_RTX, *p++); > + output_operand (NULL_RTX, targetm.asm_out.print_operand_punct_code (&p); Or add &p as extra arg to the valid_p hook. Or make targetm.asm_out.print_operand_punct_code return single-char code as well and hopefully reserved -1 or 0 as error. Richard. > else > ... > > Any code above, say, 255 could be used by a backend. > > What's more, most existing code that passes a hard-coded letter wouldn't need changing at all. > > R. > > > Thoughts? > > > > Thanks, > > Tamar > > > > gcc/ChangeLog: > > > > * target.def (print_operand): Modify with new pointer. > > * targhooks.cc (default_print_operand): Update using pointer. > > * targhooks.h (default_print_operand): Likewise. > > * config/aarch64/aarch64.cc (aarch64_print_operand): Update > > * final.cc (output_asm_insn): Update to new target hook format. > > (output_operand): Likewise. > > * output.h (output_operand): Likewise. > > > > --- > > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > > index 1902a4ee9fa34a1f00e654760d0759af1d6cf432..1bf54641f581e90bb629d2fcd2f0d32a2c9474f9 100644 > > --- a/gcc/config/aarch64/aarch64.cc > > +++ b/gcc/config/aarch64/aarch64.cc > > @@ -13009,9 +13009,10 @@ sizetochar (int size) > > 'z': Output address of a typical LDP or STP. */ > > > > static void > > -aarch64_print_operand (FILE *f, rtx x, int code) > > +aarch64_print_operand (FILE *f, rtx x, const char * const *p) > > { > > rtx elt; > > + int code = p ? (unsigned char)**p : 0; > > switch (code) > > { > > case 'c': > > diff --git a/gcc/final.cc b/gcc/final.cc > > index b5e8c6e2efde01417370e7dea5456ba108b866ed..fcb8877f8814c4594f3a4ddc0da03e631653caf4 100644 > > --- a/gcc/final.cc > > +++ b/gcc/final.cc > > @@ -3508,6 +3508,7 @@ output_asm_insn (const char *templ, rtx *operands) > > the TARGET_PRINT_OPERAND hook can define them. */ > > else if (ISALPHA (*p)) > > { > > + const char *p_init = p; > > int letter = *p++; > > unsigned long opnum; > > char *endptr; > > @@ -3535,7 +3536,7 @@ output_asm_insn (const char *templ, rtx *operands) > > if (letter2 == 'c' || CONSTANT_ADDRESS_P (operands[opnum])) > > output_addr_const (asm_out_file, operands[opnum]); > > else > > - output_operand (operands[opnum], 'c'); > > + output_operand (operands[opnum], &p_init); > > } > > else if (letter == 'n') > > { > > @@ -3549,7 +3550,7 @@ output_asm_insn (const char *templ, rtx *operands) > > } > > } > > else > > - output_operand (operands[opnum], letter); > > + output_operand (operands[opnum], &p_init); > > > > if (!opoutput[opnum]) > > oporder[ops++] = opnum; > > @@ -3585,7 +3586,10 @@ output_asm_insn (const char *templ, rtx *operands) > > punctuation character alone, with no operand. The > > TARGET_PRINT_OPERAND hook decides what is actually done. */ > > else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned char) *p)) > > - output_operand (NULL_RTX, *p++); > > + { > > + const char *ptr = p++; > > + output_operand (NULL_RTX, &ptr); > > + } > > else > > output_operand_lossage ("invalid %%-code"); > > break; > > @@ -3651,7 +3655,7 @@ mark_symbol_refs_as_used (rtx x) > > by TARGET_PRINT_OPERAND. */ > > > > void > > -output_operand (rtx x, int code ATTRIBUTE_UNUSED) > > +output_operand (rtx x, const char * const *p ATTRIBUTE_UNUSED) > > { > > if (x && GET_CODE (x) == SUBREG) > > x = alter_subreg (&x, true); > > @@ -3660,7 +3664,7 @@ output_operand (rtx x, int code ATTRIBUTE_UNUSED) > > if (!targetm.no_register_allocation) > > gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER); > > > > - targetm.asm_out.print_operand (asm_out_file, x, code); > > + targetm.asm_out.print_operand (asm_out_file, x, p); > > > > if (x == NULL_RTX) > > return; > > diff --git a/gcc/output.h b/gcc/output.h > > index 1f628ea2371aeca006d686e521a04d4f7ddb6e2d..101f4f8ed14808f37ab455e2cb9e68a3edd237f3 100644 > > --- a/gcc/output.h > > +++ b/gcc/output.h > > @@ -79,7 +79,7 @@ extern rtx_insn *final_scan_insn (rtx_insn *, FILE *, int, int, int *); > > extern rtx alter_subreg (rtx *, bool); > > > > /* Print an operand using machine-dependent assembler syntax. */ > > -extern void output_operand (rtx, int); > > +extern void output_operand (rtx, const char * const *); > > > > /* Report inconsistency between the assembler template and the operands. > > In an `asm', it's the user's fault; otherwise, the compiler's fault. */ > > diff --git a/gcc/target.def b/gcc/target.def > > index 206c94f8749ba8f242229d36da0049826c342502..793f64da9c0abb4ca470e6e9be0cd5eb1a859886 100644 > > --- a/gcc/target.def > > +++ b/gcc/target.def > > @@ -892,7 +892,7 @@ return @code{true}.", > > DEFHOOK_UNDOC > > (print_operand, > > "", > > - void, (FILE *file, rtx x, int code), > > + void, (FILE *file, rtx x, const char * const * p), > > default_print_operand) > > > > /* Emit a machine-specific memory address. */ > > diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc > > index 5f1eac75122c9cc945012a02426784f6c2584328..63cefae50f8854992b3fb7d5ad8a32cf9511208a 100644 > > --- a/gcc/targhooks.cc > > +++ b/gcc/targhooks.cc > > @@ -390,7 +390,7 @@ hook_callee_copies_named (cumulative_args_t, const function_arg_info &arg) > > > > void > > default_print_operand (FILE *stream ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, > > - int code ATTRIBUTE_UNUSED) > > + const char * const *p ATTRIBUTE_UNUSED) > > { > > #ifdef PRINT_OPERAND > > PRINT_OPERAND (stream, x, code); > > diff --git a/gcc/targhooks.h b/gcc/targhooks.h > > index 9582233e69fee1b56ab9d2f2573707621f9837ff..3031e08e84e7f1401d0fd08bf8e16c37f78c98c9 100644 > > --- a/gcc/targhooks.h > > +++ b/gcc/targhooks.h > > @@ -74,7 +74,7 @@ extern bool hook_pass_by_reference_must_pass_in_stack > > extern bool hook_callee_copies_named > > (cumulative_args_t ca, const function_arg_info &); > > > > -extern void default_print_operand (FILE *, rtx, int); > > +extern void default_print_operand (FILE *, rtx, const char * const *); > > extern void default_print_operand_address (FILE *, machine_mode, rtx); > > extern bool default_print_operand_punct_valid_p (unsigned char); > > extern tree default_mangle_assembler_name (const char *); > > > > > >
> -----Original Message----- > From: Richard Biener <rguenther@suse.de> > Sent: 08 April 2026 13:10 > To: Richard Earnshaw <Richard.Earnshaw@arm.com> > Cc: Tamar Christina <Tamar.Christina@arm.com>; gcc-patches@gcc.gnu.org; > nd <nd@arm.com>; jeffreyalaw@gmail.com; rdapp.gcc@gmail.com; > ktkachov@nvidia.com > Subject: Re: [PATCH 1/2][RFC][GCC 17][middle-end: Supporting multi > character string formatters > > On Wed, 8 Apr 2026, Richard Earnshaw (foss) wrote: > > > On 08/04/2026 09:18, Tamar Christina wrote: > > > Today asm print operands are required to be single characters. This means > we're > > > quite limited in the number of them we can have and they are threated as > white > > > gold in many backends. > > > > > > This causes us to have to do some hack solutions in the backends for > instance to > > > support some SME operations just to avoid new print operands. > > > > > > This patch extends the parsers to support multiple token operands and > extends > > > the print_operand target hook to pass a pointer to the buffer being read so > the > > > backend can consume as many tokens as it needs. > > > > > > As a consequence backends are completely free to choose how their multi > letter > > > operands look like. > > > > > > There will need to be a mechanical change in all targets doing > > > > > > int code = p ? (unsigned char)**p : 0; > > > > > > to support this new interface. > > > > > > There is one restriction in that whatever the backends choose should not > overlap > > > with assembler dialect support. This means that %{, &|, %} are reserved. > > > > > > I am wondering however if there is apetite to try to see if we can > standardise > > > on a syntax for multi character operands or whether we shouldn't try. > > > > > > One possible way is to do what we do for constraints, where you specify a > letter > > > to start the multi letter parsing and a fixed number of character to parse. > > > > > > However this is annoying as it still makes us make cryptic names. > > > > > > In the AArch64 example patch I chose %[..] so e.g. %[SME_VC]0 but I don't > quite > > > like it. I could do instead %SME_VC:0? i.e. if the character following the > > > current one isn't a digit, consume until a : is found. > > > > > > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. > > > > > > > This would be a nice improvement. > > > > We currently have an int for the code, but only use a limited set of ascii > values with that. Did you consider having a mapping function that could read > the extended formats and convert it to an int code for the extended values? > That would mean you wouldn't need to touch backends that haven't added > the parsing hook and would provide separation between reading a string code > and the backend processing of the value: the default hook would simply read a > char as before. > > > > Something like: > > else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned > char) *p)) > > - output_operand (NULL_RTX, *p++); > > + output_operand (NULL_RTX, > targetm.asm_out.print_operand_punct_code (&p); > > Or add &p as extra arg to the valid_p hook. Or make > targetm.asm_out.print_operand_punct_code return single-char code as > well and hopefully reserved -1 or 0 as error. > > Richard. I haven't considered this as I wanted to get some more descriptive names. The numerical value could work, but that's even harder to remember though. And this would escape into inline asm a user could write. In particular something like %40 is hard to parse. Is this %4 on operand 0, or code 40? It would need a larger change to the parser, because it atm unconditionally consumes numerical operands before calling the target hook. i.e. %0 is consumed and just 0 passed to the backend as a char. But it's certainly possible, but how do we then deal with the ambiguity? (I still really want more human friendly operands if possible though). Thanks, Tamar > > > else > > ... > > > > Any code above, say, 255 could be used by a backend. > > > > What's more, most existing code that passes a hard-coded letter wouldn't > need changing at all. > > > > R. > > > > > Thoughts? > > > > > > Thanks, > > > Tamar > > > > > > gcc/ChangeLog: > > > > > > * target.def (print_operand): Modify with new pointer. > > > * targhooks.cc (default_print_operand): Update using pointer. > > > * targhooks.h (default_print_operand): Likewise. > > > * config/aarch64/aarch64.cc (aarch64_print_operand): Update > > > * final.cc (output_asm_insn): Update to new target hook format. > > > (output_operand): Likewise. > > > * output.h (output_operand): Likewise. > > > > > > --- > > > diff --git a/gcc/config/aarch64/aarch64.cc > b/gcc/config/aarch64/aarch64.cc > > > index > 1902a4ee9fa34a1f00e654760d0759af1d6cf432..1bf54641f581e90bb629d > 2fcd2f0d32a2c9474f9 100644 > > > --- a/gcc/config/aarch64/aarch64.cc > > > +++ b/gcc/config/aarch64/aarch64.cc > > > @@ -13009,9 +13009,10 @@ sizetochar (int size) > > > 'z': Output address of a typical LDP or STP. */ > > > > > > static void > > > -aarch64_print_operand (FILE *f, rtx x, int code) > > > +aarch64_print_operand (FILE *f, rtx x, const char * const *p) > > > { > > > rtx elt; > > > + int code = p ? (unsigned char)**p : 0; > > > switch (code) > > > { > > > case 'c': > > > diff --git a/gcc/final.cc b/gcc/final.cc > > > index > b5e8c6e2efde01417370e7dea5456ba108b866ed..fcb8877f8814c4594f3a4 > ddc0da03e631653caf4 100644 > > > --- a/gcc/final.cc > > > +++ b/gcc/final.cc > > > @@ -3508,6 +3508,7 @@ output_asm_insn (const char *templ, rtx > *operands) > > > the TARGET_PRINT_OPERAND hook can define them. */ > > > else if (ISALPHA (*p)) > > > { > > > + const char *p_init = p; > > > int letter = *p++; > > > unsigned long opnum; > > > char *endptr; > > > @@ -3535,7 +3536,7 @@ output_asm_insn (const char *templ, rtx > *operands) > > > if (letter2 == 'c' || CONSTANT_ADDRESS_P > (operands[opnum])) > > > output_addr_const (asm_out_file, operands[opnum]); > > > else > > > - output_operand (operands[opnum], 'c'); > > > + output_operand (operands[opnum], &p_init); > > > } > > > else if (letter == 'n') > > > { > > > @@ -3549,7 +3550,7 @@ output_asm_insn (const char *templ, rtx > *operands) > > > } > > > } > > > else > > > - output_operand (operands[opnum], letter); > > > + output_operand (operands[opnum], &p_init); > > > > > > if (!opoutput[opnum]) > > > oporder[ops++] = opnum; > > > @@ -3585,7 +3586,10 @@ output_asm_insn (const char *templ, rtx > *operands) > > > punctuation character alone, with no operand. The > > > TARGET_PRINT_OPERAND hook decides what is actually done. */ > > > else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned > char) *p)) > > > - output_operand (NULL_RTX, *p++); > > > + { > > > + const char *ptr = p++; > > > + output_operand (NULL_RTX, &ptr); > > > + } > > > else > > > output_operand_lossage ("invalid %%-code"); > > > break; > > > @@ -3651,7 +3655,7 @@ mark_symbol_refs_as_used (rtx x) > > > by TARGET_PRINT_OPERAND. */ > > > > > > void > > > -output_operand (rtx x, int code ATTRIBUTE_UNUSED) > > > +output_operand (rtx x, const char * const *p ATTRIBUTE_UNUSED) > > > { > > > if (x && GET_CODE (x) == SUBREG) > > > x = alter_subreg (&x, true); > > > @@ -3660,7 +3664,7 @@ output_operand (rtx x, int code > ATTRIBUTE_UNUSED) > > > if (!targetm.no_register_allocation) > > > gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER); > > > > > > - targetm.asm_out.print_operand (asm_out_file, x, code); > > > + targetm.asm_out.print_operand (asm_out_file, x, p); > > > > > > if (x == NULL_RTX) > > > return; > > > diff --git a/gcc/output.h b/gcc/output.h > > > index > 1f628ea2371aeca006d686e521a04d4f7ddb6e2d..101f4f8ed14808f37ab45 > 5e2cb9e68a3edd237f3 100644 > > > --- a/gcc/output.h > > > +++ b/gcc/output.h > > > @@ -79,7 +79,7 @@ extern rtx_insn *final_scan_insn (rtx_insn *, FILE *, > int, int, int *); > > > extern rtx alter_subreg (rtx *, bool); > > > > > > /* Print an operand using machine-dependent assembler syntax. */ > > > -extern void output_operand (rtx, int); > > > +extern void output_operand (rtx, const char * const *); > > > > > > /* Report inconsistency between the assembler template and the > operands. > > > In an `asm', it's the user's fault; otherwise, the compiler's fault. */ > > > diff --git a/gcc/target.def b/gcc/target.def > > > index > 206c94f8749ba8f242229d36da0049826c342502..793f64da9c0abb4ca470 > e6e9be0cd5eb1a859886 100644 > > > --- a/gcc/target.def > > > +++ b/gcc/target.def > > > @@ -892,7 +892,7 @@ return @code{true}.", > > > DEFHOOK_UNDOC > > > (print_operand, > > > "", > > > - void, (FILE *file, rtx x, int code), > > > + void, (FILE *file, rtx x, const char * const * p), > > > default_print_operand) > > > > > > /* Emit a machine-specific memory address. */ > > > diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc > > > index > 5f1eac75122c9cc945012a02426784f6c2584328..63cefae50f8854992b3fb7 > d5ad8a32cf9511208a 100644 > > > --- a/gcc/targhooks.cc > > > +++ b/gcc/targhooks.cc > > > @@ -390,7 +390,7 @@ hook_callee_copies_named (cumulative_args_t, > const function_arg_info &arg) > > > > > > void > > > default_print_operand (FILE *stream ATTRIBUTE_UNUSED, rtx x > ATTRIBUTE_UNUSED, > > > - int code ATTRIBUTE_UNUSED) > > > + const char * const *p ATTRIBUTE_UNUSED) > > > { > > > #ifdef PRINT_OPERAND > > > PRINT_OPERAND (stream, x, code); > > > diff --git a/gcc/targhooks.h b/gcc/targhooks.h > > > index > 9582233e69fee1b56ab9d2f2573707621f9837ff..3031e08e84e7f1401d0fd > 08bf8e16c37f78c98c9 100644 > > > --- a/gcc/targhooks.h > > > +++ b/gcc/targhooks.h > > > @@ -74,7 +74,7 @@ extern bool > hook_pass_by_reference_must_pass_in_stack > > > extern bool hook_callee_copies_named > > > (cumulative_args_t ca, const function_arg_info &); > > > > > > -extern void default_print_operand (FILE *, rtx, int); > > > +extern void default_print_operand (FILE *, rtx, const char * const *); > > > extern void default_print_operand_address (FILE *, machine_mode, rtx); > > > extern bool default_print_operand_punct_valid_p (unsigned char); > > > extern tree default_mangle_assembler_name (const char *); > > > > > > > > > > > > -- > Richard Biener <rguenther@suse.de> > SUSE Software Solutions Germany GmbH, > Frankenstrasse 146, 90461 Nuernberg, Germany; > GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG > Nuernberg)
On 08/04/2026 13:17, Tamar Christina wrote: >> -----Original Message----- >> From: Richard Biener <rguenther@suse.de> >> Sent: 08 April 2026 13:10 >> To: Richard Earnshaw <Richard.Earnshaw@arm.com> >> Cc: Tamar Christina <Tamar.Christina@arm.com>; gcc-patches@gcc.gnu.org; >> nd <nd@arm.com>; jeffreyalaw@gmail.com; rdapp.gcc@gmail.com; >> ktkachov@nvidia.com >> Subject: Re: [PATCH 1/2][RFC][GCC 17][middle-end: Supporting multi >> character string formatters >> >> On Wed, 8 Apr 2026, Richard Earnshaw (foss) wrote: >> >>> On 08/04/2026 09:18, Tamar Christina wrote: >>>> Today asm print operands are required to be single characters. This means >> we're >>>> quite limited in the number of them we can have and they are threated as >> white >>>> gold in many backends. >>>> >>>> This causes us to have to do some hack solutions in the backends for >> instance to >>>> support some SME operations just to avoid new print operands. >>>> >>>> This patch extends the parsers to support multiple token operands and >> extends >>>> the print_operand target hook to pass a pointer to the buffer being read so >> the >>>> backend can consume as many tokens as it needs. >>>> >>>> As a consequence backends are completely free to choose how their multi >> letter >>>> operands look like. >>>> >>>> There will need to be a mechanical change in all targets doing >>>> >>>> int code = p ? (unsigned char)**p : 0; >>>> >>>> to support this new interface. >>>> >>>> There is one restriction in that whatever the backends choose should not >> overlap >>>> with assembler dialect support. This means that %{, &|, %} are reserved. >>>> >>>> I am wondering however if there is apetite to try to see if we can >> standardise >>>> on a syntax for multi character operands or whether we shouldn't try. >>>> >>>> One possible way is to do what we do for constraints, where you specify a >> letter >>>> to start the multi letter parsing and a fixed number of character to parse. >>>> >>>> However this is annoying as it still makes us make cryptic names. >>>> >>>> In the AArch64 example patch I chose %[..] so e.g. %[SME_VC]0 but I don't >> quite >>>> like it. I could do instead %SME_VC:0? i.e. if the character following the >>>> current one isn't a digit, consume until a : is found. >>>> >>>> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. >>>> >>> >>> This would be a nice improvement. >>> >>> We currently have an int for the code, but only use a limited set of ascii >> values with that. Did you consider having a mapping function that could read >> the extended formats and convert it to an int code for the extended values? >> That would mean you wouldn't need to touch backends that haven't added >> the parsing hook and would provide separation between reading a string code >> and the backend processing of the value: the default hook would simply read a >> char as before. >>> >>> Something like: >>> else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned >> char) *p)) >>> - output_operand (NULL_RTX, *p++); >>> + output_operand (NULL_RTX, >> targetm.asm_out.print_operand_punct_code (&p); >> >> Or add &p as extra arg to the valid_p hook. Or make >> targetm.asm_out.print_operand_punct_code return single-char code as >> well and hopefully reserved -1 or 0 as error. >> >> Richard. > > I haven't considered this as I wanted to get some more descriptive names. > The numerical value could work, but that's even harder to remember though. > enum operand_x_codes { SME_VC = 255, ... } ... switch (code) { case 'a': ... case SME_VC: ... } Now all your punct_code function does is map the user-space string to the enumeration value. We store them in ints so there's no representational issue. R. > And this would escape into inline asm a user could write. > > In particular something like %40 is hard to parse. Is this %4 on operand 0, or code 40? > > It would need a larger change to the parser, because it atm unconditionally consumes > numerical operands before calling the target hook. i.e. %0 is consumed and just 0 passed > to the backend as a char. > > But it's certainly possible, but how do we then deal with the ambiguity? (I still really want > more human friendly operands if possible though). The intent was not to change the string side of this, just the internal handling so that we don't need to make major changes to the internal APIs. R. > > Thanks, > Tamar > >> >>> else >>> ... >>> >>> Any code above, say, 255 could be used by a backend. >>> >>> What's more, most existing code that passes a hard-coded letter wouldn't >> need changing at all. >>> >>> R. >>> >>>> Thoughts? >>>> >>>> Thanks, >>>> Tamar >>>> >>>> gcc/ChangeLog: >>>> >>>> * target.def (print_operand): Modify with new pointer. >>>> * targhooks.cc (default_print_operand): Update using pointer. >>>> * targhooks.h (default_print_operand): Likewise. >>>> * config/aarch64/aarch64.cc (aarch64_print_operand): Update >>>> * final.cc (output_asm_insn): Update to new target hook format. >>>> (output_operand): Likewise. >>>> * output.h (output_operand): Likewise. >>>> >>>> --- >>>> diff --git a/gcc/config/aarch64/aarch64.cc >> b/gcc/config/aarch64/aarch64.cc >>>> index >> 1902a4ee9fa34a1f00e654760d0759af1d6cf432..1bf54641f581e90bb629d >> 2fcd2f0d32a2c9474f9 100644 >>>> --- a/gcc/config/aarch64/aarch64.cc >>>> +++ b/gcc/config/aarch64/aarch64.cc >>>> @@ -13009,9 +13009,10 @@ sizetochar (int size) >>>> 'z': Output address of a typical LDP or STP. */ >>>> >>>> static void >>>> -aarch64_print_operand (FILE *f, rtx x, int code) >>>> +aarch64_print_operand (FILE *f, rtx x, const char * const *p) >>>> { >>>> rtx elt; >>>> + int code = p ? (unsigned char)**p : 0; >>>> switch (code) >>>> { >>>> case 'c': >>>> diff --git a/gcc/final.cc b/gcc/final.cc >>>> index >> b5e8c6e2efde01417370e7dea5456ba108b866ed..fcb8877f8814c4594f3a4 >> ddc0da03e631653caf4 100644 >>>> --- a/gcc/final.cc >>>> +++ b/gcc/final.cc >>>> @@ -3508,6 +3508,7 @@ output_asm_insn (const char *templ, rtx >> *operands) >>>> the TARGET_PRINT_OPERAND hook can define them. */ >>>> else if (ISALPHA (*p)) >>>> { >>>> + const char *p_init = p; >>>> int letter = *p++; >>>> unsigned long opnum; >>>> char *endptr; >>>> @@ -3535,7 +3536,7 @@ output_asm_insn (const char *templ, rtx >> *operands) >>>> if (letter2 == 'c' || CONSTANT_ADDRESS_P >> (operands[opnum])) >>>> output_addr_const (asm_out_file, operands[opnum]); >>>> else >>>> - output_operand (operands[opnum], 'c'); >>>> + output_operand (operands[opnum], &p_init); >>>> } >>>> else if (letter == 'n') >>>> { >>>> @@ -3549,7 +3550,7 @@ output_asm_insn (const char *templ, rtx >> *operands) >>>> } >>>> } >>>> else >>>> - output_operand (operands[opnum], letter); >>>> + output_operand (operands[opnum], &p_init); >>>> >>>> if (!opoutput[opnum]) >>>> oporder[ops++] = opnum; >>>> @@ -3585,7 +3586,10 @@ output_asm_insn (const char *templ, rtx >> *operands) >>>> punctuation character alone, with no operand. The >>>> TARGET_PRINT_OPERAND hook decides what is actually done. */ >>>> else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned >> char) *p)) >>>> - output_operand (NULL_RTX, *p++); >>>> + { >>>> + const char *ptr = p++; >>>> + output_operand (NULL_RTX, &ptr); >>>> + } >>>> else >>>> output_operand_lossage ("invalid %%-code"); >>>> break; >>>> @@ -3651,7 +3655,7 @@ mark_symbol_refs_as_used (rtx x) >>>> by TARGET_PRINT_OPERAND. */ >>>> >>>> void >>>> -output_operand (rtx x, int code ATTRIBUTE_UNUSED) >>>> +output_operand (rtx x, const char * const *p ATTRIBUTE_UNUSED) >>>> { >>>> if (x && GET_CODE (x) == SUBREG) >>>> x = alter_subreg (&x, true); >>>> @@ -3660,7 +3664,7 @@ output_operand (rtx x, int code >> ATTRIBUTE_UNUSED) >>>> if (!targetm.no_register_allocation) >>>> gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER); >>>> >>>> - targetm.asm_out.print_operand (asm_out_file, x, code); >>>> + targetm.asm_out.print_operand (asm_out_file, x, p); >>>> >>>> if (x == NULL_RTX) >>>> return; >>>> diff --git a/gcc/output.h b/gcc/output.h >>>> index >> 1f628ea2371aeca006d686e521a04d4f7ddb6e2d..101f4f8ed14808f37ab45 >> 5e2cb9e68a3edd237f3 100644 >>>> --- a/gcc/output.h >>>> +++ b/gcc/output.h >>>> @@ -79,7 +79,7 @@ extern rtx_insn *final_scan_insn (rtx_insn *, FILE *, >> int, int, int *); >>>> extern rtx alter_subreg (rtx *, bool); >>>> >>>> /* Print an operand using machine-dependent assembler syntax. */ >>>> -extern void output_operand (rtx, int); >>>> +extern void output_operand (rtx, const char * const *); >>>> >>>> /* Report inconsistency between the assembler template and the >> operands. >>>> In an `asm', it's the user's fault; otherwise, the compiler's fault. */ >>>> diff --git a/gcc/target.def b/gcc/target.def >>>> index >> 206c94f8749ba8f242229d36da0049826c342502..793f64da9c0abb4ca470 >> e6e9be0cd5eb1a859886 100644 >>>> --- a/gcc/target.def >>>> +++ b/gcc/target.def >>>> @@ -892,7 +892,7 @@ return @code{true}.", >>>> DEFHOOK_UNDOC >>>> (print_operand, >>>> "", >>>> - void, (FILE *file, rtx x, int code), >>>> + void, (FILE *file, rtx x, const char * const * p), >>>> default_print_operand) >>>> >>>> /* Emit a machine-specific memory address. */ >>>> diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc >>>> index >> 5f1eac75122c9cc945012a02426784f6c2584328..63cefae50f8854992b3fb7 >> d5ad8a32cf9511208a 100644 >>>> --- a/gcc/targhooks.cc >>>> +++ b/gcc/targhooks.cc >>>> @@ -390,7 +390,7 @@ hook_callee_copies_named (cumulative_args_t, >> const function_arg_info &arg) >>>> >>>> void >>>> default_print_operand (FILE *stream ATTRIBUTE_UNUSED, rtx x >> ATTRIBUTE_UNUSED, >>>> - int code ATTRIBUTE_UNUSED) >>>> + const char * const *p ATTRIBUTE_UNUSED) >>>> { >>>> #ifdef PRINT_OPERAND >>>> PRINT_OPERAND (stream, x, code); >>>> diff --git a/gcc/targhooks.h b/gcc/targhooks.h >>>> index >> 9582233e69fee1b56ab9d2f2573707621f9837ff..3031e08e84e7f1401d0fd >> 08bf8e16c37f78c98c9 100644 >>>> --- a/gcc/targhooks.h >>>> +++ b/gcc/targhooks.h >>>> @@ -74,7 +74,7 @@ extern bool >> hook_pass_by_reference_must_pass_in_stack >>>> extern bool hook_callee_copies_named >>>> (cumulative_args_t ca, const function_arg_info &); >>>> >>>> -extern void default_print_operand (FILE *, rtx, int); >>>> +extern void default_print_operand (FILE *, rtx, const char * const *); >>>> extern void default_print_operand_address (FILE *, machine_mode, rtx); >>>> extern bool default_print_operand_punct_valid_p (unsigned char); >>>> extern tree default_mangle_assembler_name (const char *); >>>> >>>> >>> >>> >> >> -- >> Richard Biener <rguenther@suse.de> >> SUSE Software Solutions Germany GmbH, >> Frankenstrasse 146, 90461 Nuernberg, Germany; >> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG >> Nuernberg)
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 1902a4ee9fa34a1f00e654760d0759af1d6cf432..1bf54641f581e90bb629d2fcd2f0d32a2c9474f9 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -13009,9 +13009,10 @@ sizetochar (int size) 'z': Output address of a typical LDP or STP. */ static void -aarch64_print_operand (FILE *f, rtx x, int code) +aarch64_print_operand (FILE *f, rtx x, const char * const *p) { rtx elt; + int code = p ? (unsigned char)**p : 0; switch (code) { case 'c': diff --git a/gcc/final.cc b/gcc/final.cc index b5e8c6e2efde01417370e7dea5456ba108b866ed..fcb8877f8814c4594f3a4ddc0da03e631653caf4 100644 --- a/gcc/final.cc +++ b/gcc/final.cc @@ -3508,6 +3508,7 @@ output_asm_insn (const char *templ, rtx *operands) the TARGET_PRINT_OPERAND hook can define them. */ else if (ISALPHA (*p)) { + const char *p_init = p; int letter = *p++; unsigned long opnum; char *endptr; @@ -3535,7 +3536,7 @@ output_asm_insn (const char *templ, rtx *operands) if (letter2 == 'c' || CONSTANT_ADDRESS_P (operands[opnum])) output_addr_const (asm_out_file, operands[opnum]); else - output_operand (operands[opnum], 'c'); + output_operand (operands[opnum], &p_init); } else if (letter == 'n') { @@ -3549,7 +3550,7 @@ output_asm_insn (const char *templ, rtx *operands) } } else - output_operand (operands[opnum], letter); + output_operand (operands[opnum], &p_init); if (!opoutput[opnum]) oporder[ops++] = opnum; @@ -3585,7 +3586,10 @@ output_asm_insn (const char *templ, rtx *operands) punctuation character alone, with no operand. The TARGET_PRINT_OPERAND hook decides what is actually done. */ else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned char) *p)) - output_operand (NULL_RTX, *p++); + { + const char *ptr = p++; + output_operand (NULL_RTX, &ptr); + } else output_operand_lossage ("invalid %%-code"); break; @@ -3651,7 +3655,7 @@ mark_symbol_refs_as_used (rtx x) by TARGET_PRINT_OPERAND. */ void -output_operand (rtx x, int code ATTRIBUTE_UNUSED) +output_operand (rtx x, const char * const *p ATTRIBUTE_UNUSED) { if (x && GET_CODE (x) == SUBREG) x = alter_subreg (&x, true); @@ -3660,7 +3664,7 @@ output_operand (rtx x, int code ATTRIBUTE_UNUSED) if (!targetm.no_register_allocation) gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER); - targetm.asm_out.print_operand (asm_out_file, x, code); + targetm.asm_out.print_operand (asm_out_file, x, p); if (x == NULL_RTX) return; diff --git a/gcc/output.h b/gcc/output.h index 1f628ea2371aeca006d686e521a04d4f7ddb6e2d..101f4f8ed14808f37ab455e2cb9e68a3edd237f3 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -79,7 +79,7 @@ extern rtx_insn *final_scan_insn (rtx_insn *, FILE *, int, int, int *); extern rtx alter_subreg (rtx *, bool); /* Print an operand using machine-dependent assembler syntax. */ -extern void output_operand (rtx, int); +extern void output_operand (rtx, const char * const *); /* Report inconsistency between the assembler template and the operands. In an `asm', it's the user's fault; otherwise, the compiler's fault. */ diff --git a/gcc/target.def b/gcc/target.def index 206c94f8749ba8f242229d36da0049826c342502..793f64da9c0abb4ca470e6e9be0cd5eb1a859886 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -892,7 +892,7 @@ return @code{true}.", DEFHOOK_UNDOC (print_operand, "", - void, (FILE *file, rtx x, int code), + void, (FILE *file, rtx x, const char * const * p), default_print_operand) /* Emit a machine-specific memory address. */ diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc index 5f1eac75122c9cc945012a02426784f6c2584328..63cefae50f8854992b3fb7d5ad8a32cf9511208a 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -390,7 +390,7 @@ hook_callee_copies_named (cumulative_args_t, const function_arg_info &arg) void default_print_operand (FILE *stream ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, - int code ATTRIBUTE_UNUSED) + const char * const *p ATTRIBUTE_UNUSED) { #ifdef PRINT_OPERAND PRINT_OPERAND (stream, x, code); diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 9582233e69fee1b56ab9d2f2573707621f9837ff..3031e08e84e7f1401d0fd08bf8e16c37f78c98c9 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -74,7 +74,7 @@ extern bool hook_pass_by_reference_must_pass_in_stack extern bool hook_callee_copies_named (cumulative_args_t ca, const function_arg_info &); -extern void default_print_operand (FILE *, rtx, int); +extern void default_print_operand (FILE *, rtx, const char * const *); extern void default_print_operand_address (FILE *, machine_mode, rtx); extern bool default_print_operand_punct_valid_p (unsigned char); extern tree default_mangle_assembler_name (const char *);