1 /*
  2  * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 package org.openjdk.bench.jdk.incubator.vector.operation;
 25 
 26 #warn This file is preprocessed before being compiled
 27 
 28 import java.util.concurrent.TimeUnit;
 29 import java.util.function.IntFunction;
 30 
 31 import org.openjdk.jmh.annotations.*;
 32 import org.openjdk.jmh.infra.Blackhole;
 33 
 34 @BenchmarkMode(Mode.Throughput)
 35 @OutputTimeUnit(TimeUnit.MILLISECONDS)
 36 @State(Scope.Benchmark)
 37 @Warmup(iterations = 3, time = 1)
 38 @Measurement(iterations = 5, time = 1)
 39 @Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"})
 40 public class $Type$Scalar extends AbstractVectorBenchmark {
 41     static final int INVOC_COUNT = 1; // To align with vector benchmarks.
 42 
 43 #if[BITWISE]
 44     private static final $type$ CONST_SHIFT = $Boxtype$.SIZE / 2;
 45 #end[BITWISE]
 46 
 47     @Param("1024")
 48     int size;
 49 
 50     $type$[] fill(IntFunction<$Wideboxtype$> f) {
 51         $type$[] array = new $type$[size];
 52         for (int i = 0; i < array.length; i++) {
 53             array[i] = f.apply(i);
 54         }
 55         return array;
 56     }
 57 
 58     static $bitstype$ bits($type$ e) {
 59         return {#if[FP]?$Type$.$type$To$Bitstype$Bits(e):e};
 60     }
 61 
 62     $type$[] as, bs, cs, rs;
 63     boolean[] ms, mt, rms;
 64     int[] ss;
 65 
 66     @Setup
 67     public void init() {
 68         as = fill(i -> ($type$)(2*i));
 69         bs = fill(i -> ($type$)(i+1));
 70         cs = fill(i -> ($type$)(i+5));
 71         rs = fill(i -> ($type$)0);
 72         ms = fillMask(size, i -> (i % 2) == 0);
 73         mt = fillMask(size, i -> true);
 74         rms = fillMask(size, i -> false);
 75 
 76         ss = fillInt(size, i -> RANDOM.nextInt(Math.max(i,1)));
 77     }
 78 
 79     final IntFunction<$type$[]> fa = vl -> as;
 80     final IntFunction<$type$[]> fb = vl -> bs;
 81     final IntFunction<$type$[]> fc = vl -> cs;
 82     final IntFunction<$type$[]> fr = vl -> rs;
 83     final IntFunction<boolean[]> fm = vl -> ms;
 84     final IntFunction<boolean[]> fmt = vl -> mt;
 85     final IntFunction<boolean[]> fmr = vl -> rms;
 86     final IntFunction<int[]> fs = vl -> ss;
 87 
 88     static boolean eq($type$ a, $type$ b) {
 89         return a == b;
 90     }
 91 
 92     static boolean neq($type$ a, $type$ b) {
 93         return a != b;
 94     }
 95 
 96     static boolean lt($type$ a, $type$ b) {
 97         return a < b;
 98     }
 99 
100     static boolean le($type$ a, $type$ b) {
101         return a <= b;
102     }
103 
104     static boolean gt($type$ a, $type$ b) {
105         return a > b;
106     }
107 
108     static boolean ge($type$ a, $type$ b) {
109         return a >= b;
110     }
111 
112 #if[!FP]
113     static boolean ult($type$ a, $type$ b) {
114         return $Boxtype$.compareUnsigned(a, b) < 0;
115     }
116 
117     static boolean ule($type$ a, $type$ b) {
118         return $Boxtype$.compareUnsigned(a, b) <= 0;
119     }
120 
121     static boolean ugt($type$ a, $type$ b) {
122         return $Boxtype$.compareUnsigned(a, b) > 0;
123     }
124 
125     static boolean uge($type$ a, $type$ b) {
126         return $Boxtype$.compareUnsigned(a, b) >= 0;
127     }
128 #end[!FP]
129 
130 #if[BITWISE]
131     static $type$ ROL_scalar($type$ a, $type$ b) {
132 #if[intOrLong]
133         return $Wideboxtype$.rotateLeft(a, ((int)b));
134 #else[intOrLong]
135 #if[short]
136         return (short)(((((short)a) & 0xFFFF) << (b & 15)) | ((((short)a) & 0xFFFF) >>> (16 - (b & 15))));
137 #else[short]
138         return (byte)(((((byte)a) & 0xFF) << (b & 7)) | ((((byte)a) & 0xFF) >>> (8 - (b & 7))));
139 #end[short]
140 #end[intOrLong]
141     }
142 
143     static $type$ ROR_scalar($type$ a, $type$ b) {
144 #if[intOrLong]
145         return $Wideboxtype$.rotateRight(a, ((int)b));
146 #else[intOrLong]
147 #if[short]
148         return (short)(((((short)a) & 0xFFFF) >>> (b & 15)) | ((((short)a) & 0xFFFF) << (16 - (b & 15))));
149 #else[short]
150         return (byte)(((((byte)a) & 0xFF) >>> (b & 7)) | ((((byte)a) & 0xFF) << (8 - (b & 7))));
151 #end[short]
152 #end[intOrLong]
153     }
154 
155     static $type$ TRAILING_ZEROS_COUNT_scalar($type$ a) {
156 #if[intOrLong]
157         return $Wideboxtype$.numberOfTrailingZeros(a);
158 #else[intOrLong]
159 #if[short]
160         return (short) (a != 0 ? Integer.numberOfTrailingZeros(a) : 16);
161 #else[short]
162         return (byte) (a != 0 ? Integer.numberOfTrailingZeros(a) : 8);
163 #end[short]
164 #end[intOrLong]
165     }
166 
167     static $type$ LEADING_ZEROS_COUNT_scalar($type$ a) {
168 #if[intOrLong]
169         return $Wideboxtype$.numberOfLeadingZeros(a);
170 #else[intOrLong]
171 #if[short]
172         return (short) (a >= 0 ? Integer.numberOfLeadingZeros(a) - 16 : 0);
173 #else[short]
174         return (byte) (a >= 0 ? Integer.numberOfLeadingZeros(a) - 24 : 0);
175 #end[short]
176 #end[intOrLong]
177     }
178 
179     static $type$ REVERSE_scalar($type$ a) {
180 #if[intOrLong]
181         return $Wideboxtype$.reverse(a);
182 #else[intOrLong]
183 #if[short]
184         $type$ b = ROL_scalar(a, ($type$) 8);
185         b = (short)(((b & 0x5555) << 1) | ((b & 0xAAAA) >>> 1));
186         b = (short)(((b & 0x3333) << 2) | ((b & 0xCCCC) >>> 2));
187         b = (short)(((b & 0x0F0F) << 4) | ((b & 0xF0F0) >>> 4));
188         return b;
189 #else[short]
190         $type$ b = ROL_scalar(a, ($type$) 4);
191         b = (byte)(((b & 0x55) << 1) | ((b & 0xAA) >>> 1));
192         b = (byte)(((b & 0x33) << 2) | ((b & 0xCC) >>> 2));
193         return b;
194 #end[short]
195 #end[intOrLong]
196     }
197 #end[BITWISE]