1 /*
   2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2020, Arm Limited. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * @test
  27  * @summary AArch64 SIMD codegen test for vector float
  28  * @library /test/lib /
  29  *
  30  * @build sun.hotspot.WhiteBox
  31  *        compiler.vectorization.aarch64.CodegenTestRunner
  32  *
  33  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  34  * @run main/othervm -Xbootclasspath/a:.
  35  *                   -XX:+WhiteBoxAPI
  36  *                   compiler.vectorization.aarch64.VectorFloatTest
  37  *
  38  * @requires os.arch == "aarch64" & vm.debug == true &
  39  *           vm.compiler2.enabled & !vm.graal.enabled
  40  */
  41 
  42 package compiler.vectorization.aarch64;
  43 
  44 public class VectorFloatTest extends CodegenTestRunner {
  45 
  46     private static final int SIZE = 5432;
  47 
  48     private float[] a = new float[SIZE];
  49     private float[] b = new float[SIZE];
  50     private float[] c = new float[SIZE];
  51 
  52     // ---------------- Arithmetic ----------------
  53     @CheckOpto(neon = "fneg", sve = "sve_fneg")
  54     public void vectorNeg() {
  55         for (int i = 0; i < SIZE; i++) {
  56             c[i] = -a[i];
  57         }
  58     }
  59 
  60     @CallMath
  61     @CheckOpto(neon = "fabs", sve = "sve_fabs")
  62     public void vectorAbs() {
  63         for (int i = 0; i < SIZE; i++) {
  64             c[i] = Math.abs(a[i]);
  65         }
  66     }
  67 
  68     @CallMath
  69     @CheckOpto(neon = "fsqrt", sve = "sve_fsqrt")
  70     public void vectorSqrt() {
  71         for (int i = 0; i < SIZE; i++) {
  72             c[i] = (float) Math.sqrt(a[i]);
  73         }
  74     }
  75 
  76     @CheckOpto(neon = "fadd", sve = "sve_fadd")
  77     public void vectorAdd() {
  78         for (int i = 0; i < SIZE; i++) {
  79             c[i] = a[i] + b[i];
  80         }
  81     }
  82 
  83     @CheckOpto(neon = "fsub", sve = "sve_fsub")
  84     public void vectorSub() {
  85         for (int i = 0; i < SIZE; i++) {
  86             c[i] = a[i] - b[i];
  87         }
  88     }
  89 
  90     @CheckOpto(neon = "fmul", sve = "sve_fmul")
  91     public void vectorMul() {
  92         for (int i = 0; i < SIZE; i++) {
  93             c[i] = a[i] * b[i];
  94         }
  95     }
  96 
  97     @CheckOpto(neon = "fdiv", sve = "sve_fdiv")
  98     public void vectorDiv() {
  99         for (int i = 0; i < SIZE; i++) {
 100             c[i] = a[i] / b[i];
 101         }
 102     }
 103 
 104     @CallMath
 105     @CheckOpto(neon = "fmax", sve = "sve_fmax")
 106     public void vectorMax() {
 107         for (int i = 0; i < SIZE; i++) {
 108             c[i] = Math.max(a[i], b[i]);
 109         }
 110     }
 111 
 112     @CallMath
 113     @CheckOpto(neon = "fmin", sve = "sve_fmin")
 114     public void vectorMin() {
 115         for (int i = 0; i < SIZE; i++) {
 116             c[i] = Math.min(a[i], b[i]);
 117         }
 118     }
 119 
 120     @CallMath
 121     @CheckOpto(neon = "fmla", sve = "sve_fmla")
 122     public void vectorMulAdd() {
 123         for (int i = 0; i < SIZE; i++) {
 124             c[i] = Math.fma(a[i], b[i], c[i]);
 125         }
 126     }
 127 
 128     @CallMath
 129     @CheckOpto(neon = "fmls", sve = "sve_fmls")
 130     public void vectorMulSub1() {
 131         for (int i = 0; i < SIZE; i++) {
 132             c[i] = Math.fma(-a[i], b[i], c[i]);
 133         }
 134     }
 135 
 136     @CallMath
 137     @CheckOpto(neon = "fmls", sve = "sve_fmls")
 138     public void vectorMulSub2() {
 139         for (int i = 0; i < SIZE; i++) {
 140             c[i] = Math.fma(a[i], -b[i], c[i]);
 141         }
 142     }
 143 
 144     // Vector fnmla isn't implemented in NEON backend.
 145     @CallMath
 146     @CheckOpto(sve = "sve_fnmla")
 147     public void vectorNegateMulAdd1() {
 148         for (int i = 0; i < SIZE; i++) {
 149             c[i] = Math.fma(-a[i], b[i], -c[i]);
 150         }
 151     }
 152 
 153     // Vector fnmla isn't implemented in NEON backend.
 154     @CallMath
 155     @CheckOpto(sve = "sve_fnmla")
 156     public void vectorNegateMulAdd2() {
 157         for (int i = 0; i < SIZE; i++) {
 158             c[i] = Math.fma(a[i], -b[i], -c[i]);
 159         }
 160     }
 161 
 162     // Vector fnmls isn't implemented in NEON backend.
 163     @CallMath
 164     @CheckOpto(sve = "sve_fnmls")
 165     public void vectorNegateMulSub() {
 166         for (int i = 0; i < SIZE; i++) {
 167             c[i] = Math.fma(a[i], b[i], -c[i]);
 168         }
 169     }
 170 
 171     // ---------------- Reduction ----------------
 172     @CheckOpto(sve = "sve_fsub|sve_fadda")
 173     public float reductionAdd() {
 174         float sum = 0.0f;
 175         for (int i = 0; i < SIZE; i++) {
 176             sum += (a[i] - b[i]);
 177         }
 178         return sum;
 179     }
 180 
 181     @CallMath
 182     @CheckOpto(sve = "sve_fsub|sve_fminv")
 183     public float reductionMin() {
 184         float min = Float.POSITIVE_INFINITY;
 185         for (int i = 0; i < SIZE; i++) {
 186             min = Math.min(min, a[i] - b[i]);
 187         }
 188         return min;
 189     }
 190 
 191     @CallMath
 192     @CheckOpto(sve = "sve_fsub|sve_fmaxv")
 193     public float reductionMax() {
 194         float max = Float.NEGATIVE_INFINITY;
 195         for (int i = 0; i < SIZE; i++) {
 196             max = Math.max(max, a[i] - b[i]);
 197         }
 198         return max;
 199     }
 200 
 201     public static void main(String[] args) {
 202         // Delegate work to the test runner
 203         new VectorFloatTest().run(args);
 204     }
 205 }
 206