1 #!/bin/bash
  2 #
  3 # Copyright (c) 2018, 2025, Oracle and/or its affiliates. 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 generate_perf_tests=$1
 26 
 27 TEMPLATE_FOLDER="templates/"
 28 
 29 unit_output="unit_tests.template"
 30 perf_output="perf_tests.template"
 31 perf_scalar_output="perf_scalar_tests.template"
 32 
 33 unary="Unary-op"
 34 unary_masked="Unary-Masked-op"
 35 unary_scalar="Unary-Scalar-op"
 36 ternary="Ternary-op"
 37 ternary_masked="Ternary-Masked-op"
 38 ternary_broadcast="Ternary-Broadcast-op"
 39 ternary_broadcast_masked="Ternary-Broadcast-Masked-op"
 40 ternary_double_broadcast="Ternary-Double-Broadcast-op"
 41 ternary_double_broadcast_masked="Ternary-Double-Broadcast-Masked-op"
 42 ternary_scalar="Ternary-Scalar-op"
 43 binary="Binary-op"
 44 binary_masked="Binary-Masked-op"
 45 binary_memop="Binary-mem-op"
 46 binary_masked_memop="Binary-Masked-mem-op"
 47 saturating_binary="SaturatingBinary-op"
 48 saturating_binary_masked="SaturatingBinary-Masked-op"
 49 saturating_binary_assocative="SaturatingBinary-op-associative"
 50 saturating_binary_assocative_masked="SaturatingBinary-Masked-op-associative"
 51 binary_broadcast="Binary-Broadcast-op"
 52 binary_broadcast_masked="Binary-Broadcast-Masked-op"
 53 binary_broadcast_long="Binary-Broadcast-Long-op"
 54 binary_broadcast_masked_long="Binary-Broadcast-Masked-Long-op"
 55 binary_scalar="Binary-Scalar-op"
 56 blend="Blend-op"
 57 test_template="Test"
 58 compare_template="Compare"
 59 compare_masked_template="Compare-Masked"
 60 compare_broadcast_template="Compare-Broadcast"
 61 reduction_scalar="Reduction-Scalar-op"
 62 reduction_scalar_func="Reduction-Scalar-op-func"
 63 reduction_scalar_masked="Reduction-Scalar-Masked-op"
 64 reduction_scalar_masked_func="Reduction-Scalar-Masked-op-func"
 65 reduction_op="Reduction-op"
 66 reduction_op_func="Reduction-op-func"
 67 reduction_op_masked="Reduction-Masked-op"
 68 reduction_op_masked_func="Reduction-Masked-op-func"
 69 reduction_saturating_op="SaturatingReduction-op"
 70 reduction_saturating_op_masked="SaturatingReduction-Masked-op"
 71 unary_math_template="Unary-op-math"
 72 binary_math_template="Binary-op-math"
 73 binary_math_broadcast_template="Binary-Broadcast-op-math"
 74 bool_reduction_scalar="BoolReduction-Scalar-op"
 75 bool_reduction_template="BoolReduction-op"
 76 with_op_template="With-Op"
 77 shift_template="Shift-op"
 78 shift_masked_template="Shift-Masked-op"
 79 shift_const_template="Shift-Const-op"
 80 shift_masked_const_template="Shift-Masked-Const-op"
 81 get_template="Get-op"
 82 rearrange_template="Rearrange"
 83 compressexpand_template="CompressExpand"
 84 broadcast_template="Broadcast"
 85 zero_template="Zero"
 86 slice_template="Slice-op"
 87 slice1_template="Slice-bop"
 88 slice1_masked_template="Slice-Masked-bop"
 89 unslice_template="Unslice-op"
 90 unslice1_template="Unslice-bop"
 91 unslice1_masked_template="Unslice-Masked-bop"
 92 miscellaneous_template="Miscellaneous"
 93 
 94 function replace_variables {
 95   local filename=$1
 96   local output=$2
 97   local kernel=$3
 98   local test=$4
 99   local op=$5
100   local init=$6
101   local guard=$7
102   local masked=$8
103   local op_name=$9
104   local kernel_smoke=${10}
105   local attrib=${11}
106 
107   if [ "x${kernel}" != "x" ]; then
108     local kernel_escaped=$(echo -e "$kernel" | tr '\n' '`')
109     sed "s/\[\[KERNEL\]\]/${kernel_escaped}/g" $filename > ${filename}.current1
110     cat ${filename}.current1 | tr '`' "\n" > ${filename}.current
111     rm -f "${filename}.current1"
112   else
113     cp $filename ${filename}.current
114   fi
115 
116   # Check if we need to do multiple replacements
117   # If you want to emit for an operation using lanewise(VectorOperator.**, ..) and also using dedicated instruction (e.g. add(..)), then
118   # pass the 'test' argument as "OPERATOR_NAME+func_Name" (e.g. "ADD+add")
119   # if there is a masked version available for the operation add "withMask" to 'test' argument (e.g. "ADD+add+withMask")
120   local test_func=""
121   local withMask=""
122   local suffix=""
123   local tests=($(awk -F+ '{$1=$1} 1' <<< $test))
124   if [ "${tests[2]}" == "withMask" ]; then
125     test=${tests[0]}
126     test_func=${tests[1]}
127     withMask=${tests[2]}
128   elif [ "${tests[1]}" == "withMask" ]; then
129     test=""
130     test_func=${tests[0]}
131     withMask=${tests[1]}
132   elif [ "${tests[1]}" != "" ]; then
133     test=${tests[0]}
134     test_func=${tests[1]}
135   fi
136 
137   if [ "${attrib}" == "associative" ]; then
138      suffix=${suffix}"_ASSOC"
139   fi
140   if [ "${attrib}" == "reduction" ]; then
141      suffix=${suffix}"_REDUCTION"
142   fi
143   if [ "${attrib}" == "memoryoper" ]; then
144      suffix=${suffix}"_MEM"
145   fi
146 
147   sed_prog="
148     s/\<OPTIONAL\>\(.*\)\<\\OPTIONAL\>/\1/g
149     s/\[\[TEST_TYPE\]\]/${masked}/g
150     s/\[\[TEST_OP\]\]/${op}/g
151     s/\[\[TEST_INIT\]\]/${init}/g
152     s/\[\[OP_NAME\]\]/${op_name}/g
153     s/\[\[SUFFIX\]\]/${suffix}/g
154   "
155   sed_prog_2="$sed_prog
156     s/\[\[TEST\]\]/${test_func}/g
157     s/[.][^(]*(VectorOperators.$test_func, /.$test_func(/g
158     s/[.][^(]*(VectorOperators.$test_func,/.$test_func(/g
159     s/[.][^(]*(VectorOperators.$test_func/.$test_func(/g
160   "
161   sed_prog="
162     $sed_prog
163     s/\[\[TEST\]\]/${test}/g
164   "
165 
166   # Guard the test if necessary
167   if [ "$guard" != "" ]; then
168     echo -e "#if[${guard}]" >> $output
169   fi
170   if [ "$test" != "" ]; then
171     sed -e "$sed_prog" < ${filename}.current >> $output
172   fi
173   # If we also have a dedicated function for the operation then use 2nd sed expression
174   if [[ "$filename" == *"Unit"* ]] && [ "$test_func" != "" ]; then
175     if [ "$masked" == "" ] || [ "$withMask" != "" ]; then
176       if [ ! -z "$kernel_smoke" ]; then
177         local kernel_smoke_escaped=$(echo -e "$kernel_smoke" | tr '\n' '`')
178         sed "s/\[\[KERNEL\]\]/${kernel_smoke_escaped}/g" $filename > ${filename}.scurrent1
179         cat ${filename}.scurrent1 | tr '`' "\n" > ${filename}.scurrent
180         rm -f "${filename}.scurrent1"
181       else
182         cp $filename.current ${filename}.scurrent
183       fi
184       sed -e "$sed_prog_2" < ${filename}.scurrent >> $output
185       rm -f ${filename}.scurrent
186     fi
187   fi
188   if [ "$guard" != "" ]; then
189     echo -e "#end[${guard}]" >> $output
190   fi
191 
192   rm -f ${filename}.current
193 }
194 
195 function gen_op_tmpl {
196   local template=$1
197   local test=$2
198   local op=$3
199   local guard=""
200   local init=""
201   local attrib=""
202   if [ $# -gt 3 ]; then
203     guard=$4
204   fi
205   if [ $# -gt 4 ]; then
206     init=$5
207   fi
208 
209   if [ $# -gt 5 ]; then
210     attrib=$6
211   fi
212 
213   local masked=""
214   if [[ $template == *"Masked"* ]]; then
215     masked="Masked"
216   fi
217 
218   local op_name=""
219   if [[ $template == *"Shift"* ]]; then
220     op_name="Shift"
221   elif [[ $template == *"Get"* ]]; then
222     op_name="extract"
223   fi
224 
225   local kernel_filename="${TEMPLATE_FOLDER}/Kernel-${template}.template"
226   local kernel_smoke_filename="${TEMPLATE_FOLDER}/Kernel-${template}-smoke.template"
227   local unit_filename="${TEMPLATE_FOLDER}/Unit-${template}.template"
228   if [ ! -f $unit_filename ]; then
229     # Leverage general unit code snippet if no specialization exists
230     unit_filename="${TEMPLATE_FOLDER}/Unit-${template%_*}.template"
231     echo $unit_filename
232   fi
233 
234   local kernel=""
235   if [ -f $kernel_filename ]; then
236     kernel="$(cat $kernel_filename)"
237   fi
238 
239   local kernel_smoke=""
240   if [ -f $kernel_smoke_filename ]; then
241     kernel_smoke="$(cat $kernel_smoke_filename)"
242   else
243     kernel_smoke="$kernel"
244   fi
245 
246   # Replace template variables in unit test files (if any)
247   replace_variables $unit_filename $unit_output "$kernel" "$test" "$op" "$init" "$guard" "$masked" "$op_name" "$kernel_smoke" "$attrib"
248 
249   local gen_perf_tests=$generate_perf_tests
250   if [[ $template == *"-Broadcast-"* ]] || [[ $template == "Miscellaneous" ]] ||
251      [[ $template == *"Compare-Masked"* ]] || [[ $template == *"Compare-Broadcast"* ]]; then
252     gen_perf_tests=false
253   fi
254   if [ $gen_perf_tests == true ]; then
255     # Replace template variables in performance test files (if any)
256     local perf_wrapper_filename="${TEMPLATE_FOLDER}/Perf-wrapper.template"
257     local perf_vector_filename="${TEMPLATE_FOLDER}/Perf-${template}.template"
258     local perf_scalar_filename="${TEMPLATE_FOLDER}/Perf-Scalar-${template}.template"
259 
260     if [ -f $perf_vector_filename ]; then
261       replace_variables $perf_vector_filename  $perf_output "$kernel" "$test" "$op" "$init" "$guard" "$masked" "$op_name" "" "$attrib"
262     elif [ -f $kernel_filename ]; then
263       replace_variables $perf_wrapper_filename $perf_output "$kernel" "$test" "$op" "$init" "$guard" "$masked" "$op_name" "" "$attrib"
264     elif [[ $template != *"-Scalar-"* ]] && [[ $template != "Get-op" ]] && [[ $template != "With-Op" ]]; then
265       echo "Warning: missing perf: $@"
266     fi
267 
268     if [ -f $perf_scalar_filename ]; then
269       replace_variables $perf_scalar_filename $perf_scalar_output "$kernel" "$test" "$op" "$init" "$guard" "$masked" "$op_name" "" "$attrib"
270     elif [[ $template != *"-Scalar-"* ]] && [[ $template != "Get-op" ]] && [[ $template != "With-Op" ]]; then
271       echo "Warning: Missing PERF SCALAR: $perf_scalar_filename"
272     fi
273   fi
274 }
275 
276 function gen_binary_alu_op {
277   echo "Generating binary op $1 ($2)..."
278   gen_op_tmpl $binary "$@"
279   gen_op_tmpl $binary_masked "$@"
280 }
281 
282 function gen_binary_alu_mem_op {
283   echo "Generating binary op $1 ($2)..."
284   gen_op_tmpl $binary_memop "$@" "" "" "memoryoper"
285   gen_op_tmpl $binary_masked_memop "$@" "" "" "memoryoper"
286 }
287 
288 function gen_binary_alu_bcst_op {
289   echo "Generating binary broadcast op $1 ($2)..."
290   gen_op_tmpl $binary_broadcast "$@"
291   gen_op_tmpl $binary_broadcast_masked "$@"
292 }
293 
294 function gen_binary_alu_bcst_long_op {
295   echo "Generating binary broadcast long op $1 ($2)..."
296   gen_op_tmpl $binary_broadcast_long "$@"
297   gen_op_tmpl $binary_broadcast_masked_long "$@"
298 }
299 
300 function gen_shift_op {
301   echo "Generating Shift constant op $1 ($2)..."
302   gen_op_tmpl $shift_template "$@"
303   gen_op_tmpl $shift_masked_template "$@"
304 }
305 
306 function gen_shift_cst_op {
307   echo "Generating Shift constant op $1 ($2)..."
308   gen_op_tmpl $shift_const_template "$@"
309   gen_op_tmpl $shift_masked_const_template "$@"
310 }
311 
312 function gen_unary_alu_op {
313   echo "Generating unary op $1 ($2)..."
314   gen_op_tmpl $unary_scalar "$@"
315   gen_op_tmpl $unary "$@"
316   gen_op_tmpl $unary_masked "$@"
317 }
318 
319 function gen_ternary_alu_op {
320   echo "Generating ternary op $1 ($2)..."
321   gen_op_tmpl $ternary_scalar "$@"
322   gen_op_tmpl $ternary "$@"
323   gen_op_tmpl $ternary_masked "$@"
324 }
325 
326 function gen_ternary_alu_bcst_op {
327   echo "Generating ternary broadcast op $1 ($2)..."
328   gen_op_tmpl $ternary_broadcast "$@"
329   gen_op_tmpl $ternary_broadcast_masked "$@"
330 }
331 
332 function gen_ternary_alu_double_bcst_op {
333   echo "Generating ternary double broadcast op $1 ($2)..."
334   gen_op_tmpl $ternary_double_broadcast "$@"
335   gen_op_tmpl $ternary_double_broadcast_masked "$@"
336 }
337 
338 function gen_binary_op {
339   echo "Generating binary op $1 ($2)..."
340 #  gen_op_tmpl $binary_scalar "$@"
341   gen_op_tmpl $binary "$@"
342   gen_op_tmpl $binary_masked "$@"
343 }
344 
345 function gen_saturating_binary_op {
346   echo "Generating binary op $1 ($2)..."
347   gen_op_tmpl $saturating_binary "$@"
348   gen_op_tmpl $saturating_binary_masked "$@"
349 }
350 
351 function gen_saturating_binary_op_associative {
352   echo "Generating saturating binary associative op $1 ($2)..."
353   gen_op_tmpl $saturating_binary_assocative "$@" "" "associative"
354   gen_op_tmpl $saturating_binary_assocative_masked "$@" "" "associative"
355 }
356 
357 function gen_binary_op_no_masked {
358   echo "Generating binary op $1 ($2)..."
359 #  gen_op_tmpl $binary_scalar "$@"
360   gen_op_tmpl $binary "$@"
361 }
362 
363 function gen_binary_bcst_op_no_masked {
364   echo "Generating binary broadcast op $1 ($2)..."
365   gen_op_tmpl $binary_broadcast "$@"
366 }
367 
368 function gen_compare_op {
369   echo "Generating compare op $1 ($2)..."
370   gen_op_tmpl $compare_template "$@"
371   gen_op_tmpl $compare_masked_template "$@"
372 }
373 
374 function gen_compare_bcst_op {
375   echo "Generating compare broadcast op $1 ($2)..."
376   gen_op_tmpl $compare_broadcast_template "$@"
377 }
378 
379 function gen_reduction_op {
380   echo "Generating reduction op $1 ($2)..."
381   gen_op_tmpl $reduction_scalar "$@"
382   gen_op_tmpl $reduction_op "$@"
383   gen_op_tmpl $reduction_scalar_masked "$@"
384   gen_op_tmpl $reduction_op_masked "$@"
385 }
386 
387 function gen_reduction_op_func {
388   echo "Generating reduction op $1 ($2)..."
389   gen_op_tmpl $reduction_scalar_func "$@"
390   gen_op_tmpl $reduction_op_func "$@"
391   gen_op_tmpl $reduction_scalar_masked_func "$@"
392   gen_op_tmpl $reduction_op_masked_func "$@"
393 }
394 
395 function gen_bool_reduction_op {
396   echo "Generating boolean reduction op $1 ($2)..."
397   gen_op_tmpl $bool_reduction_scalar "$@"
398   gen_op_tmpl $bool_reduction_template "$@"
399 }
400 function gen_saturating_reduction_op {
401   echo "Generating saturating reduction op $1 ($2)..."
402   gen_op_tmpl $reduction_scalar_func "$@" "reduction"
403   gen_op_tmpl $reduction_saturating_op "$@" "reduction"
404   gen_op_tmpl $reduction_scalar_masked_func "$@" "reduction"
405   gen_op_tmpl $reduction_saturating_op_masked "$@" "reduction"
406 }
407 
408 function gen_with_op {
409   echo "Generating with op $1 ($2)..."
410   gen_op_tmpl $with_op_template "$@"
411 }
412 
413 function gen_get_op {
414   echo "Generating get op $1 ($2)..."
415   gen_op_tmpl $get_template "$@"
416 }
417 
418 function gen_unit_header {
419   cat $TEMPLATE_FOLDER/Unit-header.template > $1
420 }
421 
422 function gen_unit_footer {
423   cat $TEMPLATE_FOLDER/Unit-footer.template >> $1
424 }
425 
426 function gen_perf_header {
427   cat $TEMPLATE_FOLDER/Perf-header.template > $1
428 }
429 
430 function gen_perf_footer {
431   cat $TEMPLATE_FOLDER/Perf-footer.template >> $1
432 }
433 
434 function gen_perf_scalar_header {
435   cat $TEMPLATE_FOLDER/Perf-Scalar-header.template > $1
436 }
437 
438 function gen_perf_scalar_footer {
439   cat $TEMPLATE_FOLDER/Perf-Scalar-footer.template >> $1
440 }
441 
442 gen_unit_header $unit_output
443 
444 if [ $generate_perf_tests == true ]; then
445   gen_perf_header $perf_output
446   gen_perf_scalar_header $perf_scalar_output
447 fi
448 
449 # ALU binary ops.
450 # Here "ADD+add+withMask" says VectorOperator name is "ADD", and we have a dedicate method too named 'add', and add() is also available with mask variant.
451 gen_binary_alu_op "ADD+add+withMask" "a + b"
452 gen_binary_alu_op "SUB+sub+withMask" "a - b"
453 gen_binary_alu_op "MUL+mul+withMask" "a \* b"
454 gen_binary_alu_op "DIV+div+withMask" "a \/ b" "FP"
455 gen_op_tmpl "Binary-op_bitwise-div" "DIV+div+withMask" "a \/ b" "BITWISE"
456 gen_op_tmpl "Binary-Masked-op_bitwise-div" "DIV+div+withMask" "a \/ b" "BITWISE"
457 gen_binary_alu_op "FIRST_NONZERO" "{#if[FP]?Double.doubleToLongBits}(a)!=0?a:b"
458 gen_binary_alu_op "AND+and"   "a \& b"  "BITWISE"
459 gen_binary_alu_op "AND_NOT" "a \& ~b" "BITWISE"
460 gen_binary_alu_op "OR+or"    "a | b"   "BITWISE"
461 # Missing:        "OR_UNCHECKED"
462 gen_binary_alu_op "XOR"   "a ^ b"   "BITWISE"
463 gen_binary_alu_op "COMPRESS_BITS" "\$Boxtype\$.compress(a, b)" "intOrLong"
464 gen_binary_alu_op "EXPAND_BITS" "\$Boxtype\$.expand(a, b)" "intOrLong"
465 # Generate the broadcast versions
466 gen_binary_alu_bcst_op "add+withMask" "a + b"
467 gen_binary_alu_bcst_op "sub+withMask" "a - b"
468 gen_binary_alu_bcst_op "mul+withMask" "a \* b"
469 gen_binary_alu_bcst_op "div+withMask" "a \/ b" "FP"
470 gen_op_tmpl "Binary-Broadcast-op_bitwise-div" "div+withMask" "a \/ b" "BITWISE"
471 gen_op_tmpl "Binary-Broadcast-Masked-op_bitwise-div" "div+withMask" "a \/ b" "BITWISE"
472 gen_binary_alu_bcst_op "OR+or"    "a | b"   "BITWISE"
473 gen_binary_alu_bcst_op "AND+and"    "a \& b"   "BITWISE"
474 gen_binary_alu_bcst_long_op "OR"     "a | b"   "BITWISE"
475 gen_binary_alu_bcst_long_op "ADD"    "a + b"
476 
477 # Shifts
478 gen_binary_alu_op "LSHL" "(a << b)" "intOrLong"
479 gen_binary_alu_op "LSHL" "(a << (b \& 0x7))" "byte"
480 gen_binary_alu_op "LSHL" "(a << (b \& 0xF))" "short"
481 gen_binary_alu_op "ASHR" "(a >> b)" "intOrLong"
482 gen_binary_alu_op "ASHR" "(a >> (b \& 0x7))" "byte"
483 gen_binary_alu_op "ASHR" "(a >> (b \& 0xF))" "short"
484 gen_binary_alu_op "LSHR" "(a >>> b)" "intOrLong"
485 gen_binary_alu_op "LSHR" "((a \& 0xFF) >>> (b \& 0x7))" "byte"
486 gen_binary_alu_op "LSHR" "((a \& 0xFFFF) >>> (b \& 0xF))" "short"
487 gen_shift_op  "LSHL" "(a << b)" "intOrLong"
488 gen_shift_op  "LSHL" "(a << (b \& 7))" "byte"
489 gen_shift_op  "LSHL" "(a << (b \& 15))" "short"
490 gen_shift_op  "LSHR" "(a >>> b)" "intOrLong"
491 gen_shift_op  "LSHR" "((a \& 0xFF) >>> (b \& 7))" "byte"
492 gen_shift_op  "LSHR" "((a \& 0xFFFF) >>> (b \& 15))" "short"
493 gen_shift_op  "ASHR" "(a >> b)" "intOrLong"
494 gen_shift_op  "ASHR" "(a >> (b \& 7))" "byte"
495 gen_shift_op  "ASHR" "(a >> (b \& 15))" "short"
496 gen_binary_alu_op "ROR" "ROR_scalar(a,b)" "BITWISE"
497 gen_binary_alu_op "ROL" "ROL_scalar(a,b)" "BITWISE"
498 gen_shift_op  "ROR" "ROR_scalar(a, b)" "BITWISE"
499 gen_shift_op  "ROL" "ROL_scalar(a, b)" "BITWISE"
500 
501 # Constant Shifts
502 gen_shift_cst_op  "LSHR" "(a >>> CONST_SHIFT)" "intOrLong"
503 gen_shift_cst_op  "LSHR" "((a \& 0xFF) >>> CONST_SHIFT)" "byte"
504 gen_shift_cst_op  "LSHR" "((a \& 0xFFFF) >>> CONST_SHIFT)" "short"
505 gen_shift_cst_op  "LSHL" "(a << CONST_SHIFT)" "BITWISE"
506 gen_shift_cst_op  "ASHR" "(a >> CONST_SHIFT)" "BITWISE"
507 gen_shift_cst_op  "ROR" "ROR_scalar(a, CONST_SHIFT)" "BITWISE"
508 gen_shift_cst_op  "ROL" "ROL_scalar(a, CONST_SHIFT)" "BITWISE"
509 
510 # Binary operation with one memory operand
511 gen_binary_alu_mem_op "MIN+min+withMask", "Math.min(a, b)"
512 gen_binary_alu_mem_op "MAX+max+withMask", "Math.max(a, b)"
513 
514 # Masked reductions.
515 gen_binary_op_no_masked "MIN+min" "Math.min(a, b)"
516 gen_binary_op_no_masked "MAX+max" "Math.max(a, b)"
517 gen_binary_op "UMIN" "VectorMath.minUnsigned(a, b)" "BITWISE"
518 gen_binary_op "UMAX" "VectorMath.maxUnsigned(a, b)" "BITWISE"
519 gen_saturating_binary_op "SADD" "VectorMath.addSaturating(a, b)" "BITWISE"
520 gen_saturating_binary_op "SSUB" "VectorMath.subSaturating(a, b)" "BITWISE"
521 gen_saturating_binary_op "SUADD" "VectorMath.addSaturatingUnsigned(a, b)" "BITWISE"
522 gen_saturating_binary_op "SUSUB" "VectorMath.subSaturatingUnsigned(a, b)" "BITWISE"
523 gen_binary_bcst_op_no_masked "MIN+min" "Math.min(a, b)"
524 gen_binary_bcst_op_no_masked "MAX+max" "Math.max(a, b)"
525 gen_saturating_binary_op_associative "SUADD" "VectorMath.addSaturatingUnsigned(a, b)" "BITWISE"
526 
527 # Reductions.
528 gen_reduction_op "AND" "\&" "BITWISE" "-1"
529 gen_reduction_op "OR" "|" "BITWISE" "0"
530 gen_reduction_op "XOR" "^" "BITWISE" "0"
531 gen_reduction_op "ADD" "+" "" "0"
532 gen_reduction_op "MUL" "*" "" "1"
533 gen_reduction_op_func "MIN" "(\$type\$) Math.min" "" "\$Wideboxtype\$.\$MaxValue\$"
534 gen_reduction_op_func "MAX" "(\$type\$) Math.max" "" "\$Wideboxtype\$.\$MinValue\$"
535 gen_reduction_op_func "UMIN" "(\$type\$) VectorMath.minUnsigned" "BITWISE" "\$Wideboxtype\$.\$MaxValue\$"
536 gen_reduction_op_func "UMAX" "(\$type\$) VectorMath.maxUnsigned" "BITWISE" "\$Wideboxtype\$.\$MinValue\$"
537 gen_reduction_op_func "FIRST_NONZERO" "firstNonZero" "" "(\$type\$) 0"
538 
539 # Boolean reductions.
540 gen_bool_reduction_op "anyTrue" "|" "BITWISE" "false"
541 gen_bool_reduction_op "allTrue" "\&" "BITWISE" "true"
542 
543 # Saturating reductions.
544 gen_saturating_reduction_op "SUADD" "(\$type\$) VectorMath.addSaturatingUnsigned" "BITWISE" "0"
545 
546 #Insert
547 gen_with_op "withLane" "" "" ""
548 
549 # Tests
550 gen_op_tmpl $test_template "IS_DEFAULT" "bits(a)==0"
551 gen_op_tmpl $test_template "IS_NEGATIVE" "bits(a)<0"
552 gen_op_tmpl $test_template "IS_FINITE" "\$Boxtype\$.isFinite(a)" "FP"
553 gen_op_tmpl $test_template "IS_NAN" "\$Boxtype\$.isNaN(a)" "FP"
554 gen_op_tmpl $test_template "IS_INFINITE" "\$Boxtype\$.isInfinite(a)" "FP"
555 
556 # Compares
557 gen_compare_op "LT+lt" "lt"
558 gen_compare_op "GT" "gt"
559 gen_compare_op "EQ+eq" "eq"
560 gen_compare_op "NE" "neq"
561 gen_compare_op "LE" "le"
562 gen_compare_op "GE" "ge"
563 
564 gen_compare_op "ULT" "ult" "BITWISE"
565 gen_compare_op "UGT" "ugt" "BITWISE"
566 gen_compare_op "ULE" "ule" "BITWISE"
567 gen_compare_op "UGE" "uge" "BITWISE"
568 
569 
570 gen_compare_bcst_op "LT" "<"
571 gen_compare_bcst_op "EQ" "=="
572 
573 # Blend.
574 gen_op_tmpl $blend "blend" ""
575 
576 # Rearrange
577 gen_op_tmpl $rearrange_template "rearrange" ""
578 
579 # Compress/Expand
580 gen_op_tmpl $compressexpand_template "compress_expand" ""
581 
582 # Get
583 gen_get_op "lane" ""
584 
585 # Broadcast
586 gen_op_tmpl $broadcast_template "broadcast" ""
587 
588 # Zero
589 gen_op_tmpl $zero_template "zero" ""
590 
591 # Slice
592 gen_op_tmpl $slice_template "sliceUnary" ""
593 gen_op_tmpl $slice1_template "sliceBinary" ""
594 gen_op_tmpl $slice1_masked_template "slice" ""
595 
596 # Unslice
597 gen_op_tmpl $unslice_template "unsliceUnary" ""
598 gen_op_tmpl $unslice1_template "unsliceBinary" ""
599 gen_op_tmpl $unslice1_masked_template "unslice" ""
600 
601 # Math
602 gen_op_tmpl $unary_math_template "SIN" "Math.sin((double)a)" "FP"
603 gen_op_tmpl $unary_math_template "EXP" "Math.exp((double)a)" "FP"
604 gen_op_tmpl $unary_math_template "LOG1P" "Math.log1p((double)a)" "FP"
605 gen_op_tmpl $unary_math_template "LOG" "Math.log((double)a)" "FP"
606 gen_op_tmpl $unary_math_template "LOG10" "Math.log10((double)a)" "FP"
607 gen_op_tmpl $unary_math_template "EXPM1" "Math.expm1((double)a)" "FP"
608 gen_op_tmpl $unary_math_template "COS" "Math.cos((double)a)" "FP"
609 gen_op_tmpl $unary_math_template "TAN" "Math.tan((double)a)" "FP"
610 gen_op_tmpl $unary_math_template "SINH" "Math.sinh((double)a)" "FP"
611 gen_op_tmpl $unary_math_template "COSH" "Math.cosh((double)a)" "FP"
612 gen_op_tmpl $unary_math_template "TANH" "Math.tanh((double)a)" "FP"
613 gen_op_tmpl $unary_math_template "ASIN" "Math.asin((double)a)" "FP"
614 gen_op_tmpl $unary_math_template "ACOS" "Math.acos((double)a)" "FP"
615 gen_op_tmpl $unary_math_template "ATAN" "Math.atan((double)a)" "FP"
616 gen_op_tmpl $unary_math_template "CBRT" "Math.cbrt((double)a)" "FP"
617 gen_op_tmpl $binary_math_template "HYPOT" "Math.hypot((double)a, (double)b)" "FP"
618 gen_op_tmpl $binary_math_template "POW+pow" "Math.pow((double)a, (double)b)" "FP"
619 gen_op_tmpl $binary_math_template "ATAN2" "Math.atan2((double)a, (double)b)" "FP"
620 gen_op_tmpl $binary_math_broadcast_template "POW+pow" "Math.pow((double)a, (double)b)" "FP"
621 
622 # Ternary operations.
623 gen_ternary_alu_op "FMA+fma" "Math.fma(a, b, c)" "FP"
624 gen_ternary_alu_op "BITWISE_BLEND+bitwiseBlend" "(a\&~(c))|(b\&c)" "BITWISE"
625 gen_ternary_alu_bcst_op "FMA" "Math.fma(a, b, c)" "FP"
626 gen_ternary_alu_bcst_op "BITWISE_BLEND+bitwiseBlend" "(a\&~(c))|(b\&c)" "BITWISE"
627 gen_ternary_alu_double_bcst_op "FMA+fma" "Math.fma(a, b, c)" "FP"
628 gen_ternary_alu_double_bcst_op "BITWISE_BLEND+bitwiseBlend" "(a\&~(c))|(b\&c)" "BITWISE"
629 
630 # Unary operations.
631 gen_unary_alu_op "NEG+neg" "-((\$type\$)a)"
632 gen_unary_alu_op "ABS+abs" "Math.abs((\$type\$)a)"
633 gen_unary_alu_op "NOT+not" "~((\$type\$)a)" "BITWISE"
634 gen_unary_alu_op "ZOMO" "(a==0?0:-1)" "BITWISE"
635 gen_unary_alu_op "SQRT+sqrt" "Math.sqrt((double)a)" "FP"
636 gen_unary_alu_op "BIT_COUNT" "\$Boxtype\$.bitCount(a)" "intOrLong"
637 gen_unary_alu_op "BIT_COUNT" "Integer.bitCount((int)a \& 0xFF)" "byte"
638 gen_unary_alu_op "BIT_COUNT" "Integer.bitCount((int)a \& 0xFFFF)" "short"
639 gen_unary_alu_op "TRAILING_ZEROS_COUNT" "TRAILING_ZEROS_COUNT_scalar(a)" "BITWISE"
640 gen_unary_alu_op "LEADING_ZEROS_COUNT" "LEADING_ZEROS_COUNT_scalar(a)" "BITWISE"
641 gen_unary_alu_op "REVERSE" "REVERSE_scalar(a)" "BITWISE"
642 gen_unary_alu_op "REVERSE_BYTES" "\$Boxtype\$.reverseBytes(a)" "intOrLong"
643 gen_unary_alu_op "REVERSE_BYTES" "\$Boxtype\$.reverseBytes(a)" "short"
644 gen_unary_alu_op "REVERSE_BYTES" "a" "byte"
645 
646 # Miscellaneous Smoke Tests
647 gen_op_tmpl $miscellaneous_template "MISC" "" ""
648 
649 gen_unit_footer $unit_output
650 
651 if [ $generate_perf_tests == true ]; then
652   gen_perf_footer $perf_output
653   gen_perf_scalar_footer $perf_scalar_output
654 fi
655 
656 rm -f templates/*.current*