From patchwork Mon Aug 28 08:39:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 111130 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp4555717qge; Mon, 28 Aug 2017 02:05:23 -0700 (PDT) X-Received: by 10.98.56.195 with SMTP id f186mr6739537pfa.254.1503911123448; Mon, 28 Aug 2017 02:05:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503911123; cv=none; d=google.com; s=arc-20160816; b=0LLMJan7dxFToBxVczjRSBD1Umlqmtq6dV+VALBo9IWSqYc0BZ54qKNAF7A0xUtszF LfRrxIUrFd0+SBXycGzgQfXBJ5vwwBNgD3mtZ6rht0JideDgKwycV9fOcpgyq8PV11Fe wr7LvYkovf9hkBVVY783n9xzVTC8K5RJDFPb99bNU8qMBMZW37qTGbKuKF8A7TwegMYe qbSZ2t8m1F/UOMjpmX0J2we5+0K/CWySUsiqaRjlWHnkpgk5VTB4uXJ1CTEMvC7iGknc O89Y/Ox/qxSy1J1pWaxhFQvrkHbDAptURtuUBkivevp2OCEO+xyxJZSxhtPSMqP+G/Xc eKDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:date:subject:mail-followup-to:to :from:delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=6RF5X4JDdT8dh1TrrxJelQc37qeH95gQa/xVv3LRPco=; b=M10b8WEFAQLGwW7CT/n0gCnMSk75aiKtbFotugF36XaVJoIwrLwJw2035ij9Sx03jp Gy7KBFMauHqqrB2qSe7vbcG2yGPOZkJqpD1x22UTRNcKwsiYkDcPzsYH8h68bewS0eYS g2vo6QnwySLeZbEanyauotdfqJW1tXXK+cBU4lwyRqvTKP6sS7gFIzuaqCBkZWqP86JC TcCM5qm9OM5fmnIOT+c1aE5YOLsNrlLCstigniXihgjCBc0TuNIeM3WJDr7v3F6tF1Db HKD82/q/fR1WthfjvHKCfcdpWGaBatb5SYH5zOoj/mbc0KHoac71dQCjmYlBzjJlMOYS kuag== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=i6uyoMH6; spf=pass (google.com: domain of gcc-patches-return-461001-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-461001-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id k186si9211306pfc.280.2017.08.28.02.05.23 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 28 Aug 2017 02:05:23 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-461001-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=i6uyoMH6; spf=pass (google.com: domain of gcc-patches-return-461001-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-461001-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=De6vtEpfT2dfB5YBH9GKDamOPGSWsOlsaCFH1JO+Kw7Rs4vWPiTxC fK/unjgTDjX27BaEfu8rv9XjbUGksTgxpW28Hi7wiEfFIhmhgPFTBa3MI2fSzKD5 TtHuxhsPNhX4tXHcKi66APXCWZyU0ytVrOzIv47u3MFvOF0TooaOG8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; s= default; bh=Y7D4njIUHXmmFxV9q6Z7RdqUc1Q=; b=i6uyoMH6CXXowYtkAJL9 RVu/nMQmEdKubqedrUMgAxUMwctzScYIQc6YDoalNCkdOo9dv32TngE2hw2T6j4d GpAukGzOOWYsWXFKldVZmfvFX4iSN3w4PTnJj1k7jmbfKlz0OV5JA8fmTqSqwM7d CC+3iok6CGyhEfnC5fdOcV8= Received: (qmail 37161 invoked by alias); 28 Aug 2017 08:57:38 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 31364 invoked by uid 89); 28 Aug 2017 08:40:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-15.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=reserves, approximately, enumerated X-HELO: mail-wr0-f173.google.com Received: from mail-wr0-f173.google.com (HELO mail-wr0-f173.google.com) (209.85.128.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 28 Aug 2017 08:39:56 +0000 Received: by mail-wr0-f173.google.com with SMTP id a47so16388499wra.4 for ; Mon, 28 Aug 2017 01:39:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:date:message-id :user-agent:mime-version; bh=6RF5X4JDdT8dh1TrrxJelQc37qeH95gQa/xVv3LRPco=; b=RyL7VRr/nqDEVvLciaeFd4tZTVn+d30rMd24lfRonqGtDIUkp35Y9YQm6RCu2mYJL8 iRzvDjVrB+PfD+TqJT5ML09217HL8hF8B8ssDiOmHIA0MzucotKfMUIkusrg+c1cREAb pDllPZo8v/XcV4ekiJG9/QjGH/UxOEaorZCTdq8RYYS76ss5cnAKO6tZ/ly/AGfK23Gl qOvqKd2AaVuotoRsomla/0NBsS55Cy2nC4ouE6YcqJ/klCtu8Vayl+PyfZ1gAEmGOJAk 4Z9GzlzjDN8WQTO7T7wabiZpLN3wP2Mdgpa57EeiGV3117fcPqheAAL3hTsGQOLp3GnM DOKQ== X-Gm-Message-State: AHYfb5hDGzMYRQsyv1uVYEgLeqESMR4g/NesXl/NtpxBT+UMiRnQQUKO UU/P1StIUSwGQYj3fQTIiw== X-Received: by 10.223.167.71 with SMTP id e7mr3843849wrd.205.1503909592465; Mon, 28 Aug 2017 01:39:52 -0700 (PDT) Received: from localhost ([95.145.139.63]) by smtp.gmail.com with ESMTPSA id i80sm10646942wmh.40.2017.08.28.01.39.49 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 28 Aug 2017 01:39:51 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: Turn HARD_REGNO_CALL_PART_CLOBBERED into a target hook Date: Mon, 28 Aug 2017 09:39:58 +0100 Message-ID: <87inh8t7a9.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 The SVE patches change the size of a machine_mode from a compile-time constant to a runtime invariant. However, target-specific code can continue to treat the modes as constant-sized if the target only has constant-sized modes. The main snag with this approach is that target-independent code still uses macros from the target .h file. This patch is one of several that converts a target macro to a hook. Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu. Also tested by checking that there were no extra warnings or changes in testsuite assembly output for at least one target per CPU. OK to install? Richard 2017-08-28 Richard Sandiford Alan Hayward David Sherwood gcc/ * target.def (hard_regno_call_part_clobbered): New hook. * doc/tm.texi.in (HARD_REGNO_CALL_PART_CLOBBERED): Replace with... (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): ...this hook. * doc/tm.texi: Regenerate. * hooks.h (hook_bool_uint_mode_false): Declare. * hooks.c (hook_bool_uint_mode_false): New function. * regs.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete. * cselib.c (cselib_process_insn): Use targetm.hard_regno_call_part_clobbered instead of HARD_REGNO_CALL_PART_CLOBBERED. * ira-conflicts.c (ira_build_conflicts): Likewise. * ira-costs.c (ira_tune_allocno_costs): Likewise. * lra-constraints.c (need_for_call_save_p): Likewise. * lra-lives.c: Include target.h. (check_pseudos_live_through_calls): Use targetm.hard_regno_call_part_clobbered instead of HARD_REGNO_CALL_PART_CLOBBERED. * regcprop.c: Include target.h. (copyprop_hardreg_forward_1): Use targetm.hard_regno_call_part_clobbered instead of HARD_REGNO_CALL_PART_CLOBBERED. * reginfo.c (choose_hard_reg_mode): Likewise. * regrename.c (check_new_reg_p): Likewise. * reload.c (find_equiv_reg): Likewise. * reload1.c (emit_reload_insns): Likewise. * sched-deps.c (deps_analyze_insn): Likewise. * sel-sched.c (init_regs_for_mode): Likewise. (mark_unavailable_hard_regs): Likewise. * targhooks.c (default_dwarf_frame_reg_mode): Likewise. * config/aarch64/aarch64.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete. * config/aarch64/aarch64.c (aarch64_hard_regno_call_part_clobbered): New function. (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine. * config/avr/avr.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete. * config/avr/avr-protos.h (avr_hard_regno_call_part_clobbered): Delete. * config/avr/avr.c (avr_hard_regno_call_part_clobbered): Make static and return a bool. (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine. * config/i386/i386.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete. * config/i386/i386.c (ix86_hard_regno_call_part_clobbered): New function. (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine. * config/mips/mips.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete. * config/mips/mips.c (mips_hard_regno_call_part_clobbered): New function. (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine. * config/powerpcspe/powerpcspe.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete. * config/powerpcspe/powerpcspe.c (rs6000_hard_regno_call_part_clobbered): New function. (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine. * config/rs6000/rs6000.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete. * config/rs6000/rs6000.c (rs6000_hard_regno_call_part_clobbered): New function. (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine. * config/s390/s390.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete. * config/s390/s390.c (s390_hard_regno_call_part_clobbered): New function. (TARGET_HARD_REGNO_CALL_PART_CLOBBERED): Redefine. * config/sh/sh.h (HARD_REGNO_CALL_PART_CLOBBERED): Delete. * system.h (HARD_REGNO_CALL_PART_CLOBBERED): Poison. Index: gcc/target.def =================================================================== --- gcc/target.def 2017-08-28 09:36:09.610827107 +0100 +++ gcc/target.def 2017-08-28 09:36:10.075827140 +0100 @@ -5395,6 +5395,19 @@ The default version of this hook always bool, (unsigned int regno), default_hard_regno_scratch_ok) +DEFHOOK +(hard_regno_call_part_clobbered, + "This hook should return true if @var{regno} is partly call-saved and\n\ +partly call-clobbered, and if a value of mode @var{mode} would be partly\n\ +clobbered by a call. For example, if the low 32 bits of @var{regno} are\n\ +preserved across a call but higher bits are clobbered, this hook should\n\ +return true for a 64-bit mode but false for a 32-bit mode.\n\ +\n\ +The default implementation returns false, which is correct\n\ +for targets that don't have partly call-clobbered registers.", + bool, (unsigned int regno, machine_mode mode), + hook_bool_uint_mode_false) + /* Return the smallest number of different values for which it is best to use a jump-table instead of a tree of conditional branches. */ DEFHOOK Index: gcc/doc/tm.texi.in =================================================================== --- gcc/doc/tm.texi.in 2017-08-28 09:36:09.610827107 +0100 +++ gcc/doc/tm.texi.in 2017-08-28 09:36:10.070827139 +0100 @@ -1698,16 +1698,10 @@ This macro is optional. If not specifie of @code{CALL_USED_REGISTERS}. @end defmac -@defmac HARD_REGNO_CALL_PART_CLOBBERED (@var{regno}, @var{mode}) @cindex call-used register @cindex call-clobbered register @cindex call-saved register -A C expression that is nonzero if it is not permissible to store a -value of mode @var{mode} in hard register number @var{regno} across a -call without some part of it being clobbered. For most machines this -macro need not be defined. It is only required for machines that do not -preserve the entire contents of a register across a call. -@end defmac +@hook TARGET_HARD_REGNO_CALL_PART_CLOBBERED @findex fixed_regs @findex call_used_regs Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi 2017-08-28 09:36:09.610827107 +0100 +++ gcc/doc/tm.texi 2017-08-28 09:36:10.069827139 +0100 @@ -1869,16 +1869,19 @@ This macro is optional. If not specifie of @code{CALL_USED_REGISTERS}. @end defmac -@defmac HARD_REGNO_CALL_PART_CLOBBERED (@var{regno}, @var{mode}) @cindex call-used register @cindex call-clobbered register @cindex call-saved register -A C expression that is nonzero if it is not permissible to store a -value of mode @var{mode} in hard register number @var{regno} across a -call without some part of it being clobbered. For most machines this -macro need not be defined. It is only required for machines that do not -preserve the entire contents of a register across a call. -@end defmac +@deftypefn {Target Hook} bool TARGET_HARD_REGNO_CALL_PART_CLOBBERED (unsigned int @var{regno}, machine_mode @var{mode}) +This hook should return true if @var{regno} is partly call-saved and +partly call-clobbered, and if a value of mode @var{mode} would be partly +clobbered by a call. For example, if the low 32 bits of @var{regno} are +preserved across a call but higher bits are clobbered, this hook should +return true for a 64-bit mode but false for a 32-bit mode. + +The default implementation returns false, which is correct +for targets that don't have partly call-clobbered registers. +@end deftypefn @findex fixed_regs @findex call_used_regs Index: gcc/hooks.h =================================================================== --- gcc/hooks.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/hooks.h 2017-08-28 09:36:10.070827139 +0100 @@ -38,6 +38,7 @@ extern bool hook_bool_const_rtx_insn_con const rtx_insn *); extern bool hook_bool_mode_uhwi_false (machine_mode, unsigned HOST_WIDE_INT); +extern bool hook_bool_uint_mode_false (unsigned int, machine_mode); extern bool hook_bool_tree_false (tree); extern bool hook_bool_const_tree_false (const_tree); extern bool hook_bool_tree_true (tree); Index: gcc/hooks.c =================================================================== --- gcc/hooks.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/hooks.c 2017-08-28 09:36:10.070827139 +0100 @@ -126,6 +126,13 @@ hook_bool_mode_uhwi_false (machine_mode, return false; } +/* Generic hook that takes (unsigned int, machine_mode) and returns false. */ +bool +hook_bool_uint_mode_false (unsigned int, machine_mode) +{ + return false; +} + /* Generic hook that takes (FILE *, const char *) and does nothing. */ void hook_void_FILEptr_constcharptr (FILE *, const char *) Index: gcc/regs.h =================================================================== --- gcc/regs.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/regs.h 2017-08-28 09:36:10.072827140 +0100 @@ -193,12 +193,6 @@ #define HARD_REGNO_CALLER_SAVE_MODE(REGN choose_hard_reg_mode (REGNO, NREGS, false) #endif -/* Registers that get partially clobbered by a call in a given mode. - These must not be call used registers. */ -#ifndef HARD_REGNO_CALL_PART_CLOBBERED -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) 0 -#endif - /* Target-dependent globals. */ struct target_regs { /* For each starting hard register, the number of consecutive hard Index: gcc/cselib.c =================================================================== --- gcc/cselib.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/cselib.c 2017-08-28 09:36:10.068827139 +0100 @@ -2660,8 +2660,8 @@ cselib_process_insn (rtx_insn *insn) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (call_used_regs[i] || (REG_VALUES (i) && REG_VALUES (i)->elt - && HARD_REGNO_CALL_PART_CLOBBERED (i, - GET_MODE (REG_VALUES (i)->elt->val_rtx)))) + && (targetm.hard_regno_call_part_clobbered + (i, GET_MODE (REG_VALUES (i)->elt->val_rtx))))) cselib_invalidate_regno (i, reg_raw_mode[i]); /* Since it is not clear how cselib is going to be used, be Index: gcc/ira-conflicts.c =================================================================== --- gcc/ira-conflicts.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/ira-conflicts.c 2017-08-28 09:36:10.070827139 +0100 @@ -743,6 +743,7 @@ ira_build_conflicts (void) for (i = 0; i < n; i++) { ira_object_t obj = ALLOCNO_OBJECT (a, i); + machine_mode obj_mode = obj->allocno->mode; rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)]; if ((! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0) @@ -804,8 +805,8 @@ ira_build_conflicts (void) regs must conflict with them. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (!TEST_HARD_REG_BIT (call_used_reg_set, regno) - && HARD_REGNO_CALL_PART_CLOBBERED (regno, - obj->allocno->mode)) + && targetm.hard_regno_call_part_clobbered (regno, + obj_mode)) { SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno); SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), Index: gcc/ira-costs.c =================================================================== --- gcc/ira-costs.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/ira-costs.c 2017-08-28 09:36:10.071827140 +0100 @@ -2341,7 +2341,8 @@ ira_tune_allocno_costs (void) *crossed_calls_clobber_regs) && (ira_hard_reg_set_intersection_p (regno, mode, call_used_reg_set) - || HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))) + || targetm.hard_regno_call_part_clobbered (regno, + mode))) cost += (ALLOCNO_CALL_FREQ (a) * (ira_memory_move_cost[mode][rclass][0] + ira_memory_move_cost[mode][rclass][1])); Index: gcc/lra-constraints.c =================================================================== --- gcc/lra-constraints.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/lra-constraints.c 2017-08-28 09:36:10.071827140 +0100 @@ -5287,8 +5287,8 @@ need_for_call_save_p (int regno) ? lra_reg_info[regno].actual_call_used_reg_set : call_used_reg_set, PSEUDO_REGNO_MODE (regno), reg_renumber[regno]) - || HARD_REGNO_CALL_PART_CLOBBERED (reg_renumber[regno], - PSEUDO_REGNO_MODE (regno)))); + || (targetm.hard_regno_call_part_clobbered + (reg_renumber[regno], PSEUDO_REGNO_MODE (regno))))); } /* Global registers occurring in the current EBB. */ Index: gcc/lra-lives.c =================================================================== --- gcc/lra-lives.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/lra-lives.c 2017-08-28 09:36:10.072827140 +0100 @@ -42,6 +42,7 @@ Software Foundation; either version 3, o #include "cfganal.h" #include "sparseset.h" #include "lra-int.h" +#include "target.h" /* Program points are enumerated by numbers from range 0..LRA_LIVE_MAX_POINT-1. There are approximately two times more @@ -575,7 +576,8 @@ check_pseudos_live_through_calls (int re last_call_used_reg_set); for (hr = 0; hr < FIRST_PSEUDO_REGISTER; hr++) - if (HARD_REGNO_CALL_PART_CLOBBERED (hr, PSEUDO_REGNO_MODE (regno))) + if (targetm.hard_regno_call_part_clobbered (hr, + PSEUDO_REGNO_MODE (regno))) SET_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, hr); lra_reg_info[regno].call_p = true; if (! sparseset_bit_p (pseudos_live_through_setjumps, regno)) Index: gcc/regcprop.c =================================================================== --- gcc/regcprop.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/regcprop.c 2017-08-28 09:36:10.072827140 +0100 @@ -34,6 +34,7 @@ #include "tree-pass.h" #include "rtl-iter.h" #include "cfgrtl.h" +#include "target.h" /* The following code does forward propagation of hard register copies. The object is to eliminate as many dependencies as possible, so that @@ -1049,7 +1050,8 @@ copyprop_hardreg_forward_1 (basic_block regs_invalidated_by_call); for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if ((TEST_HARD_REG_BIT (regs_invalidated_by_this_call, regno) - || HARD_REGNO_CALL_PART_CLOBBERED (regno, vd->e[regno].mode)) + || (targetm.hard_regno_call_part_clobbered + (regno, vd->e[regno].mode))) && (regno < set_regno || regno >= set_regno + set_nregs)) kill_value_regno (regno, 1, vd); Index: gcc/reginfo.c =================================================================== --- gcc/reginfo.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/reginfo.c 2017-08-28 09:36:10.072827140 +0100 @@ -637,7 +637,8 @@ choose_hard_reg_mode (unsigned int regno mode = GET_MODE_WIDER_MODE (mode)) if ((unsigned) hard_regno_nregs[regno][mode] == nregs && HARD_REGNO_MODE_OK (regno, mode) - && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) + && (!call_saved + || !targetm.hard_regno_call_part_clobbered (regno, mode)) && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) found_mode = mode; @@ -646,7 +647,8 @@ choose_hard_reg_mode (unsigned int regno mode = GET_MODE_WIDER_MODE (mode)) if ((unsigned) hard_regno_nregs[regno][mode] == nregs && HARD_REGNO_MODE_OK (regno, mode) - && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) + && (!call_saved + || !targetm.hard_regno_call_part_clobbered (regno, mode)) && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) found_mode = mode; @@ -655,7 +657,8 @@ choose_hard_reg_mode (unsigned int regno mode = GET_MODE_WIDER_MODE (mode)) if ((unsigned) hard_regno_nregs[regno][mode] == nregs && HARD_REGNO_MODE_OK (regno, mode) - && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) + && (!call_saved + || !targetm.hard_regno_call_part_clobbered (regno, mode)) && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) found_mode = mode; @@ -664,7 +667,8 @@ choose_hard_reg_mode (unsigned int regno mode = GET_MODE_WIDER_MODE (mode)) if ((unsigned) hard_regno_nregs[regno][mode] == nregs && HARD_REGNO_MODE_OK (regno, mode) - && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) + && (!call_saved + || !targetm.hard_regno_call_part_clobbered (regno, mode)) && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) found_mode = mode; @@ -677,7 +681,8 @@ choose_hard_reg_mode (unsigned int regno mode = (machine_mode) m; if ((unsigned) hard_regno_nregs[regno][mode] == nregs && HARD_REGNO_MODE_OK (regno, mode) - && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))) + && (!call_saved + || !targetm.hard_regno_call_part_clobbered (regno, mode))) return mode; } Index: gcc/regrename.c =================================================================== --- gcc/regrename.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/regrename.c 2017-08-28 09:36:10.072827140 +0100 @@ -338,9 +338,9 @@ check_new_reg_p (int reg ATTRIBUTE_UNUSE if ((! HARD_REGNO_MODE_OK (new_reg, GET_MODE (*tmp->loc)) && ! DEBUG_INSN_P (tmp->insn)) || (this_head->need_caller_save_reg - && ! (HARD_REGNO_CALL_PART_CLOBBERED + && ! (targetm.hard_regno_call_part_clobbered (reg, GET_MODE (*tmp->loc))) - && (HARD_REGNO_CALL_PART_CLOBBERED + && (targetm.hard_regno_call_part_clobbered (new_reg, GET_MODE (*tmp->loc))))) return false; Index: gcc/reload.c =================================================================== --- gcc/reload.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/reload.c 2017-08-28 09:36:10.073827140 +0100 @@ -6922,13 +6922,14 @@ find_equiv_reg (rtx goal, rtx_insn *insn if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER) for (i = 0; i < nregs; ++i) if (call_used_regs[regno + i] - || HARD_REGNO_CALL_PART_CLOBBERED (regno + i, mode)) + || targetm.hard_regno_call_part_clobbered (regno + i, mode)) return 0; if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER) for (i = 0; i < valuenregs; ++i) if (call_used_regs[valueno + i] - || HARD_REGNO_CALL_PART_CLOBBERED (valueno + i, mode)) + || targetm.hard_regno_call_part_clobbered (valueno + i, + mode)) return 0; } Index: gcc/reload1.c =================================================================== --- gcc/reload1.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/reload1.c 2017-08-28 09:36:10.074827140 +0100 @@ -8276,7 +8276,8 @@ emit_reload_insns (struct insn_chain *ch : out_regno + k); reg_reloaded_insn[regno + k] = insn; SET_HARD_REG_BIT (reg_reloaded_valid, regno + k); - if (HARD_REGNO_CALL_PART_CLOBBERED (regno + k, mode)) + if (targetm.hard_regno_call_part_clobbered (regno + k, + mode)) SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, regno + k); else @@ -8355,7 +8356,8 @@ emit_reload_insns (struct insn_chain *ch : in_regno + k); reg_reloaded_insn[regno + k] = insn; SET_HARD_REG_BIT (reg_reloaded_valid, regno + k); - if (HARD_REGNO_CALL_PART_CLOBBERED (regno + k, mode)) + if (targetm.hard_regno_call_part_clobbered (regno + k, + mode)) SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, regno + k); else @@ -8469,8 +8471,8 @@ emit_reload_insns (struct insn_chain *ch reg_reloaded_insn[src_regno + k] = store_insn; CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + k); SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + k); - if (HARD_REGNO_CALL_PART_CLOBBERED (src_regno + k, - mode)) + if (targetm.hard_regno_call_part_clobbered + (src_regno + k, mode)) SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, src_regno + k); else Index: gcc/sched-deps.c =================================================================== --- gcc/sched-deps.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/sched-deps.c 2017-08-28 09:36:10.074827140 +0100 @@ -3706,7 +3706,8 @@ deps_analyze_insn (struct deps_desc *dep Since we only have a choice between 'might be clobbered' and 'definitely not clobbered', we must include all partly call-clobbered registers here. */ - else if (HARD_REGNO_CALL_PART_CLOBBERED (i, reg_raw_mode[i]) + else if (targetm.hard_regno_call_part_clobbered (i, + reg_raw_mode[i]) || TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) SET_REGNO_REG_SET (reg_pending_clobbers, i); /* We don't know what set of fixed registers might be used Index: gcc/sel-sched.c =================================================================== --- gcc/sel-sched.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/sel-sched.c 2017-08-28 09:36:10.075827140 +0100 @@ -1102,7 +1102,7 @@ init_regs_for_mode (machine_mode mode) if (i >= 0) continue; - if (HARD_REGNO_CALL_PART_CLOBBERED (cur_reg, mode)) + if (targetm.hard_regno_call_part_clobbered (cur_reg, mode)) SET_HARD_REG_BIT (sel_hrd.regs_for_call_clobbered[mode], cur_reg); @@ -1251,7 +1251,7 @@ mark_unavailable_hard_regs (def_t def, s /* Exclude registers that are partially call clobbered. */ if (def->crosses_call - && ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) + && !targetm.hard_regno_call_part_clobbered (regno, mode)) AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming, sel_hrd.regs_for_call_clobbered[mode]); Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/targhooks.c 2017-08-28 09:36:10.076827140 +0100 @@ -1736,7 +1736,7 @@ default_dwarf_frame_reg_mode (int regno) { machine_mode save_mode = reg_raw_mode[regno]; - if (HARD_REGNO_CALL_PART_CLOBBERED (regno, save_mode)) + if (targetm.hard_regno_call_part_clobbered (regno, save_mode)) save_mode = choose_hard_reg_mode (regno, 1, true); return save_mode; } Index: gcc/config/aarch64/aarch64.h =================================================================== --- gcc/config/aarch64/aarch64.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/aarch64/aarch64.h 2017-08-28 09:36:10.053827138 +0100 @@ -888,12 +888,6 @@ #define SHIFT_COUNT_TRUNCATED (!TARGET_S #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ aarch64_hard_regno_caller_save_mode ((REGNO), (NREGS), (MODE)) -/* Callee only saves lower 64-bits of a 128-bit register. Tell the - compiler the callee clobbers the top 64-bits when restoring the - bottom 64-bits. */ -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ - (FP_REGNUM_P (REGNO) && GET_MODE_SIZE (MODE) > 8) - #undef SWITCHABLE_TARGET #define SWITCHABLE_TARGET 1 Index: gcc/config/aarch64/aarch64.c =================================================================== --- gcc/config/aarch64/aarch64.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/aarch64/aarch64.c 2017-08-28 09:36:10.053827138 +0100 @@ -1115,6 +1115,16 @@ aarch64_hard_regno_mode_ok (unsigned reg return 0; } +/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. The callee only saves + the lower 64 bits of a 128-bit register. Tell the compiler the callee + clobbers the top 64 bits when restoring the bottom 64 bits. */ + +static bool +aarch64_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode) +{ + return FP_REGNUM_P (regno) && GET_MODE_SIZE (mode) > 8; +} + /* Implement HARD_REGNO_CALLER_SAVE_MODE. */ machine_mode aarch64_hard_regno_caller_save_mode (unsigned regno, unsigned nregs, @@ -15644,6 +15654,10 @@ #define TARGET_OMIT_STRUCT_RETURN_REG tr #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4 +#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED +#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ + aarch64_hard_regno_call_part_clobbered + #if CHECKING_P #undef TARGET_RUN_TARGET_SELFTESTS #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests Index: gcc/config/avr/avr.h =================================================================== --- gcc/config/avr/avr.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/avr/avr.h 2017-08-28 09:36:10.054827138 +0100 @@ -285,9 +285,6 @@ #define REGNO_MODE_CODE_OK_FOR_BASE_P(nu #define REGNO_OK_FOR_INDEX_P(NUM) 0 -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ - avr_hard_regno_call_part_clobbered (REGNO, MODE) - #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true #define STACK_PUSH_CODE POST_DEC Index: gcc/config/avr/avr-protos.h =================================================================== --- gcc/config/avr/avr-protos.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/avr/avr-protos.h 2017-08-28 09:36:10.053827138 +0100 @@ -46,7 +46,6 @@ extern void avr_init_cumulative_args (CU #endif /* TREE_CODE */ #ifdef RTX_CODE -extern int avr_hard_regno_call_part_clobbered (unsigned, machine_mode); extern const char *output_movqi (rtx_insn *insn, rtx operands[], int *l); extern const char *output_movhi (rtx_insn *insn, rtx operands[], int *l); extern const char *output_movsisf (rtx_insn *insn, rtx operands[], int *l); Index: gcc/config/avr/avr.c =================================================================== --- gcc/config/avr/avr.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/avr/avr.c 2017-08-28 09:36:10.054827138 +0100 @@ -12186,9 +12186,9 @@ avr_hard_regno_mode_ok (int regno, machi } -/* Implement `HARD_REGNO_CALL_PART_CLOBBERED'. */ +/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. */ -int +static bool avr_hard_regno_call_part_clobbered (unsigned regno, machine_mode mode) { /* FIXME: This hook gets called with MODE:REGNO combinations that don't @@ -14693,6 +14693,10 @@ #define TARGET_CONDITIONAL_REGISTER_USAG #undef TARGET_HARD_REGNO_SCRATCH_OK #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok +#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED +#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ + avr_hard_regno_call_part_clobbered + #undef TARGET_CASE_VALUES_THRESHOLD #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold Index: gcc/config/i386/i386.h =================================================================== --- gcc/config/i386/i386.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/i386/i386.h 2017-08-28 09:36:10.059827139 +0100 @@ -1214,12 +1214,6 @@ #define HARD_REGNO_CALLER_SAVE_MODE(REGN || MASK_REGNO_P (REGNO)) ? SImode \ : (MODE)) -/* The only ABI that saves SSE registers across calls is Win64 (thus no - need to check the current ABI here), and with AVX enabled Win64 only - guarantees that the low 16 bytes are saved. */ -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ - (SSE_REGNO_P (REGNO) && GET_MODE_SIZE (MODE) > 16) - /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/i386/i386.c 2017-08-28 09:36:10.058827139 +0100 @@ -41397,6 +41397,17 @@ ix86_hard_regno_mode_ok (int regno, mach return false; } +/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. The only ABI that + saves SSE registers across calls is Win64 (thus no need to check the + current ABI here), and with AVX enabled Win64 only guarantees that + the low 16 bytes are saved. */ + +static bool +ix86_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode) +{ + return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16; +} + /* A subroutine of ix86_modes_tieable_p. Return true if MODE is a tieable integer mode. */ @@ -53239,6 +53250,10 @@ #define TARGET_MAX_NOCE_IFCVT_SEQ_COST i #undef TARGET_NOCE_CONVERSION_PROFITABLE_P #define TARGET_NOCE_CONVERSION_PROFITABLE_P ix86_noce_conversion_profitable_p +#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED +#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ + ix86_hard_regno_call_part_clobbered + #if CHECKING_P #undef TARGET_RUN_TARGET_SELFTESTS #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests Index: gcc/config/mips/mips.h =================================================================== --- gcc/config/mips/mips.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/mips/mips.h 2017-08-28 09:36:10.060827139 +0100 @@ -1971,14 +1971,6 @@ #define HARD_REGNO_RENAME_OK(OLD_REG, NE #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ mips_hard_regno_caller_save_mode (REGNO, NREGS, MODE) -/* Odd-numbered single-precision registers are not considered callee-saved - for o32 FPXX as they will be clobbered when run on an FR=1 FPU. - MSA vector registers with MODE > 64 bits are part clobbered too. */ -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ - ((TARGET_FLOATXX && hard_regno_nregs[REGNO][MODE] == 1 \ - && FP_REG_P (REGNO) && ((REGNO) & 1)) \ - || (ISA_HAS_MSA && FP_REG_P (REGNO) && GET_MODE_SIZE (MODE) > 8)) - #define MODES_TIEABLE_P mips_modes_tieable_p /* Register to use for pushing function arguments. */ Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/mips/mips.c 2017-08-28 09:36:10.060827139 +0100 @@ -12857,6 +12857,26 @@ mips_hard_regno_scratch_ok (unsigned int return true; } +/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. Odd-numbered + single-precision registers are not considered callee-saved for o32 + FPXX as they will be clobbered when run on an FR=1 FPU. MSA vector + registers with MODE > 64 bits are part clobbered too. */ + +static bool +mips_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode) +{ + if (TARGET_FLOATXX + && hard_regno_nregs[regno][mode] == 1 + && FP_REG_P (regno) + && (regno & 1) != 0) + return true; + + if (ISA_HAS_MSA && FP_REG_P (regno) && GET_MODE_SIZE (mode) > 8) + return true; + + return false; +} + /* Implement HARD_REGNO_NREGS. */ unsigned int @@ -22557,6 +22577,10 @@ #define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO #undef TARGET_HARD_REGNO_SCRATCH_OK #define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok +#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED +#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ + mips_hard_regno_call_part_clobbered + /* The architecture reserves bit 0 for MIPS16 so use bit 1 for descriptors. */ #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2 Index: gcc/config/powerpcspe/powerpcspe.h =================================================================== --- gcc/config/powerpcspe/powerpcspe.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/powerpcspe/powerpcspe.h 2017-08-28 09:36:10.064827139 +0100 @@ -1302,13 +1302,6 @@ #define HARD_REGNO_CALLER_SAVE_MODE(REGN ? DImode \ : choose_hard_reg_mode ((REGNO), (NREGS), false)) -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ - (((TARGET_32BIT && TARGET_POWERPC64 \ - && (GET_MODE_SIZE (MODE) > 4) \ - && INT_REGNO_P (REGNO)) ? 1 : 0) \ - || (TARGET_VSX && FP_REGNO_P (REGNO) \ - && GET_MODE_SIZE (MODE) > 8 && !FLOAT128_2REG_P (MODE))) - #define VSX_VECTOR_MODE(MODE) \ ((MODE) == V4SFmode \ || (MODE) == V2DFmode) \ Index: gcc/config/powerpcspe/powerpcspe.c =================================================================== --- gcc/config/powerpcspe/powerpcspe.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/powerpcspe/powerpcspe.c 2017-08-28 09:36:10.063827139 +0100 @@ -1972,6 +1972,10 @@ #define TARGET_OPTAB_SUPPORTED_P rs6000_ #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1 + +#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED +#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ + rs6000_hard_regno_call_part_clobbered /* Processor table. */ @@ -2157,6 +2161,26 @@ rs6000_hard_regno_mode_ok (int regno, ma return GET_MODE_SIZE (mode) <= UNITS_PER_WORD; } +/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. */ + +static bool +rs6000_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode) +{ + if (TARGET_32BIT + && TARGET_POWERPC64 + && GET_MODE_SIZE (mode) > 4 + && INT_REGNO_P (regno)) + return true; + + if (TARGET_VSX + && FP_REGNO_P (regno) + && GET_MODE_SIZE (mode) > 8 + && !FLOAT128_2REG_P (mode)) + return true; + + return false; +} + /* Print interesting facts about registers. */ static void rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name) Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/rs6000/rs6000.h 2017-08-28 09:36:10.067827139 +0100 @@ -1240,13 +1240,6 @@ #define HARD_REGNO_CALLER_SAVE_MODE(REGN ? DImode \ : choose_hard_reg_mode ((REGNO), (NREGS), false)) -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ - (((TARGET_32BIT && TARGET_POWERPC64 \ - && (GET_MODE_SIZE (MODE) > 4) \ - && INT_REGNO_P (REGNO)) ? 1 : 0) \ - || (TARGET_VSX && FP_REGNO_P (REGNO) \ - && GET_MODE_SIZE (MODE) > 8 && !FLOAT128_2REG_P (MODE))) - #define VSX_VECTOR_MODE(MODE) \ ((MODE) == V4SFmode \ || (MODE) == V2DFmode) \ Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/rs6000/rs6000.c 2017-08-28 09:36:10.066827139 +0100 @@ -1963,6 +1963,9 @@ #define TARGET_GET_FUNCTION_VERSIONS_DIS #undef TARGET_OPTION_FUNCTION_VERSIONS #define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions +#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED +#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ + rs6000_hard_regno_call_part_clobbered /* Processor table. */ @@ -2125,6 +2128,26 @@ rs6000_hard_regno_mode_ok (int regno, ma return GET_MODE_SIZE (mode) <= UNITS_PER_WORD; } +/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. */ + +static bool +rs6000_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode) +{ + if (TARGET_32BIT + && TARGET_POWERPC64 + && GET_MODE_SIZE (mode) > 4 + && INT_REGNO_P (regno)) + return true; + + if (TARGET_VSX + && FP_REGNO_P (regno) + && GET_MODE_SIZE (mode) > 8 + && !FLOAT128_2REG_P (mode)) + return true; + + return false; +} + /* Print interesting facts about registers. */ static void rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name) Index: gcc/config/s390/s390.h =================================================================== --- gcc/config/s390/s390.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/s390/s390.h 2017-08-28 09:36:10.068827139 +0100 @@ -509,19 +509,6 @@ #define MODES_TIEABLE_P(MODE1, MODE2) \ (((MODE1) == SFmode || (MODE1) == DFmode) \ == ((MODE2) == SFmode || (MODE2) == DFmode)) -/* When generating code that runs in z/Architecture mode, - but conforms to the 31-bit ABI, GPRs can hold 8 bytes; - the ABI guarantees only that the lower 4 bytes are - saved across calls, however. */ -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ - ((!TARGET_64BIT && TARGET_ZARCH \ - && GET_MODE_SIZE (MODE) > 4 \ - && (((REGNO) >= 6 && (REGNO) <= 15) || (REGNO) == 32)) \ - || (TARGET_VX \ - && GET_MODE_SIZE (MODE) > 8 \ - && (((TARGET_64BIT && (REGNO) >= 24 && (REGNO) <= 31)) \ - || (!TARGET_64BIT && ((REGNO) == 18 || (REGNO) == 19))))) - /* Maximum number of registers to represent a value of mode MODE in a register of class CLASS. */ #define CLASS_MAX_NREGS(CLASS, MODE) \ Index: gcc/config/s390/s390.c =================================================================== --- gcc/config/s390/s390.c 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/s390/s390.c 2017-08-28 09:36:10.068827139 +0100 @@ -10476,6 +10476,29 @@ s390_hard_regno_scratch_ok (unsigned int return true; } +/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. When generating + code that runs in z/Architecture mode, but conforms to the 31-bit + ABI, GPRs can hold 8 bytes; the ABI guarantees only that the lower 4 + bytes are saved across calls, however. */ + +static bool +s390_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode) +{ + if (!TARGET_64BIT + && TARGET_ZARCH + && GET_MODE_SIZE (mode) > 4 + && ((regno >= 6 && regno <= 15) || regno == 32)) + return true; + + if (TARGET_VX + && GET_MODE_SIZE (mode) > 8 + && (((TARGET_64BIT && regno >= 24 && regno <= 31)) + || (!TARGET_64BIT && (regno == 18 || regno == 19)))) + return true; + + return false; +} + /* Maximum number of registers to represent a value of mode MODE in a register of class RCLASS. */ @@ -15877,6 +15900,10 @@ #define TARGET_CANONICALIZE_COMPARISON s #undef TARGET_HARD_REGNO_SCRATCH_OK #define TARGET_HARD_REGNO_SCRATCH_OK s390_hard_regno_scratch_ok +#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED +#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ + s390_hard_regno_call_part_clobbered + #undef TARGET_ATTRIBUTE_TABLE #define TARGET_ATTRIBUTE_TABLE s390_attribute_table Index: gcc/config/sh/sh.h =================================================================== --- gcc/config/sh/sh.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/config/sh/sh.h 2017-08-28 09:36:10.068827139 +0100 @@ -811,8 +811,6 @@ #define CALL_REALLY_USED_REGISTERS 1, 1, 0, 0, \ } -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO,MODE) (false) - /* Return number of consecutive hard regs needed starting at reg REGNO to hold something of mode MODE. This is ordinarily the length in words of a value of mode MODE Index: gcc/system.h =================================================================== --- gcc/system.h 2017-08-28 09:36:09.610827107 +0100 +++ gcc/system.h 2017-08-28 09:36:10.075827140 +0100 @@ -904,7 +904,8 @@ #define realloc xrealloc ASM_BYTE_OP MEMBER_TYPE_FORCES_BLK LIBGCC2_HAS_SF_MODE \ LIBGCC2_HAS_DF_MODE LIBGCC2_HAS_XF_MODE LIBGCC2_HAS_TF_MODE \ CLEAR_BY_PIECES_P MOVE_BY_PIECES_P SET_BY_PIECES_P \ - STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD + STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD \ + HARD_REGNO_CALL_PART_CLOBBERED /* Target macros only used for code built for the target, that have moved to libgcc-tm.h or have never been present elsewhere. */