From patchwork Mon Jun 25 14:59:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Gretton-Dann X-Patchwork-Id: 167133 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 95F2BB6FAC for ; Tue, 26 Jun 2012 00:59:27 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1341241167; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=HOT4m0D y6jpt/wHYkLesffwtUPQ=; b=WBz1LmkaXyCAbZ7+iXnKdnj7ywNeCoAHJfXQjjd XzO5HjnyUnVjhQ1lCgJiMTHxr5RhW9ZS7XYLeEODWpmdFKlrKXPno6MOu97UIjzq rGK0hgNSrdZyh8pT0yFCqEFhn8V9aXhPeesbYHXMujwR474QiKanshFUt1ifcUoK JPJ4= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:X-MC-Unique:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=JA2de3on8pLT6V/H3LoRlNWB1Mq3ZMCDVAi1nxx6AYYgc5rFP68xvw2qOFuobG stC4xln5kwm7oeNTZSfRNU7ZcM4grd8G2EJacC2ekVFSTcqybmIHXr1ARp1LxyD7 k2zuKdQikt9JQ9WhabaHTlUDEpMMiCpIkK9Ec1vuZ9ZmY=; Received: (qmail 2146 invoked by alias); 25 Jun 2012 14:59:20 -0000 Received: (qmail 2055 invoked by uid 22791); 25 Jun 2012 14:59:17 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_NO X-Spam-Check-By: sourceware.org Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 25 Jun 2012 14:59:03 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Mon, 25 Jun 2012 15:59:01 +0100 Received: from [10.1.69.27] ([10.1.255.212]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 25 Jun 2012 15:59:47 +0100 Message-ID: <4FE87CB4.7060103@arm.com> Date: Mon, 25 Jun 2012 15:59:00 +0100 From: Matthew Gretton-Dann User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20120615 Thunderbird/13.0.1 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Richard Earnshaw Subject: [RFA/ARM 1/3] Add VFP support for VFMA and friends X-MC-Unique: 112062515590111801 X-IsSubscribed: yes 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 All, This patch adds support to the ARM backend for generating floating-point fused multiply-accumulate. OK? gcc/ChangeLog: 2012-06-25 Matthew Gretton-Dann * config/arm/iterators.md (SDF): New mode iterator. (V_if_elem): Add support for SF and DF modes. (V_reg): Likewise. (F_w_constraint): New mode iterator attribute. (F_r_constraint): Likewise. (F_fma_type): Likewise. (F_target): Likewise. config/arm/vfp.md (fma4): New pattern. (*fmsub4): Likewise. (*fmnsub4): Likewise. (*fmnadd4): Likewise. Thanks, Matt diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 795a5ee..3063f00 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -42,6 +42,9 @@ ;; A list of the 32bit and 64bit integer modes (define_mode_iterator SIDI [SI DI]) +;; A list of modes which the VFP unit can handle +(define_mode_iterator SDF [SF DF]) + ;; Integer element sizes implemented by IWMMXT. (define_mode_iterator VMMX [V2SI V4HI V8QI]) @@ -245,7 +248,8 @@ (V4HI "P") (V8HI "q") (V2SI "P") (V4SI "q") (V2SF "P") (V4SF "q") - (DI "P") (V2DI "q")]) + (DI "P") (V2DI "q") + (SF "") (DF "P")]) ;; Wider modes with the same number of elements. (define_mode_attr V_widen [(V8QI "V8HI") (V4HI "V4SI") (V2SI "V2DI")]) @@ -303,7 +307,8 @@ (V4HI "i16") (V8HI "i16") (V2SI "i32") (V4SI "i32") (DI "i64") (V2DI "i64") - (V2SF "f32") (V4SF "f32")]) + (V2SF "f32") (V4SF "f32") + (SF "f32") (DF "f64")]) ;; Same, but for operations which work on signed values. (define_mode_attr V_s_elem [(V8QI "s8") (V16QI "s8") @@ -423,6 +428,12 @@ ;; Mode attribute for vshll. (define_mode_attr V_innermode [(V8QI "QI") (V4HI "HI") (V2SI "SI")]) +;; Mode attributes used for fused-multiply-accumulate VFP support +(define_mode_attr F_w_constraint [(SF "=t") (DF "=w")]) +(define_mode_attr F_r_constraint [(SF "t") (DF "w")]) +(define_mode_attr F_fma_type [(SF "fmacs") (DF "fmacd")]) +(define_mode_attr F_target [(SF "") (DF "&& TARGET_VFP_DOUBLE")]) + ;;---------------------------------------------------------------------------- ;; Code attributes ;;---------------------------------------------------------------------------- diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index 2061414..2a50353 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -890,6 +890,54 @@ (set_attr "type" "fmacd")] ) +;; Fused-multiply-accumulate + +(define_insn "fma4" + [(set (match_operand:SDF 0 "register_operand" "") + (fma:SDF (match_operand:SDF 1 "register_operand" "") + (match_operand:SDF 2 "register_operand" "") + (match_operand:SDF 3 "register_operand" "0")))] + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA " + "vfma%?.\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "type" "")] +) + +(define_insn "*fmsub4" + [(set (match_operand:SDF 0 "register_operand" "") + (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand" + "")) + (match_operand:SDF 2 "register_operand" "") + (match_operand:SDF 3 "register_operand" "0")))] + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA " + "vfms%?.\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "type" "")] +) + +(define_insn "*fnmsub4" + [(set (match_operand:SDF 0 "register_operand" "") + (fma:SDF (match_operand:SDF 1 "register_operand" "") + (match_operand:SDF 2 "register_operand" "") + (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))] + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA " + "vfnms%?.\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "type" "")] +) + +(define_insn "*fnmadd4" + [(set (match_operand:SDF 0 "register_operand" "") + (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand" + "")) + (match_operand:SDF 2 "register_operand" "") + (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))] + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA " + "vfnma%?.\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "type" "")] +) + ;; Conversion routines diff --git a/gcc/testsuite/gcc.target/arm/fma-sp.c b/gcc/testsuite/gcc.target/arm/fma-sp.c new file mode 100644 index 0000000..457b55c --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/fma-sp.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mthumb" } */ + +#include "fma.h" + +/* { dg-final { scan-assembler-not "vfma\.f64\td\[0-9\]" } } */ +/* { dg-final { scan-assembler-times "vfma\.f32\ts\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-not "vfms\.f64\td\[0-9\]" } } */ +/* { dg-final { scan-assembler-times "vfms\.f32\ts\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-not "vfnma\.f64\td\[0-9\]" } } */ +/* { dg-final { scan-assembler-times "vfnma\.f32\ts\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-not "vfnms\.f64\td\[0-9\]" } } */ +/* { dg-final { scan-assembler-times "vfnms\.f32\ts\[0-9\]" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/fma.c b/gcc/testsuite/gcc.target/arm/fma.c new file mode 100644 index 0000000..1809aa8 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/fma.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcpu=cortex-a15 -mfpu=vfpv4" } */ + +#include "fma.h" + +/* { dg-final { scan-assembler-times "vfma\.f64\td\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "vfma\.f32\ts\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "vfms\.f64\td\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "vfms\.f32\ts\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "vfnma\.f64\td\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "vfnma\.f32\ts\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "vfnms\.f64\td\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "vfnms\.f32\ts\[0-9\]" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/fma.h b/gcc/testsuite/gcc.target/arm/fma.h new file mode 100644 index 0000000..0812c2d --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/fma.h @@ -0,0 +1,50 @@ +extern double fma (double, double, double); +extern float fmaf (float, float, float); + +float +vfma32 (float x, float y, float z) +{ + return fmaf (x, y, z); +} + +float +vfms32 (float x, float y, float z) +{ + return fmaf (-x, y, z); +} + +float +vfnms32 (float x, float y, float z) +{ + return fmaf (x, y, -z); +} + +float +vfnma32 (float x, float y, float z) +{ + return fmaf (-x, y, -z); +} + +double +vfma64 (double x, double y, double z) +{ + return fma (x, y, z); +} + +double +vfms64 (double x, double y, double z) +{ + return fma (-x, y, z); +} + +double +vfnms64 (double x, double y, double z) +{ + return fma (x, y, -z); +} + +double +vfnma64 (double x, double y, double z) +{ + return fma (-x, y, -z); +}