From patchwork Mon Sep 11 17:18:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 112211 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp4103751qgf; Mon, 11 Sep 2017 10:19:40 -0700 (PDT) X-Received: by 10.84.248.147 with SMTP id q19mr14289193pll.72.1505150380325; Mon, 11 Sep 2017 10:19:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505150380; cv=none; d=google.com; s=arc-20160816; b=XhV58SEXQLHZcfA1ykfBaCKC8r0bsN+wYkQBm4hX0czRhnnUxICmMEradctcE5z3rR m55zpD7X/LdjUP5iVs1U6xeg6Dj4FUMnvYh4lAzrZHSD78xPPJpUVJDFnWlJ3d5wB+zO kVbS5JybolF/YdHYP9tqQQnJDyIt5qB/KWyW7ZaIJeLvh58f8A5xMzxwczSdVOrbxHHF CREk2omMEP2n6kOhEZM8oLhS30nsyGNzFHsxFiRueyMsgR9N0c+G4xHziIOp4MlQxrLJ cv8GHaF3H0jc4vkyIzoN9yG8ALLhhB61LiXFdxb34w2Yj5AeUn/6UNO9fbGwmbNs2I+8 0PbA== 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=IaZ2ZlJyIdQOOKSedwiJpySB09RO5sMU9ZZPYdPnpUw=; b=XVbhB8CIZIELHgEMeowW8QDoA4awTl2x13K/1VXdTX0/RzzIf/5OdSbofOuXSDU6wb 4afRTOnX/kFa90UskgyRa/K5Vu6cymf8E0wzZJrlI8O/aM7XRSMSHMxOvxVsSmq90kNP aB1RwIUrFXvHrIw14m0s2M3rIiMy8oX0KN2m0WsYJPmh1gzkZy11xYk6gl2/zJPpR4OO R2L8DlVSbtbLkn1Ngzbc8sk4fcwn6PQjQTq5LJ/IQ0at/No5ng86A9b/T/zmCNkOkNBV qBBt4pDXDHHZUXypT05S3MJT8zlwpOzhXR0yVak5evmwkGa6W+kIck0BggZehQ9FJRd/ MdbQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=GvIGwyvN; spf=pass (google.com: domain of gcc-patches-return-461843-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-461843-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 b60si3726991plc.23.2017.09.11.10.19.39 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Sep 2017 10:19:40 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-461843-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=GvIGwyvN; spf=pass (google.com: domain of gcc-patches-return-461843-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-461843-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=h9kgbeLG9pIqwECCuJG/PsH9/QrCPq7tl9iNfPeXTKEhrw2asdxkj X67rSOaMoC+gL/r6GcEs36p7A4PiLdJVoOwrkIN8WtBoxuP15sHecTg76/ADDYcJ 16VrKzm5jPtmdu+fWyYmQ2P67tMf95pu9+LqNJge6pKNwJMLYXO1m8= 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=3TZhONE0Xv0cj62zqCXD21eTMug=; b=GvIGwyvNDHbGaNpJyroI 0RqyRE8e3TG8E+gTIly2r5/eFtV6mam0Rjxb0wDnsZctoJTrH+0gPkeMNUzGqlhM f+GGl8/w0eFU6yG35Rc/E2qXSYXgitMykdPP34Nym/1RBvnnsid4j+J8kZoaEGRk M4sE7hKwx6usOoyMXXWYCA0= Received: (qmail 91402 invoked by alias); 11 Sep 2017 17:19:00 -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 88949 invoked by uid 89); 11 Sep 2017 17:18:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=quantities, rm X-HELO: mail-wm0-f45.google.com Received: from mail-wm0-f45.google.com (HELO mail-wm0-f45.google.com) (74.125.82.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 11 Sep 2017 17:18:47 +0000 Received: by mail-wm0-f45.google.com with SMTP id i189so45031659wmf.1 for ; Mon, 11 Sep 2017 10:18:46 -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=IaZ2ZlJyIdQOOKSedwiJpySB09RO5sMU9ZZPYdPnpUw=; b=uWAqDiQ80lIA+INWumiyPDpkIXrbZnXd+DIqB/FqUgSQMbxl60dHuPXCBMy3PPkSUE McNxQsHT8dGzcI619zTj4en7f6Y7XKYzZzzWo4SWnJZGjT9jDdEEdC2CzFm/1WO5wJS3 bH/Z2Uga5RwvszvJx3K4PmMaOO1pWr+EU9vSeyQU38x9fb1tbdrV78igns1MpmmEvnm7 8xGDq/Ny70TvPckwzQx5wdI+9CKSrpAGL7rNl1m5f65Aqis4EMvGKYo3Pg9PNHVf4zlm mz22gFP5bGZ/eY1NkGMMrwrrRJ5ssgAo/+ORYV2YBdEXQKHGfqcv+Fywxa29G4J35MUP CTBA== X-Gm-Message-State: AHPjjUjbmv8cFtlNV9u3RXHNYQgDwLR3z2e0uvhzMGvi4DhaySufHbJ/ JfIUCuEeybc+PN0L6z3B8uQTfg/Kr0M= X-Google-Smtp-Source: AOwi7QC3nktef/Xj0r1ZLiDGQK0nruO1YIH4tAO9ZOH5LPG/jmizy8JGyfw6JSTtieyogEPI8TnbSw== X-Received: by 10.28.105.157 with SMTP id z29mr7704156wmh.135.1505150320454; Mon, 11 Sep 2017 10:18:40 -0700 (PDT) Received: from localhost ([2.25.234.0]) by smtp.gmail.com with ESMTPSA id n29sm6728251wra.94.2017.09.11.10.18.37 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 11 Sep 2017 10:18:39 -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_NREGS into a target hook Date: Mon, 11 Sep 2017 18:18:36 +0100 Message-ID: <87a821cfwz.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu. Also tested by comparing the testsuite assembly output on at least one target per CPU directory. OK to install? Richard gcc/ * target.def (hard_regno_nregs): New hook. (class_max_nregs): Refer to it instead of HARD_REGNO_NREGS. * targhooks.h (default_hard_regno_nregs): Declare. * targhooks.c (default_hard_regno_nregs): New function. * doc/tm.texi.in (HARD_REGNO_NREGS): Replace with... (TARGET_HARD_REGNO_NREGS): ...this hook. (HARD_REGNO_NREGS_HAS_PADDING): Update accordingly. (CLASS_MAX_NREGS): Likewise. * doc/tm.texi: Regenerate. * reginfo.c (init_reg_modes_target): Use targetm.hard_regno_nregs instead of HARD_REGNO_NREGS. * rtl.h (REG_NREGS): Refer to TARGET_HARD_REGNO_NREGS rather than HARD_REGNO_NREGS in the comment. * config/aarch64/aarch64.h (HARD_REGNO_NREGS): Delete. * config/aarch64/aarch64-protos.h (aarch64_hard_regno_nregs): Delete. * config/aarch64/aarch64.c (aarch64_hard_regno_nregs): Make static. Return an unsigned int. (TARGET_HARD_REGNO_NREGS): Redefine. * config/alpha/alpha.h (HARD_REGNO_NREGS): Delete. * config/arc/arc.h (HARD_REGNO_NREGS): Delete. * config/arc/arc.c (TARGET_HARD_REGNO_NREGS): Redefine. (arc_hard_regno_nregs): New function. * config/arm/arm.h (HARD_REGNO_NREGS): Delete. * config/arm/arm.c (TARGET_HARD_REGNO_NREGS): Redefine. (arm_hard_regno_nregs): New function. * config/avr/avr.h (HARD_REGNO_NREGS): Delete. * config/bfin/bfin.h (HARD_REGNO_NREGS): Delete. * config/bfin/bfin.c (bfin_hard_regno_nregs): New function. (TARGET_HARD_REGNO_NREGS): Redefine. * config/c6x/c6x.h (HARD_REGNO_NREGS): Delete. * config/cr16/cr16.h (LONG_REG_P): Use targetm.hard_regno_nregs. (HARD_REGNO_NREGS): Delete. * config/cr16/cr16.c (TARGET_HARD_REGNO_NREGS): Redefine. (cr16_hard_regno_nregs): New function. (cr16_memory_move_cost): Use it instead of HARD_REGNO_NREGS. * config/cris/cris.h (HARD_REGNO_NREGS): Delete. * config/cris/cris.c (TARGET_HARD_REGNO_NREGS): Redefine. (cris_hard_regno_nregs): New function. * config/epiphany/epiphany.h (HARD_REGNO_NREGS): Delete. * config/fr30/fr30.h (HARD_REGNO_NREGS): Delete. (CLASS_MAX_NREGS): Use targetm.hard_regno_nregs. * config/frv/frv.h (HARD_REGNO_NREGS): Delete. (CLASS_MAX_NREGS): Remove outdated copy of documentation. * config/frv/frv-protos.h (frv_hard_regno_nregs): Delete. * config/frv/frv.c (TARGET_HARD_REGNO_NREGS): Redefine. (frv_hard_regno_nregs): Make static. Take and return an unsigned int. (frv_class_max_nregs): Remove outdated copy of documentation. * config/ft32/ft32.h (HARD_REGNO_NREGS): Delete. * config/h8300/h8300.h (HARD_REGNO_NREGS): Delete. * config/h8300/h8300-protos.h (h8300_hard_regno_nregs): Delete. * config/h8300/h8300.c (h8300_hard_regno_nregs): Delete. * config/i386/i386.h (HARD_REGNO_NREGS): Delete. * config/i386/i386.c (ix86_hard_regno_nregs): New function. (TARGET_HARD_REGNO_NREGS): Redefine. * config/ia64/ia64.h (HARD_REGNO_NREGS): Delete. (CLASS_MAX_NREGS): Update comment. * config/ia64/ia64.c (TARGET_HARD_REGNO_NREGS): Redefine. (ia64_hard_regno_nregs): New function. * config/iq2000/iq2000.h (HARD_REGNO_NREGS): Delete. * config/lm32/lm32.h (HARD_REGNO_NREGS): Delete. * config/m32c/m32c.h (HARD_REGNO_NREGS): Delete. * config/m32c/m32c-protos.h (m32c_hard_regno_nregs): Delete. * config/m32c/m32c.c (m32c_hard_regno_nregs_1): Take and return an unsigned int. (m32c_hard_regno_nregs): Likewise. Make static. (TARGET_HARD_REGNO_NREGS): Redefine. * config/m32r/m32r.h (HARD_REGNO_NREGS): Delete. * config/m68k/m68k.h (HARD_REGNO_NREGS): Delete. * config/m68k/m68k.c (TARGET_HARD_REGNO_NREGS): Redefine. (m68k_hard_regno_nregs): New function. * config/mcore/mcore.h (HARD_REGNO_NREGS): Delete. * config/microblaze/microblaze.h (HARD_REGNO_NREGS): Delete. * config/mips/mips.h (HARD_REGNO_NREGS): Delete. * config/mips/mips-protos.h (mips_hard_regno_nregs): Delete. * config/mips/mips.c (mips_hard_regno_nregs): Make static. Take and return an unsigned int. (TARGET_HARD_REGNO_NREGS): Redefine. * config/mmix/mmix.h (HARD_REGNO_NREGS): Delete. (CLASS_MAX_NREGS): Use targetm.hard_regno_nregs. * config/mn10300/mn10300.h (HARD_REGNO_NREGS): Delete. * config/moxie/moxie.h (HARD_REGNO_NREGS): Delete. * config/msp430/msp430.h (HARD_REGNO_NREGS): Delete. * config/msp430/msp430-protos.h (msp430_hard_regno_nregs): Delete. * config/msp430/msp430.c (TARGET_HARD_REGNO_NREGS): Redefine. (msp430_hard_regno_nregs): Make static. Take and return an unsigned int. * config/nds32/nds32.h (HARD_REGNO_NREGS): Delete. * config/nds32/nds32-protos.h (nds32_hard_regno_nregs): Delete. * config/nds32/nds32.c (nds32_hard_regno_nregs): Delete. (nds32_hard_regno_mode_ok): Use targetm.hard_regno_nregs. * config/nios2/nios2.h (HARD_REGNO_NREGS): Delete. * config/nvptx/nvptx.h (HARD_REGNO_NREGS): Delete. * config/nvptx/nvptx.c (nvptx_hard_regno_nregs): New function. (TARGET_HARD_REGNO_NREGS): Redefine. * config/pa/pa32-regs.h (HARD_REGNO_NREGS): Rename to... (PA_HARD_REGNO_NREGS): ...this. * config/pa/pa64-regs.h (HARD_REGNO_NREGS): Rename to... (PA_HARD_REGNO_NREGS): ...this. * config/pa/pa.c (TARGET_HARD_REGNO_NREGS): Redefine. (pa_hard_regno_nregs): New function. * config/pdp11/pdp11.h (HARD_REGNO_NREGS): Delete. * config/pdp11/pdp11.c (TARGET_HARD_REGNO_NREGS): Redefine. (pdp11_hard_regno_nregs): New function. * config/powerpcspe/powerpcspe.h (HARD_REGNO_NREGS): Delete. * config/powerpcspe/powerpcspe.c (TARGET_HARD_REGNO_NREGS): Redefine. (rs6000_hard_regno_nregs_hook): New function. * config/riscv/riscv.h (HARD_REGNO_NREGS): Delete. * config/riscv/riscv-protos.h (riscv_hard_regno_nregs): Delete. * config/riscv/riscv.c (riscv_hard_regno_nregs): Make static. Take and return an unsigned int. Move earlier in file. (TARGET_HARD_REGNO_NREGS): Redefine. * config/rl78/rl78.h (HARD_REGNO_NREGS): Delete. * config/rl78/rl78-protos.h (rl78_hard_regno_nregs): Delete. * config/rl78/rl78.c (TARGET_HARD_REGNO_NREGS): Reefine. (rl78_hard_regno_nregs): Make static. Take and return an unsigned int. * config/rs6000/rs6000.h (HARD_REGNO_NREGS): Delete. * config/rs6000/rs6000.c (TARGET_HARD_REGNO_NREGS): Redefine. (rs6000_hard_regno_nregs_hook): New function. * config/rx/rx.h (HARD_REGNO_NREGS): Delete. * config/rx/rx.c (rx_hard_regno_nregs): New function. (TARGET_HARD_REGNO_NREGS): Redefine. * config/s390/s390.h (HARD_REGNO_NREGS): Delete. * config/s390/s390.c (REGNO_PAIR_OK): Use s390_hard_regno_nregs instead of HARD_REGNO_NREGS. (s390_hard_regno_nregs): New function. (s390_hard_regno_mode_ok): Add comment from s390.h. (TARGET_HARD_REGNO_NREGS): Redefine. * config/sh/sh.h (HARD_REGNO_NREGS): Delete. * config/sh/sh.c (TARGET_HARD_REGNO_NREGS): Redefine. (sh_hard_regno_nregs): New function. (sh_pass_in_reg_p): Use it. * config/sparc/sparc.h (HARD_REGNO_NREGS): Delete. * config/sparc/sparc.c (TARGET_HARD_REGNO_NREGS): Redefine. (sparc_hard_regno_nregs): New function. * config/spu/spu.h (HARD_REGNO_NREGS): Delete. * config/spu/spu.c (spu_hard_regno_nregs): New function. (spu_function_arg_advance): Use it, supplying a valid register number. (TARGET_HARD_REGNO_NREGS): Redefine. * config/stormy16/stormy16.h (HARD_REGNO_NREGS): Delete. * config/tilegx/tilegx.h (HARD_REGNO_NREGS): Delete. * config/tilepro/tilepro.h (HARD_REGNO_NREGS): Delete. * config/v850/v850.h (HARD_REGNO_NREGS): Delete. * config/vax/vax.h (HARD_REGNO_NREGS): Delete. * config/visium/visium.h (HARD_REGNO_NREGS): Delete. (CLASS_MAX_NREGS): Remove copy of old documentation. * config/visium/visium.c (TARGET_HARD_REGNO_NREGS): Redefine. (visium_hard_regno_nregs): New function. (visium_hard_regno_mode_ok): Use it instead of HARD_REGNO_NREGS. * config/xtensa/xtensa.h (HARD_REGNO_NREGS): Delete. * config/xtensa/xtensa.c (TARGET_HARD_REGNO_NREGS): Redefine. xtensa_hard_regno_nregs): New function. * system.h (HARD_REGNO_NREGS): Poison. Index: gcc/target.def =================================================================== --- gcc/target.def 2017-09-11 17:55:38.950289484 +0100 +++ gcc/target.def 2017-09-11 17:55:40.037247666 +0100 @@ -5345,10 +5345,10 @@ DEFHOOK "A target hook returns the maximum number of consecutive registers\n\ of class @var{rclass} needed to hold a value of mode @var{mode}.\n\ \n\ -This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact,\n\ -the value returned by @code{TARGET_CLASS_MAX_NREGS (@var{rclass},\n\ +This is closely related to the macro @code{TARGET_HARD_REGNO_NREGS}.\n\ +In fact, the value returned by @code{TARGET_CLASS_MAX_NREGS (@var{rclass},\n\ @var{mode})} target hook should be the maximum value of\n\ -@code{HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno}\n\ +@code{TARGET_HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno}\n\ values in the class @var{rclass}.\n\ \n\ This target hook helps control the handling of multiple-word values\n\ @@ -5425,6 +5425,19 @@ that are not actually in any insns yet, hook_void_void) DEFHOOK +(hard_regno_nregs, + "This hook returns the number of consecutive hard registers, starting\n\ +at register number @var{regno}, required to hold a value of mode\n\ +@var{mode}. This hook must never return zero, even if a register\n\ +cannot hold the requested mode - indicate that with\n\ +@code{TARGET_HARD_REGNO_MODE_OK} and/or @code{CANNOT_CHANGE_MODE_CLASS}\n\ +instead.\n\ +\n\ +The default definition returns the number of words in @var{mode}.", + unsigned int, (unsigned int regno, machine_mode mode), + default_hard_regno_nregs) + +DEFHOOK (hard_regno_mode_ok, "This hook returns true if it is permissible to store a value\n\ of mode @var{mode} in hard register number @var{regno} (or in several\n\ Index: gcc/targhooks.h =================================================================== --- gcc/targhooks.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/targhooks.h 2017-09-11 17:55:40.038247628 +0100 @@ -165,6 +165,7 @@ extern int default_reloc_rw_mask (void); extern tree default_mangle_decl_assembler_name (tree, tree); extern tree default_emutls_var_fields (tree, tree *); extern tree default_emutls_var_init (tree, tree, tree); +extern unsigned int default_hard_regno_nregs (unsigned int, machine_mode); extern bool default_hard_regno_scratch_ok (unsigned int); extern bool default_mode_dependent_address_p (const_rtx, addr_space_t); extern bool default_target_option_valid_attribute_p (tree, tree, tree, int); Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/targhooks.c 2017-09-11 17:55:40.037247666 +0100 @@ -1424,6 +1424,14 @@ default_addr_space_convert (rtx op ATTRI gcc_unreachable (); } +/* The defualt implementation of TARGET_HARD_REGNO_NREGS. */ + +unsigned int +default_hard_regno_nregs (unsigned int, machine_mode mode) +{ + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + bool default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED) { Index: gcc/doc/tm.texi.in =================================================================== --- gcc/doc/tm.texi.in 2017-09-11 17:55:38.950289484 +0100 +++ gcc/doc/tm.texi.in 2017-09-11 17:55:40.032247858 +0100 @@ -1804,23 +1804,7 @@ This section discusses the macros that d (specifically, which machine modes) each register can hold, and how many consecutive registers are needed for a given mode. -@defmac HARD_REGNO_NREGS (@var{regno}, @var{mode}) -A C expression for the number of consecutive hard registers, starting -at register number @var{regno}, required to hold a value of mode -@var{mode}. This macro must never return zero, even if a register -cannot hold the requested mode - indicate that with -@code{TARGET_HARD_REGNO_MODE_OK} and/or @code{CANNOT_CHANGE_MODE_CLASS} -instead. - -On a machine where all registers are exactly one word, a suitable -definition of this macro is - -@smallexample -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ - / UNITS_PER_WORD) -@end smallexample -@end defmac +@hook TARGET_HARD_REGNO_NREGS @defmac HARD_REGNO_NREGS_HAS_PADDING (@var{regno}, @var{mode}) A C expression that is nonzero if a value of mode @var{mode}, stored @@ -1828,7 +1812,7 @@ in memory, ends with padding that causes in registers starting at register number @var{regno} (as determined by multiplying GCC's notion of the size of the register when containing this mode by the number of registers returned by -@code{HARD_REGNO_NREGS}). By default this is zero. +@code{TARGET_HARD_REGNO_NREGS}). By default this is zero. For example, if a floating-point value is stored in three 32-bit registers but takes up 128 bits in memory, then this would be @@ -2372,9 +2356,9 @@ is @code{BITS_PER_WORD} bits wide is cor A C expression for the maximum number of consecutive registers of class @var{class} needed to hold a value of mode @var{mode}. -This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact, +This is closely related to the macro @code{TARGET_HARD_REGNO_NREGS}. In fact, the value of the macro @code{CLASS_MAX_NREGS (@var{class}, @var{mode})} -should be the maximum value of @code{HARD_REGNO_NREGS (@var{regno}, +should be the maximum value of @code{TARGET_HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno} values in the class @var{class}. This macro helps control the handling of multiple-word values Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi 2017-09-11 17:55:38.950289484 +0100 +++ gcc/doc/tm.texi 2017-09-11 17:55:40.030247935 +0100 @@ -2013,23 +2013,16 @@ This section discusses the macros that d (specifically, which machine modes) each register can hold, and how many consecutive registers are needed for a given mode. -@defmac HARD_REGNO_NREGS (@var{regno}, @var{mode}) -A C expression for the number of consecutive hard registers, starting +@deftypefn {Target Hook} {unsigned int} TARGET_HARD_REGNO_NREGS (unsigned int @var{regno}, machine_mode @var{mode}) +This hook returns the number of consecutive hard registers, starting at register number @var{regno}, required to hold a value of mode -@var{mode}. This macro must never return zero, even if a register +@var{mode}. This hook must never return zero, even if a register cannot hold the requested mode - indicate that with @code{TARGET_HARD_REGNO_MODE_OK} and/or @code{CANNOT_CHANGE_MODE_CLASS} instead. -On a machine where all registers are exactly one word, a suitable -definition of this macro is - -@smallexample -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ - / UNITS_PER_WORD) -@end smallexample -@end defmac +The default definition returns the number of words in @var{mode}. +@end deftypefn @defmac HARD_REGNO_NREGS_HAS_PADDING (@var{regno}, @var{mode}) A C expression that is nonzero if a value of mode @var{mode}, stored @@ -2037,7 +2030,7 @@ in memory, ends with padding that causes in registers starting at register number @var{regno} (as determined by multiplying GCC's notion of the size of the register when containing this mode by the number of registers returned by -@code{HARD_REGNO_NREGS}). By default this is zero. +@code{TARGET_HARD_REGNO_NREGS}). By default this is zero. For example, if a floating-point value is stored in three 32-bit registers but takes up 128 bits in memory, then this would be @@ -2798,10 +2791,10 @@ pressure. A target hook returns the maximum number of consecutive registers of class @var{rclass} needed to hold a value of mode @var{mode}. -This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact, -the value returned by @code{TARGET_CLASS_MAX_NREGS (@var{rclass}, +This is closely related to the macro @code{TARGET_HARD_REGNO_NREGS}. +In fact, the value returned by @code{TARGET_CLASS_MAX_NREGS (@var{rclass}, @var{mode})} target hook should be the maximum value of -@code{HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno} +@code{TARGET_HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno} values in the class @var{rclass}. This target hook helps control the handling of multiple-word values @@ -2815,9 +2808,9 @@ in words. A C expression for the maximum number of consecutive registers of class @var{class} needed to hold a value of mode @var{mode}. -This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact, +This is closely related to the macro @code{TARGET_HARD_REGNO_NREGS}. In fact, the value of the macro @code{CLASS_MAX_NREGS (@var{class}, @var{mode})} -should be the maximum value of @code{HARD_REGNO_NREGS (@var{regno}, +should be the maximum value of @code{TARGET_HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno} values in the class @var{class}. This macro helps control the handling of multiple-word values Index: gcc/reginfo.c =================================================================== --- gcc/reginfo.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/reginfo.c 2017-09-11 17:55:40.033247820 +0100 @@ -509,7 +509,7 @@ init_reg_modes_target (void) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (j = 0; j < MAX_MACHINE_MODE; j++) this_target_regs->x_hard_regno_nregs[i][j] - = HARD_REGNO_NREGS (i, (machine_mode)j); + = targetm.hard_regno_nregs (i, (machine_mode) j); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/rtl.h 2017-09-11 17:55:40.034247781 +0100 @@ -1802,7 +1802,7 @@ #define REGNO(RTX) (rhs_regno(RTX)) #define SET_REGNO(RTX, N) (df_ref_change_reg_with_loc (RTX, N)) /* Return the number of consecutive registers in a REG. This is always - 1 for pseudo registers and is determined by HARD_REGNO_NREGS for + 1 for pseudo registers and is determined by TARGET_HARD_REGNO_NREGS for hard registers. */ #define REG_NREGS(RTX) (REG_CHECK (RTX)->nregs) Index: gcc/config/aarch64/aarch64.h =================================================================== --- gcc/config/aarch64/aarch64.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/aarch64/aarch64.h 2017-09-11 17:55:39.950251013 +0100 @@ -401,8 +401,6 @@ #define DWARF_FRAME_REGNUM(REGNO) DBX_RE #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LR_REGNUM) -#define HARD_REGNO_NREGS(REGNO, MODE) aarch64_hard_regno_nregs (REGNO, MODE) - #define DWARF2_UNWIND_INFO 1 /* Use R0 through R3 to pass exception handling information. */ Index: gcc/config/aarch64/aarch64-protos.h =================================================================== --- gcc/config/aarch64/aarch64-protos.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/aarch64/aarch64-protos.h 2017-09-11 17:55:39.949251051 +0100 @@ -384,7 +384,6 @@ int aarch64_asm_preferred_eh_data_format int aarch64_fpconst_pow_of_2 (rtx); machine_mode aarch64_hard_regno_caller_save_mode (unsigned, unsigned, machine_mode); -int aarch64_hard_regno_nregs (unsigned, machine_mode); int aarch64_uxt_size (int, HOST_WIDE_INT); int aarch64_vec_fpconst_pow_of_2 (rtx); rtx aarch64_eh_return_handler_rtx (void); Index: gcc/config/aarch64/aarch64.c =================================================================== --- gcc/config/aarch64/aarch64.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/aarch64/aarch64.c 2017-09-11 17:55:39.950251013 +0100 @@ -1067,9 +1067,9 @@ aarch64_array_mode_supported_p (machine_ return false; } -/* Implement HARD_REGNO_NREGS. */ +/* Implement TARGET_HARD_REGNO_NREGS. */ -int +static unsigned int aarch64_hard_regno_nregs (unsigned regno, machine_mode mode) { switch (aarch64_regno_regclass (regno)) @@ -15685,6 +15685,8 @@ #define TARGET_OMIT_STRUCT_RETURN_REG tr #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4 +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS aarch64_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK aarch64_hard_regno_mode_ok Index: gcc/config/alpha/alpha.h =================================================================== --- gcc/config/alpha/alpha.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/alpha/alpha.h 2017-09-11 17:55:39.950251013 +0100 @@ -371,14 +371,6 @@ #define REG_ALLOC_ORDER { \ 29, 30, 31, 63 /* gp, sp, ap, sfp */ \ } -/* 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 - but can be less for certain modes in special long registers. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - CEIL (GET_MODE_SIZE (MODE), UNITS_PER_WORD) - /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ Index: gcc/config/arc/arc.h =================================================================== --- gcc/config/arc/arc.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/arc/arc.h 2017-09-11 17:55:39.952250936 +0100 @@ -441,15 +441,6 @@ #define REG_ALLOC_ORDER \ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, \ 27, 28, 29, 30, 31, 63} -/* 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 - but can be less for certain modes in special long registers. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ -((GET_MODE_SIZE (MODE) == 16 \ - && REGNO >= ARC_FIRST_SIMD_VR_REG && REGNO <= ARC_LAST_SIMD_VR_REG) ? 1 \ - : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Internal macros to classify a register number as to whether it's a general purpose register for compact insns (r0-r3,r12-r15), or stack pointer (r28). */ Index: gcc/config/arc/arc.c =================================================================== --- gcc/config/arc/arc.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/arc/arc.c 2017-09-11 17:55:39.951250975 +0100 @@ -590,6 +590,8 @@ #define TARGET_HAVE_TLS HAVE_AS_TLS #undef TARGET_DWARF_REGISTER_SPAN #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok @@ -1877,6 +1879,19 @@ arc_conditional_register_usage (void) } } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +arc_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (GET_MODE_SIZE (mode) == 16 + && regno >= ARC_FIRST_SIMD_VR_REG + && regno <= ARC_LAST_SIMD_VR_REG) + return 1; + + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool Index: gcc/config/arm/arm.h =================================================================== --- gcc/config/arm/arm.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/arm/arm.h 2017-09-11 17:55:39.956250782 +0100 @@ -976,20 +976,6 @@ #define DBX_REGISTER_NUMBER(REGNO) arm_d #define SUBTARGET_FRAME_POINTER_REQUIRED 0 #endif -/* 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 - but can be less for certain modes in special long registers. - - On the ARM core regs are UNITS_PER_WORD bits wide. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((TARGET_32BIT \ - && REGNO > PC_REGNUM \ - && REGNO != FRAME_POINTER_REGNUM \ - && REGNO != ARG_POINTER_REGNUM) \ - && !IS_VFP_REGNUM (REGNO) \ - ? 1 : ARM_NUM_REGS (MODE)) - #define VALID_IWMMXT_REG_MODE(MODE) \ (arm_vector_mode_supported_p (MODE) || (MODE) == DImode) Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/arm/arm.c 2017-09-11 17:55:39.956250782 +0100 @@ -314,6 +314,7 @@ static unsigned int arm_elf_section_type int reloc); static void arm_expand_divmod_libfunc (rtx, machine_mode, rtx, rtx, rtx *, rtx *); static opt_scalar_float_mode arm_floatn_mode (int, bool); +static unsigned int arm_hard_regno_nregs (unsigned int, machine_mode); static bool arm_hard_regno_mode_ok (unsigned int, machine_mode); static bool arm_modes_tieable_p (machine_mode, machine_mode); @@ -785,6 +786,8 @@ #define TARGET_CUSTOM_FUNCTION_DESCRIPTO #undef TARGET_FIXED_CONDITION_CODE_REGS #define TARGET_FIXED_CONDITION_CODE_REGS arm_fixed_condition_code_regs +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS arm_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK arm_hard_regno_mode_ok @@ -23348,6 +23351,21 @@ thumb2_asm_output_opcode (FILE * stream) } } +/* Implement TARGET_HARD_REGNO_NREGS. On the ARM core regs are + UNITS_PER_WORD bytes wide. */ +static unsigned int +arm_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (TARGET_32BIT + && regno > PC_REGNUM + && regno != FRAME_POINTER_REGNUM + && regno != ARG_POINTER_REGNUM + && !IS_VFP_REGNUM (regno)) + return 1; + + return ARM_NUM_REGS (mode); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool arm_hard_regno_mode_ok (unsigned int regno, machine_mode mode) Index: gcc/config/avr/avr.h =================================================================== --- gcc/config/avr/avr.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/avr/avr.h 2017-09-11 17:55:39.957250744 +0100 @@ -209,9 +209,6 @@ #define REG_ALLOC_ORDER { \ #define ADJUST_REG_ALLOC_ORDER avr_adjust_reg_alloc_order() -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - enum reg_class { NO_REGS, R0_REG, /* r0 */ Index: gcc/config/bfin/bfin.h =================================================================== --- gcc/config/bfin/bfin.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/bfin/bfin.h 2017-09-11 17:55:39.957250744 +0100 @@ -683,11 +683,6 @@ #define CLASS_MAX_NREGS(CLASS, MODE) ((MODE) == V2PDImode && (CLASS) == AREGS ? 2 \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((MODE) == PDImode && ((REGNO) == REG_A0 || (REGNO) == REG_A1) ? 1 \ - : (MODE) == V2PDImode && ((REGNO) == REG_A0 || (REGNO) == REG_A1) ? 2 \ - : CLASS_MAX_NREGS (GENERAL_REGS, MODE)) - /* A C expression that is nonzero if hard register TO can be considered for use as a rename register for FROM register */ #define HARD_REGNO_RENAME_OK(FROM, TO) bfin_hard_regno_rename_ok (FROM, TO) Index: gcc/config/bfin/bfin.c =================================================================== --- gcc/config/bfin/bfin.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/bfin/bfin.c 2017-09-11 17:55:39.957250744 +0100 @@ -2114,6 +2114,18 @@ bfin_expand_call (rtx retval, rtx fnaddr CALL_INSN_FUNCTION_USAGE (call) = use; } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +bfin_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (mode == PDImode && (regno == REG_A0 || regno == REG_A1)) + return 1; + if (mode == V2PDImode && (regno == REG_A0 || regno == REG_A1)) + return 2; + return CLASS_MAX_NREGS (GENERAL_REGS, mode); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. Do not allow to store a value in REG_CC for any mode. @@ -5862,6 +5874,8 @@ #define TARGET_DELAY_VARTRACK true #undef TARGET_CAN_USE_DOLOOP_P #define TARGET_CAN_USE_DOLOOP_P bfin_can_use_doloop_p +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS bfin_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK bfin_hard_regno_mode_ok Index: gcc/config/c6x/c6x.h =================================================================== --- gcc/config/c6x/c6x.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/c6x/c6x.h 2017-09-11 17:55:39.957250744 +0100 @@ -181,11 +181,6 @@ #define REG_ALLOC_ORDER \ REG_A1, REG_A2, REG_B0, REG_B1, REG_B2, REG_ILC \ } -#define HARD_REGNO_NREGS(regno, mode) \ - ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) \ - / UNITS_PER_WORD) - - /* Register Classes. */ enum reg_class Index: gcc/config/cr16/cr16.h =================================================================== --- gcc/config/cr16/cr16.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/cr16/cr16.h 2017-09-11 17:55:39.958250705 +0100 @@ -197,12 +197,8 @@ #define CALL_USED_REGISTERS /* Returns 1 if the register is longer than word size, 0 otherwise. */ #define LONG_REG_P(REGNO) \ - (HARD_REGNO_NREGS (REGNO, GET_MODE_WIDER_MODE (word_mode).require ()) == 1) - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((REGNO >= CR16_FIRST_DWORD_REGISTER) \ - ? ((GET_MODE_SIZE (MODE) + CR16_UNITS_PER_DWORD - 1) / CR16_UNITS_PER_DWORD)\ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) + (targetm.hard_regno_nregs (REGNO, \ + GET_MODE_WIDER_MODE (word_mode).require ()) == 1) #define NOTICE_UPDATE_CC(EXP, INSN) \ notice_update_cc ((EXP)) Index: gcc/config/cr16/cr16.c =================================================================== --- gcc/config/cr16/cr16.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/cr16/cr16.c 2017-09-11 17:55:39.958250705 +0100 @@ -220,6 +220,8 @@ #define TARGET_ASM_UNALIGNED_SI_OP TARG #undef TARGET_ASM_UNALIGNED_DI_OP #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS cr16_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK cr16_hard_regno_mode_ok #undef TARGET_MODES_TIEABLE_P @@ -468,6 +470,16 @@ cr16_regno_reg_class (int regno) return NO_REGS; } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +cr16_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (regno >= CR16_FIRST_DWORD_REGISTER) + return CEIL (GET_MODE_SIZE (mode), CR16_UNITS_PER_DWORD); + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. On the CR16 architecture, all registers can hold all modes, except that double precision floats (and double ints) must fall on even-register boundaries. */ @@ -1371,7 +1383,7 @@ cr16_memory_move_cost (machine_mode mode { /* One LD or ST takes twice the time of a simple reg-reg move. */ if (reg_classes_intersect_p (rclass, GENERAL_REGS)) - return (4 * HARD_REGNO_NREGS (0, mode)); + return (4 * cr16_hard_regno_nregs (0, mode)); else return (100); } Index: gcc/config/cris/cris.h =================================================================== --- gcc/config/cris/cris.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/cris/cris.h 2017-09-11 17:55:39.958250705 +0100 @@ -469,14 +469,6 @@ #define REG_ALLOC_ORDER_V32 \ {15, 9, 13, 12, 11, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 17, 16, 14, 18, 19} -/* Node: Values in Registers */ - -/* The VOIDmode test is so we can omit mode on anonymous insns. FIXME: - Still needed in 2.9x, at least for Axis-20000319. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - (MODE == VOIDmode \ - ? 1 : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - /* Node: Leaf Functions */ /* (no definitions) */ Index: gcc/config/cris/cris.c =================================================================== --- gcc/config/cris/cris.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/cris/cris.c 2017-09-11 17:55:39.958250705 +0100 @@ -163,6 +163,7 @@ static rtx cris_function_value(const_tre static rtx cris_libcall_value (machine_mode, const_rtx); static bool cris_function_value_regno_p (const unsigned int); static void cris_file_end (void); +static unsigned int cris_hard_regno_nregs (unsigned int, machine_mode); static bool cris_hard_regno_mode_ok (unsigned int, machine_mode); /* This is the parsed result of the "-max-stack-stackframe=" option. If @@ -281,6 +282,8 @@ #define TARGET_LIBCALL_VALUE cris_libcal #undef TARGET_FUNCTION_VALUE_REGNO_P #define TARGET_FUNCTION_VALUE_REGNO_P cris_function_value_regno_p +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS cris_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK cris_hard_regno_mode_ok @@ -4296,6 +4299,19 @@ cris_trampoline_init (rtx m_tramp, tree sake of a trampoline. */ } +/* Implement TARGET_HARD_REGNO_NREGS. + + The VOIDmode test is so we can omit mode on anonymous insns. FIXME: + Still needed in 2.9x, at least for Axis-20000319. */ + +static unsigned int +cris_hard_regno_nregs (unsigned int, machine_mode mode) +{ + if (mode == VOIDmode) + return 1; + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. CRIS permits all registers to hold all modes. Well, except for the Index: gcc/config/epiphany/epiphany.h =================================================================== --- gcc/config/epiphany/epiphany.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/epiphany/epiphany.h 2017-09-11 17:55:39.959250667 +0100 @@ -302,13 +302,6 @@ #define REG_ALLOC_ORDER \ #define HARD_REGNO_RENAME_OK(SRC, DST) epiphany_regno_rename_ok (SRC, DST) -/* 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 - but can be less for certain modes in special long registers. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ -((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Register classes and constants. */ /* Define the classes of registers for register constraints in the Index: gcc/config/fr30/fr30.h =================================================================== --- gcc/config/fr30/fr30.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/fr30/fr30.h 2017-09-11 17:55:39.959250667 +0100 @@ -238,15 +238,6 @@ #define ADDITIONAL_REGISTER_NAMES \ } /*}}}*/ -/*{{{ How Values Fit in Registers. */ - -/* A C expression for the number of consecutive hard registers, starting at - register number REGNO, required to hold a value of mode MODE. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - -/*}}}*/ /*{{{ Register Classes. */ /* An enumeral type that must be defined with all the register class names as @@ -345,16 +336,7 @@ #define REGNO_OK_FOR_BASE_P(NUM) 1 will reload one or both registers only if neither labeling works. */ #define REGNO_OK_FOR_INDEX_P(NUM) 1 -/* A C expression for the maximum number of consecutive registers of - class CLASS needed to hold a value of mode MODE. - - This is closely related to the macro `HARD_REGNO_NREGS'. In fact, the value - of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be the maximum value of - `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class CLASS. - - This macro helps control the handling of multiple-word values in - the reload pass. */ -#define CLASS_MAX_NREGS(CLASS, MODE) HARD_REGNO_NREGS (0, MODE) +#define CLASS_MAX_NREGS(CLASS, MODE) targetm.hard_regno_nregs (0, MODE) /*}}}*/ /*{{{ Basic Stack Layout. */ Index: gcc/config/frv/frv.h =================================================================== --- gcc/config/frv/frv.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/frv/frv.h 2017-09-11 17:55:39.961250590 +0100 @@ -747,22 +747,6 @@ #define REG_ALLOC_ORDER \ } -/* How Values Fit in Registers. */ - -/* A C expression for the number of consecutive hard registers, starting at - register number REGNO, required to hold a value of mode MODE. - - On a machine where all registers are exactly one word, a suitable definition - of this macro is - - #define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ - / UNITS_PER_WORD)) */ - -/* On the FRV, make the CC modes take 3 words in the integer registers, so that - we can build the appropriate instructions to properly reload the values. */ -#define HARD_REGNO_NREGS(REGNO, MODE) frv_hard_regno_nregs (REGNO, MODE) - /* Define this macro if the compiler should avoid copies to/from CCmode registers. You should only define this macro if support fo copying to/from CCmode is incomplete. */ @@ -930,17 +914,6 @@ #define SECONDARY_INPUT_RELOAD_CLASS(CLA #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ frv_secondary_reload_class (CLASS, MODE, X) -/* A C expression for the maximum number of consecutive registers of - class CLASS needed to hold a value of mode MODE. - - This is closely related to the macro `HARD_REGNO_NREGS'. In fact, the value - of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be the maximum value of - `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class CLASS. - - This macro helps control the handling of multiple-word values in - the reload pass. - - This declaration is required. */ #define CLASS_MAX_NREGS(CLASS, MODE) frv_class_max_nregs (CLASS, MODE) #define ZERO_P(x) (x == CONST0_RTX (GET_MODE (x))) Index: gcc/config/frv/frv-protos.h =================================================================== --- gcc/config/frv/frv-protos.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/frv/frv-protos.h 2017-09-11 17:55:39.959250667 +0100 @@ -74,7 +74,6 @@ extern void frv_ifcvt_modify_cancel (str extern enum reg_class frv_secondary_reload_class (enum reg_class, machine_mode, rtx); -extern int frv_hard_regno_nregs (int, machine_mode); extern int frv_class_max_nregs (enum reg_class rclass, machine_mode mode); extern machine_mode frv_select_cc_mode (enum rtx_code, rtx, rtx); Index: gcc/config/frv/frv.c =================================================================== --- gcc/config/frv/frv.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/frv/frv.c 2017-09-11 17:55:39.960250628 +0100 @@ -397,6 +397,7 @@ static bool frv_can_eliminate (const i static void frv_conditional_register_usage (void); static void frv_trampoline_init (rtx, tree, rtx); static bool frv_class_likely_spilled_p (reg_class_t); +static unsigned int frv_hard_regno_nregs (unsigned int, machine_mode); static bool frv_hard_regno_mode_ok (unsigned int, machine_mode); static bool frv_modes_tieable_p (machine_mode, machine_mode); @@ -516,6 +517,8 @@ #define TARGET_FUNCTION_VALUE frv_functi #undef TARGET_LIBCALL_VALUE #define TARGET_LIBCALL_VALUE frv_libcall_value +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS frv_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK frv_hard_regno_mode_ok #undef TARGET_MODES_TIEABLE_P @@ -6600,23 +6603,15 @@ frv_modes_tieable_p (machine_mode mode1, } -/* A C expression for the number of consecutive hard registers, starting at - register number REGNO, required to hold a value of mode MODE. +/* Implement TARGET_HARD_REGNO_NREGS. - On a machine where all registers are exactly one word, a suitable definition - of this macro is - - #define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ - / UNITS_PER_WORD)) */ - -/* On the FRV, make the CC_FP mode take 3 words in the integer registers, so + On the FRV, make the CC_FP mode take 3 words in the integer registers, so that we can build the appropriate instructions to properly reload the values. Also, make the byte-sized accumulator guards use one guard for each byte. */ -int -frv_hard_regno_nregs (int regno, machine_mode mode) +static unsigned int +frv_hard_regno_nregs (unsigned int regno, machine_mode mode) { if (ACCG_P (regno)) return GET_MODE_SIZE (mode); @@ -6625,17 +6620,7 @@ frv_hard_regno_nregs (int regno, machine } -/* A C expression for the maximum number of consecutive registers of - class RCLASS needed to hold a value of mode MODE. - - This is closely related to the macro `HARD_REGNO_NREGS'. In fact, the value - of the macro `CLASS_MAX_NREGS (RCLASS, MODE)' should be the maximum value of - `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class RCLASS. - - This macro helps control the handling of multiple-word values in - the reload pass. - - This declaration is required. */ +/* Implement CLASS_MAX_NREGS. */ int frv_class_max_nregs (enum reg_class rclass, machine_mode mode) Index: gcc/config/ft32/ft32.h =================================================================== --- gcc/config/ft32/ft32.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/ft32/ft32.h 2017-09-11 17:55:39.961250590 +0100 @@ -171,13 +171,6 @@ #define AVOID_CCMODE_COPIES 1 #define REGNO_REG_CLASS(R) ((R < FT32_PC) ? GENERAL_REGS : \ (R == FT32_CC ? CC_REGS : SPECIAL_REGS)) -/* A C expression for the number of consecutive hard registers, - starting at register number REGNO, required to hold a value of mode - MODE. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ - / UNITS_PER_WORD) - /* The Overall Framework of an Assembler File */ #undef ASM_SPEC Index: gcc/config/h8300/h8300.h =================================================================== --- gcc/config/h8300/h8300.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/h8300/h8300.h 2017-09-11 17:55:39.963250513 +0100 @@ -236,9 +236,6 @@ #define REG_ALLOC_ORDER \ /* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap fp */ \ { 2, 3, 0, 1, 4, 5, 6, 8, 7, 9, 10, 11 } -#define HARD_REGNO_NREGS(REGNO, MODE) \ - h8300_hard_regno_nregs ((REGNO), (MODE)) - /* A C expression that is nonzero if hard register NEW_REG can be considered for use as a rename register for OLD_REG register */ Index: gcc/config/h8300/h8300-protos.h =================================================================== --- gcc/config/h8300/h8300-protos.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/h8300/h8300-protos.h 2017-09-11 17:55:39.961250590 +0100 @@ -99,7 +99,6 @@ extern int h8300_current_function_monito extern int h8300_initial_elimination_offset (int, int); extern int h8300_regs_ok_for_stm (int, rtx[]); extern int h8300_hard_regno_rename_ok (unsigned int, unsigned int); -extern int h8300_hard_regno_nregs (int, machine_mode); extern bool h8300_move_ok (rtx, rtx); struct cpp_reader; Index: gcc/config/h8300/h8300.c =================================================================== --- gcc/config/h8300/h8300.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/h8300/h8300.c 2017-09-11 17:55:39.963250513 +0100 @@ -5878,17 +5878,6 @@ h8300_legitimate_address_p (machine_mode return 0; } -/* Worker function for HARD_REGNO_NREGS. - - We pretend the MAC register is 32bits -- we don't have any data - types on the H8 series to handle more than 32bits. */ - -int -h8300_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, machine_mode mode) -{ - return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; -} - /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool Index: gcc/config/i386/i386.h =================================================================== --- gcc/config/i386/i386.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/i386/i386.h 2017-09-11 17:55:39.969250282 +0100 @@ -1073,25 +1073,6 @@ #define ADJUST_REG_ALLOC_ORDER x86_order #define OVERRIDE_ABI_FORMAT(FNDECL) ix86_call_abi_override (FNDECL) -/* 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 - but can be less for certain modes in special long registers. - - Actually there are no two word move instructions for consecutive - registers. And only registers 0-3 may have mov byte instructions - applied to them. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - (GENERAL_REGNO_P (REGNO) \ - ? ((MODE) == XFmode \ - ? (TARGET_64BIT ? 2 : 3) \ - : ((MODE) == XCmode \ - ? (TARGET_64BIT ? 4 : 6) \ - : CEIL (GET_MODE_SIZE (MODE), UNITS_PER_WORD))) \ - : (COMPLEX_MODE_P (MODE) ? 2 : \ - (((MODE == V64SFmode) || (MODE == V64SImode)) ? 4 : 1))) - #define HARD_REGNO_NREGS_HAS_PADDING(REGNO, MODE) \ (TARGET_128BIT_LONG_DOUBLE && !TARGET_64BIT \ && GENERAL_REGNO_P (REGNO) \ Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/i386/i386.c 2017-09-11 17:55:39.968250321 +0100 @@ -41410,6 +41410,32 @@ ix86_register_move_cost (machine_mode mo return 2; } +/* Implement TARGET_HARD_REGNO_NREGS. This is ordinarily the length in + words of a value of mode MODE but can be less for certain modes in + special long registers. + + Actually there are no two word move instructions for consecutive + registers. And only registers 0-3 may have mov byte instructions + applied to them. */ + +static unsigned int +ix86_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (GENERAL_REGNO_P (regno)) + { + if (mode == XFmode) + return TARGET_64BIT ? 2 : 3; + if (mode == XCmode) + return TARGET_64BIT ? 4 : 6; + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); + } + if (COMPLEX_MODE_P (mode)) + return 2; + if (mode == V64SFmode || mode == V64SImode) + return 4; + return 1; +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool @@ -53376,6 +53402,8 @@ #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_NREGS +#define TARGET_HARD_REGNO_NREGS ix86_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK ix86_hard_regno_mode_ok Index: gcc/config/ia64/ia64.h =================================================================== --- gcc/config/ia64/ia64.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/ia64/ia64.h 2017-09-11 17:55:39.970250244 +0100 @@ -598,22 +598,6 @@ #define REG_ALLOC_ORDER \ /* How Values Fit in Registers */ -/* A C expression for the number of consecutive hard registers, starting at - register number REGNO, required to hold a value of mode MODE. */ - -/* ??? We say that BImode PR values require two registers. This allows us to - easily store the normal and inverted values. We use CCImode to indicate - a single predicate register. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((REGNO) == PR_REG (0) && (MODE) == DImode ? 64 \ - : PR_REGNO_P (REGNO) && (MODE) == BImode ? 2 \ - : (PR_REGNO_P (REGNO) || GR_REGNO_P (REGNO)) && (MODE) == CCImode ? 1\ - : FR_REGNO_P (REGNO) && (MODE) == XFmode ? 1 \ - : FR_REGNO_P (REGNO) && (MODE) == RFmode ? 1 \ - : FR_REGNO_P (REGNO) && (MODE) == XCmode ? 2 \ - : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Specify the modes required to caller save a given hard regno. We need to ensure floating pt regs are not saved as DImode. */ @@ -803,7 +787,7 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, /* A C expression for the maximum number of consecutive registers of class CLASS needed to hold a value of mode MODE. - This is closely related to the macro `HARD_REGNO_NREGS'. */ + This is closely related to TARGET_HARD_REGNO_NREGS. */ #define CLASS_MAX_NREGS(CLASS, MODE) \ ((MODE) == BImode && (CLASS) == PR_REGS ? 2 \ Index: gcc/config/ia64/ia64.c =================================================================== --- gcc/config/ia64/ia64.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/ia64/ia64.c 2017-09-11 17:55:39.969250282 +0100 @@ -336,6 +336,7 @@ static section * ia64_hpux_function_sect static bool ia64_vectorize_vec_perm_const_ok (machine_mode vmode, const unsigned char *sel); +static unsigned int ia64_hard_regno_nregs (unsigned int, machine_mode); static bool ia64_hard_regno_mode_ok (unsigned int, machine_mode); static bool ia64_modes_tieable_p (machine_mode, machine_mode); @@ -659,6 +660,8 @@ #define TARGET_ATTRIBUTE_TAKES_IDENTIFIE #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 0 +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS ia64_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK ia64_hard_regno_mode_ok @@ -4263,6 +4266,30 @@ ia64_hard_regno_rename_ok (int from, int return 1; } +/* Implement TARGET_HARD_REGNO_NREGS. + + ??? We say that BImode PR values require two registers. This allows us to + easily store the normal and inverted values. We use CCImode to indicate + a single predicate register. */ + +static unsigned int +ia64_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (regno == PR_REG (0) && mode == DImode) + return 64; + if (PR_REGNO_P (regno) && (mode) == BImode) + return 2; + if ((PR_REGNO_P (regno) || GR_REGNO_P (regno)) && mode == CCImode) + return 1; + if (FR_REGNO_P (regno) && mode == XFmode) + return 1; + if (FR_REGNO_P (regno) && mode == RFmode) + return 1; + if (FR_REGNO_P (regno) && mode == XCmode) + return 2; + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool Index: gcc/config/iq2000/iq2000.h =================================================================== --- gcc/config/iq2000/iq2000.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/iq2000/iq2000.h 2017-09-11 17:55:39.970250244 +0100 @@ -160,10 +160,6 @@ #define REG_ALLOC_ORDER \ } -/* How Values Fit in Registers. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) #define AVOID_CCMODE_COPIES Index: gcc/config/lm32/lm32.h =================================================================== --- gcc/config/lm32/lm32.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/lm32/lm32.h 2017-09-11 17:55:39.970250244 +0100 @@ -163,9 +163,6 @@ #define CALL_USED_REGISTERS \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 1, 0, 1, 0, 1, 1} -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - #define AVOID_CCMODE_COPIES /*----------------------------------*/ Index: gcc/config/m32c/m32c.h =================================================================== --- gcc/config/m32c/m32c.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/m32c/m32c.h 2017-09-11 17:55:39.971250205 +0100 @@ -255,7 +255,6 @@ #define REG_ALLOC_ORDER { \ /* How Values Fit in Registers */ -#define HARD_REGNO_NREGS(R,M) m32c_hard_regno_nregs (R, M) #define AVOID_CCMODE_COPIES /* Register Classes */ Index: gcc/config/m32c/m32c-protos.h =================================================================== --- gcc/config/m32c/m32c-protos.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/m32c/m32c-protos.h 2017-09-11 17:55:39.970250244 +0100 @@ -49,7 +49,6 @@ int m32c_expand_movstr (rtx *); void m32c_expand_neg_mulpsi3 (rtx *); int m32c_expand_setmemhi (rtx *); bool m32c_matches_constraint_p (rtx, int); -int m32c_hard_regno_nregs (int, machine_mode); bool m32c_illegal_subreg_p (rtx); bool m32c_immd_dbl_mov (rtx *, machine_mode); rtx m32c_incoming_return_addr_rtx (void); Index: gcc/config/m32c/m32c.c =================================================================== --- gcc/config/m32c/m32c.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/m32c/m32c.c 2017-09-11 17:55:39.971250205 +0100 @@ -539,11 +539,11 @@ m32c_conditional_register_usage (void) /* How Values Fit in Registers */ -/* Implements HARD_REGNO_NREGS. This is complicated by the fact that +/* Implements TARGET_HARD_REGNO_NREGS. This is complicated by the fact that different registers are different sizes from each other, *and* may be different sizes in different chip families. */ -static int -m32c_hard_regno_nregs_1 (int regno, machine_mode mode) +static unsigned int +m32c_hard_regno_nregs_1 (unsigned int regno, machine_mode mode) { if (regno == FLG_REGNO && mode == CCmode) return 1; @@ -568,10 +568,10 @@ m32c_hard_regno_nregs_1 (int regno, mach return 0; } -int -m32c_hard_regno_nregs (int regno, machine_mode mode) +static unsigned int +m32c_hard_regno_nregs (unsigned int regno, machine_mode mode) { - int rv = m32c_hard_regno_nregs_1 (regno, mode); + unsigned int rv = m32c_hard_regno_nregs_1 (regno, mode); return rv ? rv : 1; } @@ -4489,6 +4489,8 @@ #define TARGET_ENCODE_SECTION_INFO m32c_ #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED hook_bool_void_true +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS m32c_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK m32c_hard_regno_mode_ok #undef TARGET_MODES_TIEABLE_P Index: gcc/config/m32r/m32r.h =================================================================== --- gcc/config/m32r/m32r.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/m32r/m32r.h 2017-09-11 17:55:39.971250205 +0100 @@ -389,13 +389,6 @@ #define REG_ALLOC_ORDER \ } #endif -/* 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 - but can be less for certain modes in special long registers. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - #define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \ m32r_hard_regno_rename_ok (OLD_REG, NEW_REG) Index: gcc/config/m68k/m68k.h =================================================================== --- gcc/config/m68k/m68k.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/m68k/m68k.h 2017-09-11 17:55:39.972250167 +0100 @@ -381,13 +381,6 @@ #define REG_ALLOC_ORDER \ } -/* On the m68k, ordinary registers hold 32 bits worth; - for the 68881 registers, a single register is always enough for - anything that can be stored in them at all. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((REGNO) >= 16 ? GET_MODE_NUNITS (MODE) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - /* A C expression that is nonzero if hard register NEW_REG can be considered for use as a rename register for OLD_REG register. */ Index: gcc/config/m68k/m68k.c =================================================================== --- gcc/config/m68k/m68k.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/m68k/m68k.c 2017-09-11 17:55:39.971250205 +0100 @@ -187,6 +187,7 @@ static bool m68k_output_addr_const_extra static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED; static enum flt_eval_method m68k_excess_precision (enum excess_precision_type); +static unsigned int m68k_hard_regno_nregs (unsigned int, machine_mode); static bool m68k_hard_regno_mode_ok (unsigned int, machine_mode); static bool m68k_modes_tieable_p (machine_mode, machine_mode); @@ -336,6 +337,8 @@ #define TARGET_C_EXCESS_PRECISION m68k_e #undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL #define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 128 +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS m68k_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK m68k_hard_regno_mode_ok @@ -5178,6 +5181,20 @@ m68k_hard_regno_rename_ok (unsigned int return 1; } +/* Implement TARGET_HARD_REGNO_NREGS. + + On the m68k, ordinary registers hold 32 bits worth; + for the 68881 registers, a single register is always enough for + anything that can be stored in them at all. */ + +static unsigned int +m68k_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (regno >= 16) + return GET_MODE_NUNITS (mode); + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. On the 68000, we let the cpu registers can hold any mode, but restrict the 68881 registers to floating-point modes. */ Index: gcc/config/mcore/mcore.h =================================================================== --- gcc/config/mcore/mcore.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/mcore/mcore.h 2017-09-11 17:55:39.972250167 +0100 @@ -239,15 +239,6 @@ #define REG_ALLOC_ORDER \ /* r7 r6 r5 r4 r3 r2 r15 r14 r13 r12 r11 r10 r9 r8 r1 r0 ap c fp x19*/ \ { 7, 6, 5, 4, 3, 2, 15, 14, 13, 12, 11, 10, 9, 8, 1, 0, 16, 17, 18, 19} -/* 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 - but can be less for certain modes in special long registers. - - On the MCore regs are UNITS_PER_WORD bits wide; */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - (((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - /* Definitions for register eliminations. We have two registers that can be eliminated on the MCore. First, the Index: gcc/config/microblaze/microblaze.h =================================================================== --- gcc/config/microblaze/microblaze.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/microblaze/microblaze.h 2017-09-11 17:55:39.972250167 +0100 @@ -292,9 +292,6 @@ #define FRP_REG_NUM 35 #define GP_REG_P(REGNO) ((unsigned) ((REGNO) - GP_REG_FIRST) < GP_REG_NUM) #define ST_REG_P(REGNO) ((REGNO) == ST_REG) -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - #define STACK_POINTER_REGNUM (GP_REG_FIRST + MB_ABI_STACK_POINTER_REGNUM) #define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(FNDECL) Index: gcc/config/mips/mips.h =================================================================== --- gcc/config/mips/mips.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/mips/mips.h 2017-09-11 17:55:39.974250090 +0100 @@ -1959,8 +1959,6 @@ #define COPNUM_AS_CHAR_FROM_REGNUM(REGNO : COP3_REG_P (REGNO) ? '3' : '?') -#define HARD_REGNO_NREGS(REGNO, MODE) mips_hard_regno_nregs (REGNO, MODE) - #define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \ mips_hard_regno_rename_ok (OLD_REG, NEW_REG) Index: gcc/config/mips/mips-protos.h =================================================================== --- gcc/config/mips/mips-protos.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/mips/mips-protos.h 2017-09-11 17:55:39.972250167 +0100 @@ -323,7 +323,6 @@ extern const char *mips_output_division extern const char *mips_msa_output_division (const char *, rtx *); extern const char *mips_output_probe_stack_range (rtx, rtx); extern bool mips_hard_regno_rename_ok (unsigned int, unsigned int); -extern unsigned int mips_hard_regno_nregs (int, machine_mode); extern bool mips_linked_madd_p (rtx_insn *, rtx_insn *); extern bool mips_store_data_bypass_p (rtx_insn *, rtx_insn *); extern int mips_dspalu_bypass_p (rtx, rtx); Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/mips/mips.c 2017-09-11 17:55:39.974250090 +0100 @@ -12886,10 +12886,10 @@ mips_hard_regno_call_part_clobbered (uns return false; } -/* Implement HARD_REGNO_NREGS. */ +/* Implement TARGET_HARD_REGNO_NREGS. */ -unsigned int -mips_hard_regno_nregs (int regno, machine_mode mode) +static unsigned int +mips_hard_regno_nregs (unsigned int regno, machine_mode mode) { if (ST_REG_P (regno)) /* The size of FP status registers is always 4, because they only hold @@ -22589,6 +22589,8 @@ #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_NREGS +#define TARGET_HARD_REGNO_NREGS mips_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK mips_hard_regno_mode_ok Index: gcc/config/mmix/mmix.h =================================================================== --- gcc/config/mmix/mmix.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/mmix/mmix.h 2017-09-11 17:55:39.974250090 +0100 @@ -380,12 +380,6 @@ #define MMIX_GNU_ABI_REG_ALLOC_ORDER \ /* The default one. */ #define REG_ALLOC_ORDER MMIX_MMIXWARE_ABI_REG_ALLOC_ORDER -/* Node: Values in Registers */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ - / UNITS_PER_WORD) - /* Node: Leaf Functions */ /* (empty) */ @@ -438,7 +432,7 @@ #define SECONDARY_INPUT_RELOAD_CLASS(CLA #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ mmix_secondary_reload_class (CLASS, MODE, X, 0) -#define CLASS_MAX_NREGS(CLASS, MODE) HARD_REGNO_NREGS (CLASS, MODE) +#define CLASS_MAX_NREGS(CLASS, MODE) targetm.hard_regno_nregs (CLASS, MODE) /* Node: Frame Layout */ Index: gcc/config/mn10300/mn10300.h =================================================================== --- gcc/config/mn10300/mn10300.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/mn10300/mn10300.h 2017-09-11 17:55:39.975250051 +0100 @@ -224,15 +224,6 @@ #define REG_ALLOC_ORDER \ , 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 50, 51 \ } -/* 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 - but can be less for certain modes in special long registers. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* 4 data, and effectively 3 address registers is small as far as I'm concerned. */ #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true Index: gcc/config/moxie/moxie.h =================================================================== --- gcc/config/moxie/moxie.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/moxie/moxie.h 2017-09-11 17:55:39.975250051 +0100 @@ -176,13 +176,6 @@ #define AVOID_CCMODE_COPIES 1 #define REGNO_REG_CLASS(R) ((R < MOXIE_PC) ? GENERAL_REGS : \ (R == MOXIE_CC ? CC_REGS : SPECIAL_REGS)) -/* A C expression for the number of consecutive hard registers, - starting at register number REGNO, required to hold a value of mode - MODE. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ - / UNITS_PER_WORD) - /* The Overall Framework of an Assembler File */ #undef ASM_SPEC Index: gcc/config/msp430/msp430.h =================================================================== --- gcc/config/msp430/msp430.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/msp430/msp430.h 2017-09-11 17:55:39.975250051 +0100 @@ -332,9 +332,6 @@ #define PROFILE_BEFORE_PROLOGUE 1 #define FUNCTION_PROFILER(FILE, LABELNO) \ fprintf (FILE, "\tcall\t__mcount\n"); -#define HARD_REGNO_NREGS(REGNO, MODE) \ - msp430_hard_regno_nregs (REGNO, MODE) - /* Exception Handling */ /* R12,R13,R14 - EH data Index: gcc/config/msp430/msp430-protos.h =================================================================== --- gcc/config/msp430/msp430-protos.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/msp430/msp430-protos.h 2017-09-11 17:55:39.975250051 +0100 @@ -29,7 +29,6 @@ void msp430_expand_helper (rtx *operands void msp430_expand_prologue (void); const char * msp430x_extendhisi (rtx *); void msp430_fixup_compare_operands (machine_mode, rtx *); -int msp430_hard_regno_nregs (int, machine_mode); int msp430_hard_regno_nregs_has_padding (int, machine_mode); int msp430_hard_regno_nregs_with_padding (int, machine_mode); bool msp430_hwmult_enabled (void); Index: gcc/config/msp430/msp430.c =================================================================== --- gcc/config/msp430/msp430.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/msp430/msp430.c 2017-09-11 17:55:39.975250051 +0100 @@ -900,11 +900,11 @@ msp430_ms_bitfield_layout_p (const_tree /* Register Usage */ -/* Implements HARD_REGNO_NREGS. MSP430X registers can hold a single - PSImode value, but not an SImode value. */ -int -msp430_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, - machine_mode mode) +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS msp430_hard_regno_nregs + +static unsigned int +msp430_hard_regno_nregs (unsigned int, machine_mode mode) { if (mode == PSImode && msp430x) return 1; Index: gcc/config/nds32/nds32.h =================================================================== --- gcc/config/nds32/nds32.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/nds32/nds32.h 2017-09-11 17:55:39.976250013 +0100 @@ -596,10 +596,6 @@ #define REG_ALLOC_ORDER \ own cost calculations. */ #define HONOR_REG_ALLOC_ORDER optimize_size -/* The number of consecutive hard regs needed starting at - reg "regno" for holding a value of mode "mode". */ -#define HARD_REGNO_NREGS(regno, mode) nds32_hard_regno_nregs (regno, mode) - /* Register Classes. */ Index: gcc/config/nds32/nds32-protos.h =================================================================== --- gcc/config/nds32/nds32-protos.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/nds32/nds32-protos.h 2017-09-11 17:55:39.975250051 +0100 @@ -26,13 +26,6 @@ extern void nds32_init_expanders (void); -/* Register Usage. */ - -/* -- How Values Fit in Registers. */ - -extern int nds32_hard_regno_nregs (int, machine_mode); - - /* Register Classes. */ extern enum reg_class nds32_regno_reg_class (int); Index: gcc/config/nds32/nds32.c =================================================================== --- gcc/config/nds32/nds32.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/nds32/nds32.c 2017-09-11 17:55:39.976250013 +0100 @@ -2746,20 +2746,13 @@ nds32_init_expanders (void) /* -- How Values Fit in Registers. */ -int -nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, - machine_mode mode) -{ - return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); -} - /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool nds32_hard_regno_mode_ok (unsigned int regno, machine_mode mode) { /* Restrict double-word quantities to even register pairs. */ - if (HARD_REGNO_NREGS (regno, mode) == 1 + if (targetm.hard_regno_nregs (regno, mode) == 1 || !((regno) & 1)) return true; Index: gcc/config/nios2/nios2.h =================================================================== --- gcc/config/nios2/nios2.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/nios2/nios2.h 2017-09-11 17:55:39.976250013 +0100 @@ -172,9 +172,6 @@ #define CALL_USED_REGISTERS /* 30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ } -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Order in which to allocate registers. Each register must be listed once. This is the default ordering for R1 and non-CDX R2 code. For CDX, we overwrite this in ADJUST_REG_ALLOC_ORDER. */ Index: gcc/config/nvptx/nvptx.h =================================================================== --- gcc/config/nvptx/nvptx.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/nvptx/nvptx.h 2017-09-11 17:55:39.977249974 +0100 @@ -95,8 +95,6 @@ #define FIRST_PSEUDO_REGISTER 16 #define FIXED_REGISTERS { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } #define CALL_USED_REGISTERS { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } -#define HARD_REGNO_NREGS(REG, MODE) \ - ((void)(REG), (void)(MODE), 1) #define CANNOT_CHANGE_MODE_CLASS(M1, M2, CLS) \ ((void)(M1), (void)(M2), (void)(CLS), true) Index: gcc/config/nvptx/nvptx.c =================================================================== --- gcc/config/nvptx/nvptx.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/nvptx/nvptx.c 2017-09-11 17:55:39.977249974 +0100 @@ -5521,6 +5521,14 @@ nvptx_modes_tieable_p (machine_mode, mac return false; } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +nvptx_hard_regno_nregs (unsigned int, machine_mode) +{ + return 1; +} + #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE nvptx_option_override @@ -5648,6 +5656,9 @@ #define TARGET_VECTORIZE_PREFERRED_SIMD_ #undef TARGET_MODES_TIEABLE_P #define TARGET_MODES_TIEABLE_P nvptx_modes_tieable_p +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS nvptx_hard_regno_nregs + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-nvptx.h" Index: gcc/config/pa/pa32-regs.h =================================================================== --- gcc/config/pa/pa32-regs.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/pa/pa32-regs.h 2017-09-11 17:55:39.978249936 +0100 @@ -166,7 +166,7 @@ #define REG_ALLOC_ORDER \ point registers are 64 bits wide. Snake fp regs are treated as 32 bits wide since the left and right parts are independently accessible. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ +#define PA_HARD_REGNO_NREGS(REGNO, MODE) \ (FP_REGNO_P (REGNO) \ ? (!TARGET_PA_11 \ ? COMPLEX_MODE_P (MODE) ? 2 : 1 \ Index: gcc/config/pa/pa64-regs.h =================================================================== --- gcc/config/pa/pa64-regs.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/pa/pa64-regs.h 2017-09-11 17:55:39.978249936 +0100 @@ -137,7 +137,7 @@ #define REG_ALLOC_ORDER \ WORD_SIZE bits. Note that SCmode values are placed in a single FPR. Thus, any patterns defined to operate on these values would have to use the 32-bit addressability of the FPR registers. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ +#define PA_HARD_REGNO_NREGS(REGNO, MODE) \ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) /* These are the valid FP modes. */ Index: gcc/config/pa/pa.c =================================================================== --- gcc/config/pa/pa.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/pa/pa.c 2017-09-11 17:55:39.978249936 +0100 @@ -199,6 +199,7 @@ static unsigned int pa_section_type_flag static bool pa_legitimate_address_p (machine_mode, rtx, bool); static bool pa_callee_copies (cumulative_args_t, machine_mode, const_tree, bool); +static unsigned int pa_hard_regno_nregs (unsigned int, machine_mode); static bool pa_hard_regno_mode_ok (unsigned int, machine_mode); static bool pa_modes_tieable_p (machine_mode, machine_mode); @@ -409,6 +410,8 @@ #define TARGET_LEGITIMATE_ADDRESS_P pa_l #undef TARGET_LRA_P #define TARGET_LRA_P hook_bool_void_false +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS pa_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK pa_hard_regno_mode_ok #undef TARGET_MODES_TIEABLE_P @@ -10765,6 +10768,14 @@ pa_callee_copies (cumulative_args_t cum return !TARGET_CALLER_COPIES; } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +pa_hard_regno_nregs (unsigned int regno ATTRIBUTE_UNUSED, machine_mode mode) +{ + return PA_HARD_REGNO_NREGS (regno, mode); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool Index: gcc/config/pdp11/pdp11.h =================================================================== --- gcc/config/pdp11/pdp11.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/pdp11/pdp11.h 2017-09-11 17:55:39.978249936 +0100 @@ -164,18 +164,6 @@ #define CALL_USED_REGISTERS \ 0, 0, 0, 0, 0, 0, 1, 1 } -/* 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 - but can be less for certain modes in special long registers. -*/ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ -((REGNO <= PC_REGNUM)? \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) \ - :1) - - /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ Index: gcc/config/pdp11/pdp11.c =================================================================== --- gcc/config/pdp11/pdp11.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/pdp11/pdp11.c 2017-09-11 17:55:39.978249936 +0100 @@ -236,6 +236,8 @@ #define TARGET_LEGITIMATE_CONSTANT_P pdp #undef TARGET_SCALAR_MODE_SUPPORTED_P #define TARGET_SCALAR_MODE_SUPPORTED_P pdp11_scalar_mode_supported_p +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS pdp11_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK pdp11_hard_regno_mode_ok @@ -1931,6 +1933,16 @@ pdp11_branch_cost () return (TARGET_BRANCH_CHEAP ? 0 : 1); } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +pdp11_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (regno <= PC_REGNUM) + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); + return 1; +} + /* Implement TARGET_HARD_REGNO_MODE_OK. On the pdp, the cpu registers can hold any mode other than float (because otherwise we may end up being asked to move from CPU to FPU register, which isn't a valid Index: gcc/config/powerpcspe/powerpcspe.h =================================================================== --- gcc/config/powerpcspe/powerpcspe.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/powerpcspe/powerpcspe.h 2017-09-11 17:55:39.992249397 +0100 @@ -1263,11 +1263,6 @@ #define VLOGICAL_REGNO_P(N) \ (INT_REGNO_P (N) || ALTIVEC_REGNO_P (N) \ || (TARGET_VSX && FP_REGNO_P (N))) \ -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)] - /* When setting up caller-save slots (MODE == VOIDmode) ensure we allocate enough space to account for vectors in FP regs. However, TFmode/TDmode should not use VSX instructions to do a caller save. */ Index: gcc/config/powerpcspe/powerpcspe.c =================================================================== --- gcc/config/powerpcspe/powerpcspe.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/powerpcspe/powerpcspe.c 2017-09-11 17:55:39.991249436 +0100 @@ -1977,6 +1977,8 @@ #define TARGET_OPTAB_SUPPORTED_P rs6000_ #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1 +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS rs6000_hard_regno_nregs_hook #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK rs6000_hard_regno_mode_ok @@ -2174,6 +2176,14 @@ rs6000_hard_regno_mode_ok_uncached (int return GET_MODE_SIZE (mode) <= UNITS_PER_WORD; } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +rs6000_hard_regno_nregs_hook (unsigned int regno, machine_mode mode) +{ + return rs6000_hard_regno_nregs[mode][regno]; +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool Index: gcc/config/riscv/riscv.h =================================================================== --- gcc/config/riscv/riscv.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/riscv/riscv.h 2017-09-11 17:55:39.994249320 +0100 @@ -292,8 +292,6 @@ #define FP_REG_P(REGNO) \ #define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X))) -#define HARD_REGNO_NREGS(REGNO, MODE) riscv_hard_regno_nregs (REGNO, MODE) - /* Use s0 as the frame pointer if it is so requested. */ #define HARD_FRAME_POINTER_REGNUM 8 #define STACK_POINTER_REGNUM 2 Index: gcc/config/riscv/riscv-protos.h =================================================================== --- gcc/config/riscv/riscv-protos.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/riscv/riscv-protos.h 2017-09-11 17:55:39.992249397 +0100 @@ -68,7 +68,6 @@ extern void riscv_expand_prologue (void) extern void riscv_expand_epilogue (bool); extern bool riscv_can_use_return_insn (void); extern rtx riscv_function_value (const_tree, const_tree, machine_mode); -extern unsigned int riscv_hard_regno_nregs (int, machine_mode); /* Routines implemented in riscv-c.c. */ void riscv_cpu_cpp_builtins (cpp_reader *); Index: gcc/config/riscv/riscv.c =================================================================== --- gcc/config/riscv/riscv.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/riscv/riscv.c 2017-09-11 17:55:39.993249359 +0100 @@ -3519,6 +3519,18 @@ riscv_register_move_cost (machine_mode m return SECONDARY_MEMORY_NEEDED (from, to, mode) ? 8 : 2; } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +riscv_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (FP_REG_P (regno)) + return (GET_MODE_SIZE (mode) + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG; + + /* All other registers are word-sized. */ + return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool @@ -3571,18 +3583,6 @@ riscv_modes_tieable_p (machine_mode mode && GET_MODE_CLASS (mode2) == MODE_FLOAT)); } -/* Implement HARD_REGNO_NREGS. */ - -unsigned int -riscv_hard_regno_nregs (int regno, machine_mode mode) -{ - if (FP_REG_P (regno)) - return (GET_MODE_SIZE (mode) + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG; - - /* All other registers are word-sized. */ - return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; -} - /* Implement CLASS_MAX_NREGS. */ static unsigned char @@ -4104,6 +4104,8 @@ #define TARGET_BUILTIN_DECL riscv_builti #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN riscv_expand_builtin +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS riscv_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK riscv_hard_regno_mode_ok Index: gcc/config/rl78/rl78.h =================================================================== --- gcc/config/rl78/rl78.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/rl78/rl78.h 2017-09-11 17:55:39.996249243 +0100 @@ -407,10 +407,6 @@ #define FUNCTION_PROFILER(FILE, LABELNO) fprintf (FILE, "\tbsr\t__mcount\n"); -#define HARD_REGNO_NREGS(REGNO, MODE) \ - rl78_hard_regno_nregs (REGNO, MODE) - - #define TEXT_SECTION_ASM_OP ".text" #define DATA_SECTION_ASM_OP ".data" #define BSS_SECTION_ASM_OP ".bss" Index: gcc/config/rl78/rl78-protos.h =================================================================== --- gcc/config/rl78/rl78-protos.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/rl78/rl78-protos.h 2017-09-11 17:55:39.994249320 +0100 @@ -29,7 +29,6 @@ void rl78_expand_eh_epilogue (rtx); void rl78_expand_epilogue (void); void rl78_expand_prologue (void); int rl78_far_p (rtx x); -int rl78_hard_regno_nregs (int, machine_mode); bool rl78_hl_b_c_addr_p (rtx); int rl78_initial_elimination_offset (int, int); bool rl78_as_legitimate_address (machine_mode, rtx, Index: gcc/config/rl78/rl78.c =================================================================== --- gcc/config/rl78/rl78.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/rl78/rl78.c 2017-09-11 17:55:39.995249282 +0100 @@ -449,9 +449,11 @@ rl78_real_insns_ok (void) return false; } -/* Implements HARD_REGNO_NREGS. */ -int -rl78_hard_regno_nregs (int regno, machine_mode mode) +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS rl78_hard_regno_nregs + +static unsigned int +rl78_hard_regno_nregs (unsigned int regno, machine_mode mode) { int rs = register_sizes[regno]; if (rs < 1) Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/rs6000/rs6000.h 2017-09-11 17:55:40.006248859 +0100 @@ -1202,11 +1202,6 @@ #define VLOGICAL_REGNO_P(N) \ (INT_REGNO_P (N) || ALTIVEC_REGNO_P (N) \ || (TARGET_VSX && FP_REGNO_P (N))) \ -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)] - /* When setting up caller-save slots (MODE == VOIDmode) ensure we allocate enough space to account for vectors in FP regs. However, TFmode/TDmode should not use VSX instructions to do a caller save. */ Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/rs6000/rs6000.c 2017-09-11 17:55:40.005248897 +0100 @@ -1967,6 +1967,8 @@ #define TARGET_GET_FUNCTION_VERSIONS_DIS #undef TARGET_OPTION_FUNCTION_VERSIONS #define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS rs6000_hard_regno_nregs_hook #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK rs6000_hard_regno_mode_ok @@ -2141,6 +2143,14 @@ rs6000_hard_regno_mode_ok_uncached (int return GET_MODE_SIZE (mode) <= UNITS_PER_WORD; } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +rs6000_hard_regno_nregs_hook (unsigned int regno, machine_mode mode) +{ + return rs6000_hard_regno_nregs[mode][regno]; +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool Index: gcc/config/rx/rx.h =================================================================== --- gcc/config/rx/rx.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/rx/rx.h 2017-09-11 17:55:40.007248820 +0100 @@ -331,10 +331,6 @@ #define FUNCTION_PROFILER(FILE, LABELNO) fprintf (FILE, "\tbsr\t__mcount\n"); -#define HARD_REGNO_NREGS(REGNO, MODE) CLASS_MAX_NREGS (0, MODE) - - - #define REGISTER_NAMES \ { \ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ Index: gcc/config/rx/rx.c =================================================================== --- gcc/config/rx/rx.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/rx/rx.c 2017-09-11 17:55:40.007248820 +0100 @@ -3434,6 +3434,14 @@ rx_atomic_sequence::~rx_atomic_sequence emit_insn (gen_mvtc (GEN_INT (CTRLREG_PSW), m_prev_psw_reg)); } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +rx_hard_regno_nregs (unsigned int, machine_mode mode) +{ + return CLASS_MAX_NREGS (0, mode); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool @@ -3606,6 +3614,8 @@ #define TARGET_WARN_FUNC_RETURN rx_war #undef TARGET_LRA_P #define TARGET_LRA_P rx_enable_lra +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS rx_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK rx_hard_regno_mode_ok Index: gcc/config/s390/s390.h =================================================================== --- gcc/config/s390/s390.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/s390/s390.h 2017-09-11 17:55:40.011248666 +0100 @@ -469,29 +469,6 @@ #define REG_ALLOC_ORDER \ 15, 32, 33, 34, 35, 36, 37 } -/* Fitting values into registers. */ - -/* Integer modes <= word size fit into any GPR. - Integer modes > word size fit into successive GPRs, starting with - an even-numbered register. - SImode and DImode fit into FPRs as well. - - Floating point modes <= word size fit into any FPR or GPR. - Floating point modes > word size (i.e. DFmode on 32-bit) fit - into any FPR, or an even-odd GPR pair. - TFmode fits only into an even-odd FPR pair. - - Complex floating point modes fit either into two FPRs, or into - successive GPRs (again starting with an even number). - TCmode fits only into two successive even-odd FPR pairs. - - Condition code modes fit only into the CC register. */ - -/* Because all registers in a class have the same size HARD_REGNO_NREGS - is equivalent to CLASS_MAX_NREGS. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - s390_class_max_nregs (REGNO_REG_CLASS (REGNO), (MODE)) - #define HARD_REGNO_RENAME_OK(FROM, TO) \ s390_hard_regno_rename_ok ((FROM), (TO)) Index: gcc/config/s390/s390.c =================================================================== --- gcc/config/s390/s390.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/s390/s390.c 2017-09-11 17:55:40.011248666 +0100 @@ -496,7 +496,7 @@ #define CONST_OK_FOR_On(x) \ CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On") #define REGNO_PAIR_OK(REGNO, MODE) \ - (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1)) + (s390_hard_regno_nregs ((REGNO), (MODE)) == 1 || !((REGNO) & 1)) /* That's the read ahead of the dynamic branch prediction unit in bytes on a z10 (or higher) CPU. */ @@ -10383,7 +10383,32 @@ s390_optimize_nonescaping_tx (void) return; } -/* Implement TARGET_HARD_REGNO_MODE_OK. */ +/* Implement TARGET_HARD_REGNO_NREGS. Because all registers in a class + have the same size, this is equivalent to CLASS_MAX_NREGS. */ + +static unsigned int +s390_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + return s390_class_max_nregs (REGNO_REG_CLASS (regno), mode); +} + +/* Implement TARGET_HARD_REGNO_MODE_OK. + + Integer modes <= word size fit into any GPR. + Integer modes > word size fit into successive GPRs, starting with + an even-numbered register. + SImode and DImode fit into FPRs as well. + + Floating point modes <= word size fit into any FPR or GPR. + Floating point modes > word size (i.e. DFmode on 32-bit) fit + into any FPR, or an even-odd GPR pair. + TFmode fits only into an even-odd FPR pair. + + Complex floating point modes fit either into two FPRs, or into + successive GPRs (again starting with an even number). + TCmode fits only into two successive even-odd FPR pairs. + + Condition code modes fit only into the CC register. */ static bool s390_hard_regno_mode_ok (unsigned int regno, machine_mode mode) @@ -15977,6 +16002,8 @@ #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_NREGS +#define TARGET_HARD_REGNO_NREGS s390_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK s390_hard_regno_mode_ok #undef TARGET_MODES_TIEABLE_P Index: gcc/config/sh/sh.h =================================================================== --- gcc/config/sh/sh.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/sh/sh.h 2017-09-11 17:55:40.015248512 +0100 @@ -812,17 +812,6 @@ #define CALL_REALLY_USED_REGISTERS 1, 1, 0, 0, \ } -/* 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 - but can be less for certain modes in special long registers. - - On the SH all but the XD regs are UNITS_PER_WORD bits wide. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - (XD_REGISTER_P (REGNO) \ - ? ((GET_MODE_SIZE (MODE) + (2*UNITS_PER_WORD - 1)) / (2*UNITS_PER_WORD)) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - /* Specify the modes required to caller save a given hard regno. */ #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ sh_hard_regno_caller_save_mode ((REGNO), (NREGS), (MODE)) Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/sh/sh.c 2017-09-11 17:55:40.014248551 +0100 @@ -322,6 +322,7 @@ static bool sh_legitimate_combined_insn static bool sh_fixed_condition_code_regs (unsigned int* p1, unsigned int* p2); static void sh_init_sync_libfuncs (void) ATTRIBUTE_UNUSED; +static unsigned int sh_hard_regno_nregs (unsigned int, machine_mode); static bool sh_hard_regno_mode_ok (unsigned int, machine_mode); static bool sh_modes_tieable_p (machine_mode, machine_mode); @@ -644,6 +645,8 @@ #define TARGET_ATOMIC_TEST_AND_SET_TRUEV #undef TARGET_CANNOT_FORCE_CONST_MEM #define TARGET_CANNOT_FORCE_CONST_MEM sh_cannot_force_const_mem_p +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS sh_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK sh_hard_regno_mode_ok @@ -7954,7 +7957,7 @@ sh_pass_in_reg_p (const CUMULATIVE_ARGS& + int_size_in_bytes (type)) <= NPARM_REGS (SImode) * UNITS_PER_WORD) : ((sh_round_reg (cum, mode) - + HARD_REGNO_NREGS (BASE_ARG_REG (mode), mode)) + + sh_hard_regno_nregs (BASE_ARG_REG (mode), mode)) <= NPARM_REGS (mode))) : sh_round_reg (cum, mode) < NPARM_REGS (mode))); } @@ -10503,6 +10506,17 @@ sh_expand_builtin (tree exp, rtx target, return target; } +/* Implement TARGET_HARD_REGNO_NREGS. On the SH all but the XD regs are + UNITS_PER_WORD bits wide. */ + +static unsigned int +sh_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (XD_REGISTER_P (regno)) + return CEIL (GET_MODE_SIZE (mode), 2 * UNITS_PER_WORD); + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. We can allow any mode in any general register. The special registers Index: gcc/config/sparc/sparc.h =================================================================== --- gcc/config/sparc/sparc.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/sparc/sparc.h 2017-09-11 17:55:40.019248359 +0100 @@ -745,25 +745,6 @@ #define CALL_REALLY_USED_REGISTERS \ \ 1, 1, 1, 1, 1, 1, 1} -/* 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 - but can be less for certain modes in special long registers. - - On SPARC, ordinary registers hold 32 bits worth; - this means both integer and floating point registers. - On v9, integer regs hold 64 bits worth; floating point regs hold - 32 bits worth (this includes the new fp regs as even the odd ones are - included in the hard register count). */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((REGNO) == SPARC_GSR_REG ? 1 : \ - (TARGET_ARCH64 \ - ? (SPARC_INT_REG_P (REGNO) || (REGNO) == FRAME_POINTER_REGNUM \ - ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \ - : (GET_MODE_SIZE (MODE) + 3) / 4) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))) - /* Due to the ARCH64 discrepancy above we must override this next macro too. */ #define REGMODE_NATURAL_SIZE(MODE) sparc_regmode_natural_size (MODE) Index: gcc/config/sparc/sparc.c =================================================================== --- gcc/config/sparc/sparc.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/sparc/sparc.c 2017-09-11 17:55:40.018248397 +0100 @@ -676,6 +676,7 @@ static scalar_int_mode sparc_cstore_mode static void sparc_atomic_assign_expand_fenv (tree *, tree *, tree *); static bool sparc_fixed_condition_code_regs (unsigned int *, unsigned int *); static unsigned int sparc_min_arithmetic_precision (void); +static unsigned int sparc_hard_regno_nregs (unsigned int, machine_mode); static bool sparc_hard_regno_mode_ok (unsigned int, machine_mode); static bool sparc_modes_tieable_p (machine_mode, machine_mode); @@ -905,6 +906,8 @@ #define TARGET_MIN_ARITHMETIC_PRECISION #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1 +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS sparc_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK sparc_hard_regno_mode_ok @@ -13149,6 +13152,28 @@ sparc_regmode_natural_size (machine_mode return size; } +/* Implement TARGET_HARD_REGNO_NREGS. + + On SPARC, ordinary registers hold 32 bits worth; this means both + integer and floating point registers. On v9, integer regs hold 64 + bits worth; floating point regs hold 32 bits worth (this includes the + new fp regs as even the odd ones are included in the hard register + count). */ + +static unsigned int +sparc_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (regno == SPARC_GSR_REG) + return 1; + if (TARGET_ARCH64) + { + if (SPARC_INT_REG_P (regno) || regno == FRAME_POINTER_REGNUM) + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); + return CEIL (GET_MODE_SIZE (mode), 4); + } + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. ??? Because of the funny way we pass parameters we should allow certain Index: gcc/config/spu/spu.h =================================================================== --- gcc/config/spu/spu.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/spu/spu.h 2017-09-11 17:55:40.021248282 +0100 @@ -171,12 +171,6 @@ #define CALL_USED_REGISTERS { \ } -/* Values in Registers */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_BITSIZE(MODE)+MAX_FIXED_MODE_SIZE-1)/MAX_FIXED_MODE_SIZE) - - /* Register Classes */ enum reg_class { Index: gcc/config/spu/spu.c =================================================================== --- gcc/config/spu/spu.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/spu/spu.c 2017-09-11 17:55:40.020248320 +0100 @@ -281,6 +281,14 @@ spu_option_override (void) REAL_MODE_FORMAT (SFmode) = &spu_single_format; } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +spu_hard_regno_nregs (unsigned int, machine_mode mode) +{ + return CEIL (GET_MODE_BITSIZE (mode), MAX_FIXED_MODE_SIZE); +} + /* Handle an attribute requiring a FUNCTION_DECL; arguments as in struct attribute_spec.handler. */ @@ -3870,7 +3878,7 @@ spu_function_arg_advance (cumulative_arg ? ((int_size_in_bytes (type) + 15) / 16) : mode == VOIDmode ? 1 - : HARD_REGNO_NREGS (cum, mode)); + : spu_hard_regno_nregs (FIRST_ARG_REGNUM, mode)); } /* Implement TARGET_FUNCTION_ARG_PADDING. */ @@ -7382,6 +7390,9 @@ #define TARGET_CAN_USE_DOLOOP_P can_use_ #undef TARGET_MODES_TIEABLE_P #define TARGET_MODES_TIEABLE_P spu_modes_tieable_p +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS spu_hard_regno_nregs + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-spu.h" Index: gcc/config/stormy16/stormy16.h =================================================================== --- gcc/config/stormy16/stormy16.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/stormy16/stormy16.h 2017-09-11 17:55:40.021248282 +0100 @@ -140,12 +140,6 @@ #define CALL_USED_REGISTERS \ #define REG_ALLOC_ORDER { 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 10, 11, 12, 13, 14, 15, 16 } -/* How Values Fit in Registers. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - - /* Register Classes. */ enum reg_class Index: gcc/config/tilegx/tilegx.h =================================================================== --- gcc/config/tilegx/tilegx.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/tilegx/tilegx.h 2017-09-11 17:55:40.021248282 +0100 @@ -156,9 +156,6 @@ #define REG_ALLOC_ORDER { \ 66, 67 \ } -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Register that holds an address into the text segment that can be used by pic code. */ #define TILEGX_PIC_TEXT_LABEL_REGNUM (flag_pic ? 50 : INVALID_REGNUM) Index: gcc/config/tilepro/tilepro.h =================================================================== --- gcc/config/tilepro/tilepro.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/tilepro/tilepro.h 2017-09-11 17:55:40.021248282 +0100 @@ -121,9 +121,6 @@ #define REG_ALLOC_ORDER { \ 66 \ } -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Register that holds an address into the text segment that can be used by pic code. */ #define TILEPRO_PIC_TEXT_LABEL_REGNUM (flag_pic ? 50 : INVALID_REGNUM) Index: gcc/config/v850/v850.h =================================================================== --- gcc/config/v850/v850.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/v850/v850.h 2017-09-11 17:55:40.022248243 +0100 @@ -291,15 +291,6 @@ #define REG_ALLOC_ORDER \ 34, 35 \ } -/* 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 - but can be less for certain modes in special long registers. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Define the classes of registers for register constraints in the machine description. Also define ranges of constants. Index: gcc/config/vax/vax.h =================================================================== --- gcc/config/vax/vax.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/vax/vax.h 2017-09-11 17:55:40.022248243 +0100 @@ -135,14 +135,6 @@ #define FIXED_REGISTERS {0, 0, 0, 0, 0, Aside from that, you can include as many other registers as you like. */ #define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} -/* 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 - but can be less for certain modes in special long registers. - On the VAX, all registers are one word long. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ Index: gcc/config/visium/visium.h =================================================================== --- gcc/config/visium/visium.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/visium/visium.h 2017-09-11 17:55:40.024248166 +0100 @@ -556,16 +556,6 @@ #define REG_ALLOC_ORDER \ 50, 51, 52, /* flags, arg, frame */ \ 0, 34 } /* r0, f0 */ -/* `HARD_REGNO_NREGS (REGNO, MODE)' - - A C expression for the number of consecutive hard registers, - starting at register number REGNO, required to hold a value of mode - MODE. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((REGNO) == MDB_REGNUM ? \ - ((GET_MODE_SIZE (MODE) + 2 * UNITS_PER_WORD - 1) / (2 * UNITS_PER_WORD)) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - /* `HARD_REGNO_RENAME_OK (OLD_REG, NEW_REG)' A C expression which is nonzero if hard register NEW_REG can be @@ -751,18 +741,6 @@ #define PREFERRED_RELOAD_CLASS(X,CLASS) #define CANNOT_CHANGE_MODE_CLASS(FROM,TO,CLASS) \ (CLASS == MDB ? (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)) : 0) -/* `CLASS_MAX_NREGS (CLASS, MODE)' - - A C expression for the maximum number of consecutive registers of - class CLASS needed to hold a value of mode MODE. - - This is closely related to the macro `HARD_REGNO_NREGS'. In fact, - the value of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be - the maximum value of `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO - values in the class CLASS. - - This macro helps control the handling of multiple-word values in - the reload pass. */ #define CLASS_MAX_NREGS(CLASS, MODE) \ ((CLASS) == MDB ? \ ((GET_MODE_SIZE (MODE) + 2 * UNITS_PER_WORD - 1) / (2 * UNITS_PER_WORD)) \ Index: gcc/config/visium/visium.c =================================================================== --- gcc/config/visium/visium.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/visium/visium.c 2017-09-11 17:55:40.023248205 +0100 @@ -228,6 +228,8 @@ static void visium_init_libfuncs (void); static unsigned int visium_reorg (void); +static unsigned int visium_hard_regno_nregs (unsigned int, machine_mode); + static bool visium_hard_regno_mode_ok (unsigned int, machine_mode); static bool visium_modes_tieable_p (machine_mode, machine_mode); @@ -343,6 +345,9 @@ #define TARGET_MD_ASM_ADJUST visium_md_a #undef TARGET_FLAGS_REGNUM #define TARGET_FLAGS_REGNUM FLAGS_REGNUM +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS visium_hard_regno_nregs + #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK visium_hard_regno_mode_ok @@ -846,6 +851,16 @@ visium_hard_regno_rename_ok (unsigned in return 1; } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +visium_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (regno == MDB_REGNUM) + return CEIL (GET_MODE_SIZE (mode), 2 * UNITS_PER_WORD); + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. Modes with sizes which cross from the one register class to the @@ -863,7 +878,7 @@ visium_hard_regno_mode_ok (unsigned int return mode == SFmode || (mode == SImode && TARGET_FPU_IEEE); return (GET_MODE_CLASS (mode) == MODE_INT - && HARD_REGNO_NREGS (regno, mode) == 1); + && visium_hard_regno_nregs (regno, mode) == 1); } /* Implement TARGET_MODES_TIEABLE_P. */ Index: gcc/config/xtensa/xtensa.h =================================================================== --- gcc/config/xtensa/xtensa.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/xtensa/xtensa.h 2017-09-11 17:55:40.025248128 +0100 @@ -321,13 +321,6 @@ #define BR_REG_P(REGNO) ((unsigned) ((RE #define FP_REG_P(REGNO) ((unsigned) ((REGNO) - FP_REG_FIRST) < FP_REG_NUM) #define ACC_REG_P(REGNO) ((unsigned) ((REGNO) - ACC_REG_FIRST) < ACC_REG_NUM) -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - (FP_REG_P (REGNO) ? \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG) : \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - /* Register to use for pushing function arguments. */ #define STACK_POINTER_REGNUM (GP_REG_FIRST + 1) Index: gcc/config/xtensa/xtensa.c =================================================================== --- gcc/config/xtensa/xtensa.c 2017-09-11 17:55:38.950289484 +0100 +++ gcc/config/xtensa/xtensa.c 2017-09-11 17:55:40.025248128 +0100 @@ -178,6 +178,7 @@ static bool xtensa_member_type_forces_bl machine_mode mode); static void xtensa_conditional_register_usage (void); +static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode); static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode); static bool xtensa_modes_tieable_p (machine_mode, machine_mode); @@ -308,6 +309,8 @@ #define TARGET_INVALID_WITHIN_DOLOOP xte #undef TARGET_CONDITIONAL_REGISTER_USAGE #define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS xtensa_hard_regno_nregs #undef TARGET_HARD_REGNO_MODE_OK #define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok @@ -2261,6 +2264,16 @@ xtensa_option_override (void) } } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +xtensa_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (FP_REG_P (regno)) + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_FPREG); + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + /* Implement TARGET_HARD_REGNO_MODE_OK. */ static bool Index: gcc/system.h =================================================================== --- gcc/system.h 2017-09-11 17:55:38.950289484 +0100 +++ gcc/system.h 2017-09-11 17:55:40.034247781 +0100 @@ -912,7 +912,8 @@ #define realloc xrealloc CLEAR_BY_PIECES_P MOVE_BY_PIECES_P SET_BY_PIECES_P \ STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD \ HARD_REGNO_CALL_PART_CLOBBERED HARD_REGNO_MODE_OK \ - MODES_TIEABLE_P FUNCTION_ARG_PADDING SLOW_UNALIGNED_ACCESS + MODES_TIEABLE_P FUNCTION_ARG_PADDING SLOW_UNALIGNED_ACCESS \ + HARD_REGNO_NREGS /* Target macros only used for code built for the target, that have moved to libgcc-tm.h or have never been present elsewhere. */