get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2231246/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2231246,
    "url": "http://patchwork.ozlabs.org/api/patches/2231246/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/CAMe9rOrG=Pk9YsEVyFHCi302Y1pi8VOSxZGesruDqmO8ngOasw@mail.gmail.com/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<CAMe9rOrG=Pk9YsEVyFHCi302Y1pi8VOSxZGesruDqmO8ngOasw@mail.gmail.com>",
    "list_archive_url": null,
    "date": "2026-04-30T12:28:53",
    "name": "x86: Implement TARGET_FNTYPE_ABI",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "e93cfbfffe041393bbdfee9421f6544628367fe2",
    "submitter": {
        "id": 4387,
        "url": "http://patchwork.ozlabs.org/api/people/4387/?format=api",
        "name": "H.J. Lu",
        "email": "hjl.tools@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/CAMe9rOrG=Pk9YsEVyFHCi302Y1pi8VOSxZGesruDqmO8ngOasw@mail.gmail.com/mbox/",
    "series": [
        {
            "id": 502296,
            "url": "http://patchwork.ozlabs.org/api/series/502296/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=502296",
            "date": "2026-04-30T12:28:53",
            "name": "x86: Implement TARGET_FNTYPE_ABI",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/502296/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2231246/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2231246/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=U6xmWdi8;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=U6xmWdi8",
            "sourceware.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com",
            "sourceware.org; spf=pass smtp.mailfrom=gmail.com",
            "server2.sourceware.org;\n arc=pass smtp.remote-ip=209.85.215.180"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g5tmJ3bhhz1yHZ\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 22:30:08 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id A280A436F7C2\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 12:30:06 +0000 (GMT)",
            "from mail-pg1-f180.google.com (mail-pg1-f180.google.com\n [209.85.215.180])\n by sourceware.org (Postfix) with ESMTPS id 6228D4371D70\n for <gcc-patches@gcc.gnu.org>; Thu, 30 Apr 2026 12:29:32 +0000 (GMT)",
            "by mail-pg1-f180.google.com with SMTP id\n 41be03b00d2f7-c736261ee8dso288454a12.1\n for <gcc-patches@gcc.gnu.org>; Thu, 30 Apr 2026 05:29:32 -0700 (PDT)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org A280A436F7C2",
            "OpenDKIM Filter v2.11.0 sourceware.org 6228D4371D70"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 6228D4371D70",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 6228D4371D70",
        "ARC-Seal": [
            "i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1777552172; cv=pass;\n b=pqi0WCTmkQ95utid9WRnCCPyrU6LpDFEZmPLla2s4GqX/WogX9YHFDzy+Ox2e0IHenhE1AdUhA0ifMDEr1pPCiGhrkm6nyE+U2N38lAx7gTnKWKnxitSdSDsC75Y82pCpkXuTG2H03SkNirCJE1JFbQKpynL9sE5w+kCZnEsnwY=",
            "i=1; a=rsa-sha256; t=1777552171; cv=none;\n d=google.com; s=arc-20240605;\n b=TUOXTiEaZPa/o4yWPz9ajCWod7rCE6DW6vemcUM6IMDYgPku5WgL5vnbhP+lagIedW\n btQbgjgdaz46kB9YrEx+gKCxJmgbC5D2dckoZEEdnTprrOuFowo2uZQpu0X/5XEC8TYm\n UpA3YQ+n8xTzcphRgsnjAEebC3DiICneNc+H/SP427LdZKnmJMSBDETw+w7lBv3IZwgs\n LwQagb3yfQrg9t5cKI863ACLLHM9JYjoB4+8nnhrTdB4EtpCO+XLdXRGPwtcnkMioJnJ\n mv5CnhqDs1oFH5GVw57VWgxHyJlFzv/gxoa5mP1fkxU9/azSduWlAyUgEQhpRthC2kos\n RwlA=="
        ],
        "ARC-Message-Signature": [
            "i=2; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777552172; c=relaxed/simple;\n bh=BLUP8wjhbcqEEAAFEWH4cmjFG/uN1G+RVzgWWPnIj9U=;\n h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To;\n b=kmhngsymREj7N62TYgyUKZ2ctrMJiP0ocpLJXW0zmewJUwSUBRAKYeGs8kti1TZyw5oSFLxBM9ylfpxNAFlvsx7maaC027GmgTHShdD68EASqXWxpbgwwAtaxkZwS0D4Zo9q5iuPAbQxoWku45mNwKgKa3QrVobDzskQVayL67k=",
            "i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=to:subject:message-id:date:from:mime-version:dkim-signature;\n bh=ee/HzurH3GR8Ybq5eB2XvpA8Eq6ZS81HvRfwR2oczOI=;\n fh=83snE5t1iR5QXMcAAhy1f7NFmMeqVCeXIkq3dVlORPM=;\n b=fFCDVzeCvfF0R2GljmJcKvHaD5TajSmnO0on37IBfyFxqaNN3FL5QndBPKShUhv0xo\n HjC88i8+kwp+mGrg9ZP4IYuoTTDOmfCyfQI+bPNXOsfbXOiMNCXZ2xA8Y5UtMlsEL+Hm\n 5i1FH8n9+cFCCFbf8W8HItVHJLIdYA+1mDQgMYOTy4tqsf8GgmGqg8j14n6wGToZYFK+\n +XFhsJwusDVSJ9BeJXrzDVAQVibzSm8H2tBjwJryI38pfVzkJJyEGShAxwV+n/Moz98f\n /3KYZmjr0513YJPvvFnNvag7DqCxOPYPS8/MbjKRbEl1xT+iMswAsMOiIpNRaCCjjwjM\n dwhw==; darn=gcc.gnu.org"
        ],
        "ARC-Authentication-Results": [
            "i=2; server2.sourceware.org",
            "i=1; mx.google.com; arc=none"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1777552171; x=1778156971; darn=gcc.gnu.org;\n h=to:subject:message-id:date:from:mime-version:from:to:cc:subject\n :date:message-id:reply-to;\n bh=ee/HzurH3GR8Ybq5eB2XvpA8Eq6ZS81HvRfwR2oczOI=;\n b=U6xmWdi8oHdJ2rVNnGY+8pOo+8p1bk4ZD+z6G4IRfy549QB0av7rbR06ZKxTpxrqn0\n s0i19E5b7oowSPKIRmDIjqhzvGILNre67YyaneglM558yaM+OORT2aBedGv5WOnj3E94\n sYIWAOBD/ThAgZUHUQBpRYPEhvhinEleDsBD6qZV0j8+mxx196AYdjk+2QZTQwiP2mCn\n Xj/g8dWB5Gm256sNDk3Ai5Or1Egh/3cHCcCN+8XsM5MQyCMOcZJs3VAkZS84q2trO0nJ\n xAfdSnM4rG/sQl2hk56p5zj6IZeiJPKhkQ3uYF0glE4HeFwU4jjwdZ5CpLs0az1fd9w/\n ktSw==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777552171; x=1778156971;\n h=to:subject:message-id:date:from:mime-version:x-gm-gg\n :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=ee/HzurH3GR8Ybq5eB2XvpA8Eq6ZS81HvRfwR2oczOI=;\n b=XFLE90RH7CLOHWCm6tz6tnEDegE1f1SH7TMe97uzQsJhGsQZ/5ovnCPr+dlhcffkUo\n /6JWBw+O36kXLkdkhKeJytVjwjwRB2ZBvG8ARCwoyBpV9B1wVDYs7vSGyvwiAmnBvqH4\n dV7gKuIsBFZvEdv1rW4YktC3kGU3XH9RneOpj+Px8tJ2Zusg80bKtvb2Y6PTcvPzru+C\n 0RatEi8yG5bgN/fyEyP0B7J1A+bGIOYdy1Cnfc87PXhRx+b5hKuoC4dIfalBhurJOm1Y\n HRMqG64Gq84xCK7QEZTP5guOsfSjmsB6CVciPQjDZJmrXADff6Y4Nx+4V8wA0cub7E/M\n 3gfA==",
        "X-Gm-Message-State": "AOJu0Yz8AbANP6GrEObm5YV7XZb80PvWJ9+syENfDBToEuG5ib+S2q0S\n wnmabkq4bEzEgziEchBDbOvskNQwu9d7RFDhXqOvrIpNjPouI4vcqZVuq2yzpN+Umi8QEJq8P+Q\n vdOIQorstzFBPhuQJoArbkZK2z0I4wD6UXzbX2lII30Qu",
        "X-Gm-Gg": "AeBDievaDHCWq6HEDb83TK7QJebI+M5KyyVQeV+LrNz395/BF+0wW7X3cZtjl5Ra3aw\n Z1VRfsCN7rEPPejASVpDEZEn9tdgPQ4FN1G3kkW88ZUknkgV14pR3wKMevUeiXxWcaic/uTWf3/\n K1z/HiBa0RJtHwWlrIty1XsOMwqlPySHpqDXBgRRLX2stqMH2OFbmcD4CaD+pHYMCqKJVKpAp9+\n 160IEWhR34u5zpmy926YNMh7BQrYzDYtfVSctyUyo4woiGn5kWjy/B5RjiDzvj3drK8V84sGfgm\n hTERtko6Tz9EgcIWAw==",
        "X-Received": "by 2002:a05:6a21:6d9c:b0:3a1:90ef:7e31 with SMTP id\n adf61e73a8af0-3a3cf8c2cc4mr3248481637.54.1777552170857; Thu, 30 Apr 2026\n 05:29:30 -0700 (PDT)",
        "MIME-Version": "1.0",
        "From": "\"H.J. Lu\" <hjl.tools@gmail.com>",
        "Date": "Thu, 30 Apr 2026 20:28:53 +0800",
        "X-Gm-Features": "AVHnY4K9qoBq47TQi3XMMveMhvkV1fdIkT7tf3Mxx8HNZ2MplMuTq_hlOM4_IcU",
        "Message-ID": "\n <CAMe9rOrG=Pk9YsEVyFHCi302Y1pi8VOSxZGesruDqmO8ngOasw@mail.gmail.com>",
        "Subject": "[PATCH] x86: Implement TARGET_FNTYPE_ABI",
        "To": "GCC Patches <gcc-patches@gcc.gnu.org>, Uros Bizjak <ubizjak@gmail.com>,\n Hongtao Liu <hongtao.liu@intel.com>",
        "Content-Type": "multipart/mixed; boundary=\"000000000000b6d5ed0650ac9d12\"",
        "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>,\n <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>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "Implement TARGET_FNTYPE_ABI to avoid spills of callee-saved registers\nwhen calling functions with no_caller_saved_registers attribute.\n\n1. For functions with no_callee_saved_registers attribute, frame register\nis preserved to mitigate PR target/114116.  MMX and x87 registers are\npreserved if MMX and x87 aren't enabled.\n2. For functions with no_caller_saved_registers attribute, MMX and x87\nregisters aren't preserved since saving and restoring registers doesn't\ninclude MMX nor x87 registers.\n3. Don't mark disabled registers as call used.\n\ngcc/\n\nPR target/124798\n* config/i386/i386.cc (ix86_conditional_register_usage): Don't\nmark disabled registers as call used.\n(ix86_no_callee_saved_abi): New function.\n(ix86_no_caller_saved_abi_void): Likewise.\n(ix86_no_caller_saved_abi_ax): Likewise.\n(ix86_no_caller_saved_abi_ax_dx): Likewise.\n(ix86_no_caller_saved_abi_xmm0): Likewise.\n(ix86_no_caller_saved_abi_xmm0_xmm1): Likewise.\n(ix86_fntype_abi): Likewise.\n(ix86_hard_regno_call_part_clobbered): Handle newly added ABIs.\n(TARGET_FNTYPE_ABI): New.\n* config/i386/i386.md: Add ABI_NO_CALLEE_SAVED,\nABI_NO_CALLER_SAVED_RETURN_VOID, ABI_NO_CALLER_SAVED_RETURN_AX,\nABI_NO_CALLER_SAVED_RETURN_AX_DX, ABI_NO_CALLER_SAVED_RETURN_XMM0\nand ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1.\n\ngcc/testsuite/\n\nPR target/124798\n* gcc.target/i386/no-callee-saved-2.c: Check frame register isn't\nsaved or restored in 64-bit mode.\n* gcc.target/i386/preserve-none-7.c: Likewise.\n* gcc.target/i386/no-caller-saved-1.c: New test.\n* gcc.target/i386/no-caller-saved-2.c: Likewise.\n* gcc.target/i386/no-caller-saved-3.c: Likewise.\n* gcc.target/i386/no-caller-saved-4.c: Likewise.\n* gcc.target/i386/no-caller-saved-5.c: Likewise.\n* gcc.target/i386/no-caller-saved-6.c: Likewise.\n* gcc.target/i386/no-caller-saved-7.c: Likewise.",
    "diff": "From f0d2b28e80fc35f100a25d4da51982c1b8a733d6 Mon Sep 17 00:00:00 2001\nFrom: \"H.J. Lu\" <hjl.tools@gmail.com>\nDate: Tue, 14 Apr 2026 18:37:20 +0800\nSubject: [PATCH] x86: Implement TARGET_FNTYPE_ABI\n\nImplement TARGET_FNTYPE_ABI to avoid spills of callee-saved registers\nwhen calling functions with no_caller_saved_registers attribute.\n\n1. For functions with no_callee_saved_registers attribute, frame register\nis preserved to mitigate PR target/114116.  MMX and x87 registers are\npreserved if MMX and x87 aren't enabled.\n2. For functions with no_caller_saved_registers attribute, MMX and x87\nregisters aren't preserved since saving and restoring registers doesn't\ninclude MMX nor x87 registers.\n3. Don't mark disabled registers as call used.\n\ngcc/\n\n\tPR target/124798\n\t* config/i386/i386.cc (ix86_conditional_register_usage): Don't\n\tmark disabled registers as call used.\n\t(ix86_no_callee_saved_abi): New function.\n\t(ix86_no_caller_saved_abi_void): Likewise.\n\t(ix86_no_caller_saved_abi_ax): Likewise.\n\t(ix86_no_caller_saved_abi_ax_dx): Likewise.\n\t(ix86_no_caller_saved_abi_xmm0): Likewise.\n\t(ix86_no_caller_saved_abi_xmm0_xmm1): Likewise.\n\t(ix86_fntype_abi): Likewise.\n\t(ix86_hard_regno_call_part_clobbered): Handle newly added ABIs.\n\t(TARGET_FNTYPE_ABI): New.\n\t* config/i386/i386.md: Add ABI_NO_CALLEE_SAVED,\n\tABI_NO_CALLER_SAVED_RETURN_VOID, ABI_NO_CALLER_SAVED_RETURN_AX,\n\tABI_NO_CALLER_SAVED_RETURN_AX_DX, ABI_NO_CALLER_SAVED_RETURN_XMM0\n\tand ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1.\n\ngcc/testsuite/\n\n\tPR target/124798\n\t* gcc.target/i386/no-callee-saved-2.c: Check frame register isn't\n\tsaved or restored in 64-bit mode.\n\t* gcc.target/i386/preserve-none-7.c: Likewise.\n\t* gcc.target/i386/no-caller-saved-1.c: New test.\n\t* gcc.target/i386/no-caller-saved-2.c: Likewise.\n\t* gcc.target/i386/no-caller-saved-3.c: Likewise.\n\t* gcc.target/i386/no-caller-saved-4.c: Likewise.\n\t* gcc.target/i386/no-caller-saved-5.c: Likewise.\n\t* gcc.target/i386/no-caller-saved-6.c: Likewise.\n\t* gcc.target/i386/no-caller-saved-7.c: Likewise.\n\nSigned-off-by: H.J. Lu <hjl.tools@gmail.com>\n---\n gcc/config/i386/i386.cc                       | 249 +++++++++++++++++-\n gcc/config/i386/i386.md                       |  18 +-\n .../gcc.target/i386/no-callee-saved-2.c       |  10 +-\n .../gcc.target/i386/no-caller-saved-1.c       |  46 ++++\n .../gcc.target/i386/no-caller-saved-2.c       |  45 ++++\n .../gcc.target/i386/no-caller-saved-3.c       |  44 ++++\n .../gcc.target/i386/no-caller-saved-4.c       |  44 ++++\n .../gcc.target/i386/no-caller-saved-5.c       |  34 +++\n .../gcc.target/i386/no-caller-saved-6.c       |  34 +++\n .../gcc.target/i386/no-caller-saved-7.c       |  49 ++++\n .../gcc.target/i386/preserve-none-7.c         |  10 +-\n 11 files changed, 572 insertions(+), 11 deletions(-)\n create mode 100644 gcc/testsuite/gcc.target/i386/no-caller-saved-1.c\n create mode 100644 gcc/testsuite/gcc.target/i386/no-caller-saved-2.c\n create mode 100644 gcc/testsuite/gcc.target/i386/no-caller-saved-3.c\n create mode 100644 gcc/testsuite/gcc.target/i386/no-caller-saved-4.c\n create mode 100644 gcc/testsuite/gcc.target/i386/no-caller-saved-5.c\n create mode 100644 gcc/testsuite/gcc.target/i386/no-caller-saved-6.c\n create mode 100644 gcc/testsuite/gcc.target/i386/no-caller-saved-7.c\n\ndiff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc\nindex 01715f84e8a..428394985a1 100644\n--- a/gcc/config/i386/i386.cc\n+++ b/gcc/config/i386/i386.cc\n@@ -571,6 +571,11 @@ ix86_conditional_register_usage (void)\n       for (i = FIRST_REX2_INT_REG; i <= LAST_REX2_INT_REG; i++)\n \tCLEAR_HARD_REG_BIT (accessible_reg_set, i);\n     }\n+\n+  /* If a register is disabled, it can't be used for call.  */\n+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)\n+    if (!TEST_HARD_REG_BIT (accessible_reg_set, i))\n+      call_used_regs[i] = 0;\n }\n \n /* Canonicalize a comparison from one we don't have to one we do have.  */\n@@ -21719,6 +21724,214 @@ ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)\n   return false;\n }\n \n+/* Return the descriptor of no_callee_saved_registers function type.\n+   None of registers are preserved, except for frame register to\n+   mitigate PR target/114116.  MMX and x87 registers are preserved\n+   if MMX and x87 aren't enabled.  */\n+\n+static const predefined_function_abi &\n+ix86_no_callee_saved_abi (void)\n+{\n+  auto &no_callee_saved_abi = function_abis[ABI_NO_CALLEE_SAVED];\n+  if (!no_callee_saved_abi.initialized_p ())\n+    {\n+      HARD_REG_SET full_reg_clobbers = reg_class_contents[ALL_REGS];\n+      CLEAR_HARD_REG_BIT (full_reg_clobbers, HARD_FRAME_POINTER_REGNUM);\n+      for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)\n+\tif ((!TARGET_80387 && STACK_REGNO_P (i))\n+\t    || (!TARGET_MMX && MMX_REGNO_P (i)))\n+\t  CLEAR_HARD_REG_BIT (full_reg_clobbers, i);\n+      no_callee_saved_abi.initialize (ABI_NO_CALLEE_SAVED,\n+\t\t\t\t      full_reg_clobbers);\n+    }\n+  return no_callee_saved_abi;\n+}\n+\n+/* Return the descriptor of no_caller_saved_registers function type.\n+   All registers are preserved, except for MMX and x87 registers\n+   which aren't supported when saving and restoring registers.  */\n+\n+static const predefined_function_abi &\n+ix86_no_caller_saved_abi_void (void)\n+{\n+  auto &no_caller_saved_abi\n+    = function_abis[ABI_NO_CALLER_SAVED_RETURN_VOID];\n+  if (!no_caller_saved_abi.initialized_p ())\n+    {\n+      HARD_REG_SET full_reg_clobbers = {};\n+      for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)\n+\tif ((TARGET_80387 && STACK_REGNO_P (i))\n+\t    || (TARGET_MMX && MMX_REGNO_P (i)))\n+\t  SET_HARD_REG_BIT (full_reg_clobbers, i);\n+      no_caller_saved_abi.initialize\n+\t(ABI_NO_CALLER_SAVED_RETURN_VOID, full_reg_clobbers);\n+    }\n+  return no_caller_saved_abi;\n+}\n+\n+/* Return the descriptor of no_caller_saved_registers function type.\n+   All registers are preserved, except for AX used for return value,\n+   MMX and x87 registers which aren't supported when saving and\n+   restoring registers.  */\n+\n+static const predefined_function_abi &\n+ix86_no_caller_saved_abi_ax (void)\n+{\n+  auto &no_caller_saved_abi\n+    = function_abis[ABI_NO_CALLER_SAVED_RETURN_AX];\n+  if (!no_caller_saved_abi.initialized_p ())\n+    {\n+      HARD_REG_SET full_reg_clobbers = {};\n+      for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)\n+\tif (i == AX_REG\n+\t    || (TARGET_80387 && STACK_REGNO_P (i))\n+\t    || (TARGET_MMX && MMX_REGNO_P (i)))\n+\t  SET_HARD_REG_BIT (full_reg_clobbers, i);\n+      no_caller_saved_abi.initialize\n+\t(ABI_NO_CALLER_SAVED_RETURN_AX, full_reg_clobbers);\n+    }\n+  return no_caller_saved_abi;\n+}\n+\n+/* Return the descriptor of no_caller_saved_registers function type.\n+   All registers are preserved, except for AX/DX used for return value,\n+   MMX and x87 registers which aren't supported when saving and\n+   restoring registers.  */\n+\n+static const predefined_function_abi &\n+ix86_no_caller_saved_abi_ax_dx (void)\n+{\n+  auto &no_caller_saved_abi\n+    = function_abis[ABI_NO_CALLER_SAVED_RETURN_AX_DX];\n+  if (!no_caller_saved_abi.initialized_p ())\n+    {\n+      HARD_REG_SET full_reg_clobbers = {};\n+      for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)\n+\tif (i == AX_REG\n+\t    || i == DX_REG\n+\t    || (TARGET_80387 && STACK_REGNO_P (i))\n+\t    || (TARGET_MMX && MMX_REGNO_P (i)))\n+\t  SET_HARD_REG_BIT (full_reg_clobbers, i);\n+      no_caller_saved_abi.initialize\n+\t(ABI_NO_CALLER_SAVED_RETURN_AX_DX, full_reg_clobbers);\n+    }\n+  return no_caller_saved_abi;\n+}\n+\n+/* Return the descriptor of no_caller_saved_registers function type.\n+   All registers are preserved, except for XMM0 used for return value,\n+   MMX and x87 registers which aren't supported when saving and\n+   restoring registers.  */\n+\n+static const predefined_function_abi &\n+ix86_no_caller_saved_abi_xmm0 (void)\n+{\n+  auto &no_caller_saved_abi\n+    = function_abis[ABI_NO_CALLER_SAVED_RETURN_XMM0];\n+  if (!no_caller_saved_abi.initialized_p ())\n+    {\n+      HARD_REG_SET full_reg_clobbers = {};\n+      for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)\n+\tif (i == XMM0_REG\n+\t    || (TARGET_80387 && STACK_REGNO_P (i))\n+\t    || (TARGET_MMX && MMX_REGNO_P (i)))\n+\t  SET_HARD_REG_BIT (full_reg_clobbers, i);\n+      no_caller_saved_abi.initialize\n+\t(ABI_NO_CALLER_SAVED_RETURN_XMM0, full_reg_clobbers);\n+    }\n+  return no_caller_saved_abi;\n+}\n+\n+/* Return the descriptor of no_caller_saved_registers function type.\n+   All registers are preserved, except for XMM0/XMM1 used for return\n+   value, MMX and x87 registers which aren't supported when saving and\n+   restoring registers.  */\n+\n+static const predefined_function_abi &\n+ix86_no_caller_saved_abi_xmm0_xmm1 (void)\n+{\n+  auto &no_caller_saved_abi\n+    = function_abis[ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1];\n+  if (!no_caller_saved_abi.initialized_p ())\n+    {\n+      HARD_REG_SET full_reg_clobbers = {};\n+      for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)\n+\tif (i == XMM0_REG\n+\t    || i == XMM1_REG\n+\t    || (TARGET_80387 && STACK_REGNO_P (i))\n+\t    || (TARGET_MMX && MMX_REGNO_P (i)))\n+\t  SET_HARD_REG_BIT (full_reg_clobbers, i);\n+      no_caller_saved_abi.initialize\n+\t(ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1, full_reg_clobbers);\n+    }\n+  return no_caller_saved_abi;\n+}\n+\n+/* Implement TARGET_FNTYPE_ABI.  */\n+\n+static const predefined_function_abi &\n+ix86_fntype_abi (const_tree fntype)\n+{\n+  if (lookup_attribute (\"no_callee_saved_registers\",\n+\t\t\tTYPE_ATTRIBUTES (fntype))\n+      || lookup_attribute (\"no_callee_saved_registers\",\n+\t\t\t   TYPE_ATTRIBUTES (fntype)))\n+    return ix86_no_callee_saved_abi ();\n+\n+  if (lookup_attribute (\"no_caller_saved_registers\",\n+\t\t\tTYPE_ATTRIBUTES (fntype)))\n+    {\n+      tree type = TREE_TYPE (fntype);\n+      if (VOID_TYPE_P (type))\n+\treturn ix86_no_caller_saved_abi_void ();\n+      /* AX register contains the address of the return value location\n+\t passed in by the caller.  */\n+      else if (ix86_return_in_memory (type, fntype))\n+\treturn ix86_no_caller_saved_abi_ax ();\n+      rtx ret = ix86_function_value (type, fntype, false);\n+      unsigned int nregs;\n+      if (REG_P (ret))\n+\t{\n+\t  unsigned int regno = REGNO (ret);\n+\t  if (STACK_REGNO_P (regno) || MMX_REGNO_P (regno))\n+\t    return ix86_no_caller_saved_abi_void ();\n+\t  else\n+\t    switch (regno)\n+\t      {\n+\t      case AX_REG:\n+\t\tnregs = REG_NREGS (ret);\n+\t\tif (nregs == 1)\n+\t\t  return ix86_no_caller_saved_abi_ax ();\n+\t\telse if (nregs == 2)\n+\t\t  return ix86_no_caller_saved_abi_ax_dx ();\n+\t\tbreak;\n+\t      case XMM0_REG:\n+\t\treturn ix86_no_caller_saved_abi_xmm0 ();\n+\t      }\n+\t}\n+      else if (GET_CODE (ret) == PARALLEL && XVECLEN (ret, 0) == 2)\n+\t{\n+\t  rtx x0 = XVECEXP (ret, 0, 0);\n+\t  rtx x1 = XVECEXP (ret, 0, 1);\n+\t  if (GET_CODE (x0) == EXPR_LIST\n+\t      && GET_CODE (x1) == EXPR_LIST)\n+\t    {\n+\t      x0 = XEXP (x0, 0);\n+\t      x1 = XEXP (x1, 0);\n+\t      if (REG_P (x0)\n+\t\t  && REGNO (x0) == XMM0_REG\n+\t\t  && REG_P (x1)\n+\t\t  && REGNO (x1) == XMM1_REG)\n+\t\treturn ix86_no_caller_saved_abi_xmm0_xmm1 ();\n+\t    }\n+\t}\n+\n+      gcc_unreachable ();\n+    }\n+\n+  return default_function_abi;\n+}\n+\n /* Implement TARGET_INSN_CALLEE_ABI.  */\n \n const predefined_function_abi &\n@@ -21769,12 +21982,41 @@ static bool\n ix86_hard_regno_call_part_clobbered (unsigned int abi_id, unsigned int regno,\n \t\t\t\t     machine_mode mode)\n {\n-  /* Special ABI for vzeroupper which only clobber higher part of sse regs.  */\n-  if (abi_id == ABI_VZEROUPPER)\n+  switch (abi_id)\n+    {\n+    case ABI_VZEROUPPER:\n+      /* Special ABI for vzeroupper which only clobbers higher part of\n+\t SSE registers.  */\n       return (GET_MODE_SIZE (mode) > 16\n \t      && ((TARGET_64BIT && REX_SSE_REGNO_P (regno))\n \t\t  || LEGACY_SSE_REGNO_P (regno)));\n \n+    case ABI_DEFAULT:\n+    case ABI_NO_CALLEE_SAVED:\n+      break;\n+\n+    case ABI_NO_CALLER_SAVED_RETURN_VOID:\n+    case ABI_NO_CALLER_SAVED_RETURN_AX:\n+    case ABI_NO_CALLER_SAVED_RETURN_AX_DX:\n+      /* These ABIs don't clobber SSE registers.  */\n+      return false;\n+\n+    case ABI_NO_CALLER_SAVED_RETURN_XMM0:\n+      /* This ABI only clobbers XMM0.  */\n+      if (regno != XMM0_REG)\n+\treturn false;\n+      break;\n+\n+    case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:\n+      /* This ABI only clobbers XMM0 and XMM1.  */\n+      if (regno != XMM0_REG && regno != XMM1_REG)\n+\treturn false;\n+      break;\n+\n+    default:\n+      gcc_unreachable ();\n+    }\n+\n   return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;\n }\n \n@@ -28642,6 +28884,9 @@ ix86_libgcc_floating_mode_supported_p\n #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \\\n   ix86_hard_regno_call_part_clobbered\n \n+#undef TARGET_FNTYPE_ABI\n+#define TARGET_FNTYPE_ABI ix86_fntype_abi\n+\n #undef TARGET_INSN_CALLEE_ABI\n #define TARGET_INSN_CALLEE_ABI ix86_insn_callee_abi\n \ndiff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md\nindex c67b1c7183e..65367ea922d 100644\n--- a/gcc/config/i386/i386.md\n+++ b/gcc/config/i386/i386.md\n@@ -515,7 +515,23 @@ (define_constants\n (define_constants\n   [(ABI_DEFAULT\t\t0)\n    (ABI_VZEROUPPER\t1)\n-   (ABI_UNKNOWN\t\t2)])\n+   (ABI_NO_CALLEE_SAVED 2)\n+   ;; Return void.\n+   (ABI_NO_CALLER_SAVED_RETURN_VOID 3)\n+   ;; Return char, short, int in 32-bit/64-bit.\n+   ;; Return int64 and _Complex int in 64-bit.\n+   ;; Return _Complex float in MS 32-bit/64-bit.\n+   (ABI_NO_CALLER_SAVED_RETURN_AX 4)\n+   ;; Return int64 and _Complex int in 32-bit.\n+   ;; Return _Complex int64 in 64-bit.\n+   (ABI_NO_CALLER_SAVED_RETURN_AX_DX 5)\n+   ;; Return float and double in 64-bit.\n+   ;; Return _Complex float in SYSV 64-bit.\n+   ;; Return int28, _Complex double in MS 64-bit.\n+   (ABI_NO_CALLER_SAVED_RETURN_XMM0 6)\n+   ;; Return _Complex double in SYSV 64-bit.\n+   (ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1 7)\n+   (ABI_UNKNOWN\t\t8)])\n \n ;; Insns whose names begin with \"x86_\" are emitted by gen_FOO calls\n ;; from i386.cc.\ndiff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-2.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-2.c\nindex e074ca51df4..86864ea9bff 100644\n--- a/gcc/testsuite/gcc.target/i386/no-callee-saved-2.c\n+++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-2.c\n@@ -26,7 +26,9 @@ foo (void *frame)\n   }\n }\n \n-/* { dg-final { scan-assembler-times \"push(?:l|q)\\[\\\\t \\]*%(?:e|r)bp\" 1 } } */\n-/* { dg-final { scan-assembler-times \"pop(?:l|q)\\[\\\\t \\]*%(?:e|r)bp\" 1 } } */\n-/* { dg-final { scan-assembler-times \"push(?:l|q)\\[\\\\t \\]*\" 1 } } */\n-/* { dg-final { scan-assembler-times \"pop(?:l|q)\\[\\\\t \\]*\" 1 } } */\n+/* { dg-final { scan-assembler-times \"push(?:l|q)\\[\\\\t \\]*%(?:e|r)bp\" 1 { target ia32 } } } */\n+/* { dg-final { scan-assembler-times \"pop(?:l|q)\\[\\\\t \\]*%(?:e|r)bp\" 1 { target ia32 } } } */\n+/* { dg-final { scan-assembler-times \"push(?:l|q)\\[\\\\t \\]*\" 1 { target ia32 } } } */\n+/* { dg-final { scan-assembler-times \"pop(?:l|q)\\[\\\\t \\]*\" 1 { target ia32 } } } */\n+/* { dg-final { scan-assembler-not \"push(?:l|q)\\[\\\\t \\]*\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"pop(?:l|q)\\[\\\\t \\]*\" { target { ! ia32 } } } } */\ndiff --git a/gcc/testsuite/gcc.target/i386/no-caller-saved-1.c b/gcc/testsuite/gcc.target/i386/no-caller-saved-1.c\nnew file mode 100644\nindex 00000000000..e675f4327cb\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/i386/no-caller-saved-1.c\n@@ -0,0 +1,46 @@\n+/* PR target/124798  */\n+/* { dg-do compile } */\n+/* { dg-options \"-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer\" } */\n+\n+[[gnu::no_caller_saved_registers]] extern void foo (void);\n+\n+void\n+qux (void)\n+{\n+  int a, b, c, d, e, f;\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t: \"=r\" (a), \"=r\" (b), \"=r\" (c), \"=r\" (d), \"=r\" (e), \"=r\" (f));\n+#ifdef __x86_64__\n+  int g, h, i, j, k, l, m, n, o, p;\n+  asm volatile (\"# %0 %1\"\n+\t\t: \"=r\" (g), \"=r\" (h));\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: \"=r\" (i), \"=r\" (j), \"=r\" (k), \"=r\" (l), \"=r\" (m), \"=r\" (n), \"=r\" (o), \"=r\" (p));\n+#endif\n+  foo ();\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t:: \"r\" (a), \"r\" (b), \"r\" (c), \"r\" (d), \"r\" (e), \"r\" (f));\n+#ifdef __x86_64__\n+  asm volatile (\"# %0 %1\"\n+\t\t:: \"r\" (g), \"r\" (h));\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: : \"r\" (i), \"r\" (j), \"r\" (k), \"r\" (l), \"r\" (m), \"r\" (n), \"r\" (o), \"r\" (p));\n+#endif\n+}\n+\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%edx, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%ecx, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%esi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%edi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %edx\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %ecx\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %esi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %edi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r8d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r9d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r10d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r11d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r8d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r9d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r10d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r11d\" { target { ! ia32 } } } } */\ndiff --git a/gcc/testsuite/gcc.target/i386/no-caller-saved-2.c b/gcc/testsuite/gcc.target/i386/no-caller-saved-2.c\nnew file mode 100644\nindex 00000000000..0a7e443b3db\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/i386/no-caller-saved-2.c\n@@ -0,0 +1,45 @@\n+/* PR target/124798  */\n+/* { dg-do compile } */\n+/* { dg-options \"-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer\" } */\n+\n+[[gnu::no_caller_saved_registers]] extern int foo (void);\n+\n+int\n+qux (void)\n+{\n+  int a, b, c, d, e, f;\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t: \"=r\" (a), \"=r\" (b), \"=r\" (c), \"=r\" (d), \"=r\" (e), \"=r\" (f));\n+#ifdef __x86_64__\n+  int g, h, i, j, k, l, m, n, o, p;\n+  asm volatile (\"# %0 %1\"\n+\t\t: \"=r\" (g), \"=r\" (h));\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: \"=r\" (i), \"=r\" (j), \"=r\" (k), \"=r\" (l), \"=r\" (m), \"=r\" (n), \"=r\" (o), \"=r\" (p));\n+#endif\n+  int ret = foo ();\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t:: \"r\" (a), \"r\" (b), \"r\" (c), \"r\" (d), \"r\" (e), \"r\" (f));\n+#ifdef __x86_64__\n+  asm volatile (\"# %0 %1\"\n+\t\t:: \"r\" (g), \"r\" (h));\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: : \"r\" (i), \"r\" (j), \"r\" (k), \"r\" (l), \"r\" (m), \"r\" (n), \"r\" (o), \"r\" (p));\n+#endif\n+\n+  return ret;\n+}\n+\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%ecx, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%esi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%edi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %ecx\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %esi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %edi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r8d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r9d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r10d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r11d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r8d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r9d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r11d\" { target { ! ia32 } } } } */\ndiff --git a/gcc/testsuite/gcc.target/i386/no-caller-saved-3.c b/gcc/testsuite/gcc.target/i386/no-caller-saved-3.c\nnew file mode 100644\nindex 00000000000..e940ee85cfe\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/i386/no-caller-saved-3.c\n@@ -0,0 +1,44 @@\n+/* PR target/124798  */\n+/* { dg-do compile } */\n+/* { dg-options \"-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer\" } */\n+\n+[[gnu::no_caller_saved_registers]] extern long long foo (void);\n+\n+long long\n+qux (void)\n+{\n+  int a, b, c, d, e, f;\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t: \"=r\" (a), \"=r\" (b), \"=r\" (c), \"=r\" (d), \"=r\" (e), \"=r\" (f));\n+#ifdef __x86_64__\n+  int g, h, i, j, k, l, m, n;\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: \"=r\" (g), \"=r\" (h), \"=r\" (i), \"=r\" (j), \"=r\" (k), \"=r\" (l), \"=r\" (m), \"=r\" (n));\n+#endif\n+  long long ret = foo ();\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t:: \"r\" (a), \"r\" (b), \"r\" (c), \"r\" (d), \"r\" (e), \"r\" (f));\n+#ifdef __x86_64__\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: : \"r\" (g), \"r\" (h), \"r\" (i), \"r\" (j), \"r\" (k), \"r\" (l), \"r\" (m), \"r\" (n));\n+#endif\n+\n+  return ret;\n+}\n+\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%ecx, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%esi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%edi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %ecx\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %esi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %edi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%edx, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r8d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r9d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r10d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r11d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %edx\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r8d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r9d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r10d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r11d\" { target { ! ia32 } } } } */\ndiff --git a/gcc/testsuite/gcc.target/i386/no-caller-saved-4.c b/gcc/testsuite/gcc.target/i386/no-caller-saved-4.c\nnew file mode 100644\nindex 00000000000..e52a0cd9c4b\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/i386/no-caller-saved-4.c\n@@ -0,0 +1,44 @@\n+/* PR target/124798  */\n+/* { dg-do compile { target int128 } } */\n+/* { dg-options \"-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer\" } */\n+\n+[[gnu::no_caller_saved_registers]] extern __int128 foo (void);\n+\n+__int128\n+qux (void)\n+{\n+  int a, b, c, d, e, f;\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t: \"=r\" (a), \"=r\" (b), \"=r\" (c), \"=r\" (d), \"=r\" (e), \"=r\" (f));\n+#ifdef __x86_64__\n+  int g, h, i, j, k, l, m, n;\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: \"=r\" (g), \"=r\" (h), \"=r\" (i), \"=r\" (j), \"=r\" (k), \"=r\" (l), \"=r\" (m), \"=r\" (n));\n+#endif\n+  __int128 ret = foo ();\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t:: \"r\" (a), \"r\" (b), \"r\" (c), \"r\" (d), \"r\" (e), \"r\" (f));\n+#ifdef __x86_64__\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: : \"r\" (g), \"r\" (h), \"r\" (i), \"r\" (j), \"r\" (k), \"r\" (l), \"r\" (m), \"r\" (n));\n+#endif\n+\n+  return ret;\n+}\n+\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%edx, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%ecx, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%esi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%edi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %edx\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %ecx\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %esi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %edi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r8d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r9d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r10d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r11d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r8d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r9d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r10d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r11d\" { target { ! ia32 } } } } */\ndiff --git a/gcc/testsuite/gcc.target/i386/no-caller-saved-5.c b/gcc/testsuite/gcc.target/i386/no-caller-saved-5.c\nnew file mode 100644\nindex 00000000000..98f58fe92f5\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/i386/no-caller-saved-5.c\n@@ -0,0 +1,34 @@\n+/* PR target/124798  */\n+/* { dg-do compile } */\n+/* { dg-options \"-O2 -mtune=corei7 -msse2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer\" } */\n+\n+[[gnu::no_caller_saved_registers]] extern float foo (void);\n+\n+float\n+qux (void)\n+{\n+  float a, b, c, d, e, f;\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t: \"=v\" (a), \"=v\" (b), \"=v\" (c), \"=v\" (d), \"=v\" (e), \"=v\" (f));\n+#ifdef __x86_64__\n+  float g, h, i, j, k, l, m, n, o, p;\n+  asm volatile (\"# %0 %1\"\n+\t\t: \"=v\" (g), \"=v\" (h));\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: \"=v\" (i), \"=v\" (j), \"=v\" (k), \"=v\" (l), \"=v\" (m), \"=v\" (n), \"=v\" (o), \"=v\" (p));\n+#endif\n+  float ret = foo ();\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t:: \"v\" (a), \"v\" (b), \"v\" (c), \"v\" (d), \"v\" (e), \"v\" (f));\n+#ifdef __x86_64__\n+  asm volatile (\"# %0 %1\"\n+\t\t:: \"v\" (g), \"v\" (h));\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: : \"v\" (i), \"v\" (j), \"v\" (k), \"v\" (l), \"v\" (m), \"v\" (n), \"v\" (o), \"v\" (p));\n+#endif\n+\n+  return ret;\n+}\n+\n+/* { dg-final { scan-assembler-not \"movss\\[ \\\\t\\]+%xmm\\[0-9\\]+, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %xmm\\[0-9\\]+\" } } */\ndiff --git a/gcc/testsuite/gcc.target/i386/no-caller-saved-6.c b/gcc/testsuite/gcc.target/i386/no-caller-saved-6.c\nnew file mode 100644\nindex 00000000000..5eb5b102843\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/i386/no-caller-saved-6.c\n@@ -0,0 +1,34 @@\n+/* PR target/124798  */\n+/* { dg-do compile } */\n+/* { dg-options \"-O2 -mtune=corei7 -msse2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer\" } */\n+\n+[[gnu::no_caller_saved_registers]] extern _Complex double foo (void);\n+\n+_Complex double\n+qux (void)\n+{\n+  double a, b, c, d, e, f;\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t: \"=v\" (a), \"=v\" (b), \"=v\" (c), \"=v\" (d), \"=v\" (e), \"=v\" (f));\n+#ifdef __x86_64__\n+  double g, h, i, j, k, l, m, n, o, p;\n+  asm volatile (\"# %0 %1\"\n+\t\t: \"=v\" (g), \"=v\" (h));\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: \"=v\" (i), \"=v\" (j), \"=v\" (k), \"=v\" (l), \"=v\" (m), \"=v\" (n), \"=v\" (o), \"=v\" (p));\n+#endif\n+  _Complex double ret = foo ();\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t:: \"v\" (a), \"v\" (b), \"v\" (c), \"v\" (d), \"v\" (e), \"v\" (f));\n+#ifdef __x86_64__\n+  asm volatile (\"# %0 %1\"\n+\t\t:: \"v\" (g), \"v\" (h));\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5 %6 %7\"\n+\t\t: : \"v\" (i), \"v\" (j), \"v\" (k), \"v\" (l), \"v\" (m), \"v\" (n), \"v\" (o), \"v\" (p));\n+#endif\n+\n+  return ret;\n+}\n+\n+/* { dg-final { scan-assembler-not \"movss\\[ \\\\t\\]+%xmm\\[0-9\\]+, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %xmm\\[0-9\\]+\" } } */\ndiff --git a/gcc/testsuite/gcc.target/i386/no-caller-saved-7.c b/gcc/testsuite/gcc.target/i386/no-caller-saved-7.c\nnew file mode 100644\nindex 00000000000..c8a99e950da\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/i386/no-caller-saved-7.c\n@@ -0,0 +1,49 @@\n+/* PR target/124798  */\n+/* { dg-do compile } */\n+/* { dg-options \"-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer\" } */\n+\n+typedef struct\n+{\n+  double d[16];\n+} record;\n+\n+[[gnu::no_caller_saved_registers]] extern record foo (void);\n+\n+record\n+qux (void)\n+{\n+  int a, b, c, d, e, f;\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t: \"=r\" (a), \"=r\" (b), \"=r\" (c), \"=r\" (d), \"=r\" (e), \"=r\" (f));\n+#ifdef __x86_64__\n+  int g, h, i, j;\n+  asm volatile (\"# %0 %1 %2 %3\"\n+\t\t: \"=r\" (g), \"=r\" (h), \"=r\" (i), \"=r\" (j));\n+#endif\n+  record ret = foo ();\n+  asm volatile (\"# %0 %1 %2 %3 %4 %5\"\n+\t\t:: \"r\" (a), \"r\" (b), \"r\" (c), \"r\" (d), \"r\" (e), \"r\" (f));\n+#ifdef __x86_64__\n+  asm volatile (\"# %0 %1 %2 %3\"\n+\t\t:: \"r\" (g), \"r\" (h), \"r\" (i), \"r\" (j));\n+#endif\n+\n+  return ret;\n+}\n+\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%edx, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%ecx, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%esi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%edi, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %edx\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %ecx\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %esi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %edi\" } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r8d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r9d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r10d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+%r11d, \\[0-9\\]*\\\\(%\\[re\\]?sp\\\\)\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r8d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r9d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r10d\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"mov(l|q)\\[ \\\\t\\]+\\[0-9\\]*\\\\(%\\[re\\]?sp\\\\), %r11d\" { target { ! ia32 } } } } */\ndiff --git a/gcc/testsuite/gcc.target/i386/preserve-none-7.c b/gcc/testsuite/gcc.target/i386/preserve-none-7.c\nindex 2c80560887c..6f252ee50a4 100644\n--- a/gcc/testsuite/gcc.target/i386/preserve-none-7.c\n+++ b/gcc/testsuite/gcc.target/i386/preserve-none-7.c\n@@ -26,7 +26,9 @@ foo (void *frame)\n   }\n }\n \n-/* { dg-final { scan-assembler-times \"push(?:l|q)\\[\\\\t \\]*%(?:e|r)bp\" 1 } } */\n-/* { dg-final { scan-assembler-times \"pop(?:l|q)\\[\\\\t \\]*%(?:e|r)bp\" 1 } } */\n-/* { dg-final { scan-assembler-times \"push(?:l|q)\\[\\\\t \\]*\" 1 } } */\n-/* { dg-final { scan-assembler-times \"pop(?:l|q)\\[\\\\t \\]*\" 1 } } */\n+/* { dg-final { scan-assembler-times \"push(?:l|q)\\[\\\\t \\]*%(?:e|r)bp\" 1 { target ia32 } } } */\n+/* { dg-final { scan-assembler-times \"pop(?:l|q)\\[\\\\t \\]*%(?:e|r)bp\" 1 { target ia32 } } } */\n+/* { dg-final { scan-assembler-times \"push(?:l|q)\\[\\\\t \\]*\" 1 { target ia32 } } } */\n+/* { dg-final { scan-assembler-times \"pop(?:l|q)\\[\\\\t \\]*\" 1 { target ia32 } } } */\n+/* { dg-final { scan-assembler-not \"push(?:l|q)\\[\\\\t \\]*\" { target { ! ia32 } } } } */\n+/* { dg-final { scan-assembler-not \"pop(?:l|q)\\[\\\\t \\]*\" { target { ! ia32 } } } } */\n-- \n2.53.0\n\n",
    "prefixes": []
}