1#!/bin/bash
2#
3# Copyright (c) 2018, 2020, 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.  Oracle designates this
9# particular file as subject to the "Classpath" exception as provided
10# by Oracle in the LICENSE file that accompanied this code.
11#
12# This code is distributed in the hope that it will be useful, but WITHOUT
13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15# version 2 for more details (a copy is included in the LICENSE file that
16# accompanied this code).
17#
18# You should have received a copy of the GNU General Public License version
19# 2 along with this work; if not, write to the Free Software Foundation,
20# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21#
22# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23# or visit www.oracle.com if you need additional information or have any
24# questions.
25#
26
27generate_perf_tests=$1
28
29TEMPLATE_FOLDER="templates/"
30
31unit_output="unit_tests.template"
32perf_output="perf_tests.template"
33perf_scalar_output="perf_scalar_tests.template"
34
35unary="Unary-op"
36unary_masked="Unary-Masked-op"
37unary_scalar="Unary-Scalar-op"
38ternary="Ternary-op"
39ternary_masked="Ternary-Masked-op"
40ternary_broadcast="Ternary-Broadcast-op"
41ternary_broadcast_masked="Ternary-Broadcast-Masked-op"
42ternary_double_broadcast="Ternary-Double-Broadcast-op"
43ternary_double_broadcast_masked="Ternary-Double-Broadcast-Masked-op"
44ternary_scalar="Ternary-Scalar-op"
45binary="Binary-op"
46binary_masked="Binary-Masked-op"
47binary_broadcast="Binary-Broadcast-op"
48binary_broadcast_masked="Binary-Broadcast-Masked-op"
49binary_broadcast_long="Binary-Broadcast-Long-op"
50binary_broadcast_masked_long="Binary-Broadcast-Masked-Long-op"
51binary_scalar="Binary-Scalar-op"
52blend="Blend-op"
53test_template="Test"
54compare_template="Compare"
55compare_masked_template="Compare-Masked"
56compare_broadcast_template="Compare-Broadcast"
57reduction_scalar="Reduction-Scalar-op"
58reduction_scalar_min="Reduction-Scalar-Min-op"
59reduction_scalar_max="Reduction-Scalar-Max-op"
60reduction_scalar_masked="Reduction-Scalar-Masked-op"
61reduction_scalar_min_masked="Reduction-Scalar-Masked-Min-op"
62reduction_scalar_max_masked="Reduction-Scalar-Masked-Max-op"
63reduction_op="Reduction-op"
64reduction_op_min="Reduction-Min-op"
65reduction_op_max="Reduction-Max-op"
66reduction_op_masked="Reduction-Masked-op"
67reduction_op_min_masked="Reduction-Masked-Min-op"
68reduction_op_max_masked="Reduction-Masked-Max-op"
69unary_math_template="Unary-op-math"
70binary_math_template="Binary-op-math"
71binary_math_broadcast_template="Binary-Broadcast-op-math"
72bool_reduction_scalar="BoolReduction-Scalar-op"
73bool_reduction_template="BoolReduction-op"
74with_op_template="With-Op"
75shift_template="Shift-op"
76shift_masked_template="Shift-Masked-op"
77gather_template="Gather-op"
78gather_masked_template="Gather-Masked-op"
79scatter_template="Scatter-op"
80scatter_masked_template="Scatter-Masked-op"
81get_template="Get-op"
82rearrange_template="Rearrange"
83broadcast_template="Broadcast"
84zero_template="Zero"
85slice_template="Slice-op"
86slice1_template="Slice-bop"
87slice1_masked_template="Slice-Masked-bop"
88unslice_template="Unslice-op"
89unslice1_template="Unslice-bop"
90unslice1_masked_template="Unslice-Masked-bop"
91miscellaneous_template="Miscellaneous"
92
93function replace_variables {
94  local filename=$1
95  local output=$2
96  local kernel=$3
97  local test=$4
98  local op=$5
99  local init=$6
100  local guard=$7
101  local masked=$8
102  local op_name=$9
103  local kernel_smoke=${10}
104
105  if [ "x${kernel}" != "x" ]; then
106    local kernel_escaped=$(echo -e "$kernel" | tr '\n' '|')
107    sed "s/\[\[KERNEL\]\]/${kernel_escaped}/g" $filename > ${filename}.current1
108    cat ${filename}.current1 | tr '|' "\n" > ${filename}.current
109    rm -f "${filename}.current1"
110  else
111    cp $filename ${filename}.current
112  fi
113
114  # Check if we need to do multiple replacements
115  # If you want to emit for an operation using lanewise(VectorOperator.**, ..) and also using dedicated instruction (e.g. add(..)), then
116  # pass the 'test' argument as "OPERATOR_NAME+func_Name" (e.g. "ADD+add")
117  # if there is a masked version available for the operation add "withMask" to 'test' argument (e.g. "ADD+add+withMask")
118  local test_func=""
119  local withMask=""
120  local tests=($(awk -F+ '{$1=$1} 1' <<< $test))
121  if [ "${tests[2]}" == "withMask" ]; then
122    test=${tests[0]}
123    test_func=${tests[1]}
124    withMask=${tests[2]}
125  elif [ "${tests[1]}" == "withMask" ]; then
126    test=""
127    test_func=${tests[0]}
128    withMask=${tests[1]}
129  elif [ "${tests[1]}" != "" ]; then
130    test=${tests[0]}
131    test_func=${tests[1]}
132  fi
133
134  sed_prog="
135    s/\<OPTIONAL\>\(.*\)\<\\OPTIONAL\>/\1/g
136    s/\[\[TEST_TYPE\]\]/${masked}/g
137    s/\[\[TEST_OP\]\]/${op}/g
138    s/\[\[TEST_INIT\]\]/${init}/g
139    s/\[\[OP_NAME\]\]/${op_name}/g
140  "
141  sed_prog_2="$sed_prog
142    s/\[\[TEST\]\]/${test_func}/g
143    s/[.][^(]*(VectorOperators.$test_func, /.$test_func(/g
144    s/[.][^(]*(VectorOperators.$test_func,/.$test_func(/g
145    s/[.][^(]*(VectorOperators.$test_func/.$test_func(/g
146  "
147  sed_prog="
148    $sed_prog
149    s/\[\[TEST\]\]/${test}/g
150  "
151
152  # Guard the test if necessary
153  if [ "$guard" != "" ]; then
154    echo -e "#if[${guard}]\n" >> $output
155  fi
156  if [ "$test" != "" ]; then
157    sed -e "$sed_prog" < ${filename}.current >> $output
158  fi
159  # If we also have a dedicated function for the operation then use 2nd sed expression
160  if [[ "$filename" == *"Unit"* ]] && [ "$test_func" != "" ]; then
161    if [ "$masked" == "" ] || [ "$withMask" != "" ]; then
162      if [ ! -z "$kernel_smoke" ]; then
163        local kernel_smoke_escaped=$(echo -e "$kernel_smoke" | tr '\n' '|')
164        sed "s/\[\[KERNEL\]\]/${kernel_smoke_escaped}/g" $filename > ${filename}.scurrent1
165        cat ${filename}.scurrent1 | tr '|' "\n" > ${filename}.scurrent
166        rm -f "${filename}.scurrent1"
167      else
168        cp $filename.current ${filename}.scurrent
169      fi
170      sed -e "$sed_prog_2" < ${filename}.scurrent >> $output
171      rm -f ${filename}.scurrent
172    fi
173  fi
174  if [ "$guard" != "" ]; then
175    echo -e "#end[${guard}]\n" >> $output
176  fi
177
178  rm -f ${filename}.current
179}
180
181function gen_op_tmpl {
182  local template=$1
183  local test=$2
184  local op=$3
185  local guard=""
186  local init=""
187  if [ $# -gt 3 ]; then
188    guard=$4
189  fi
190  if [ $# == 5 ]; then
191    init=$5
192  fi
193
194  local masked=""
195  if [[ $template == *"Masked"* ]]; then
196    masked="Masked"
197  fi
198
199  local op_name=""
200  if [[ $template == *"Shift"* ]]; then
201    op_name="Shift"
202  elif [[ $template == *"Get"* ]]; then
203    op_name="extract"
204  fi
205
206  local kernel_filename="${TEMPLATE_FOLDER}/Kernel-${template}.template"
207  local kernel_smoke_filename="${TEMPLATE_FOLDER}/Kernel-${template}-smoke.template"
208  local unit_filename="${TEMPLATE_FOLDER}/Unit-${template}.template"
209  if [ ! -f $unit_filename ]; then
210    # Leverage general unit code snippet if no specialization exists
211    unit_filename="${TEMPLATE_FOLDER}/Unit-${template%_*}.template"
212    echo $unit_filename
213  fi
214
215  local kernel=""
216  if [ -f $kernel_filename ]; then
217    kernel="$(cat $kernel_filename)"
218  fi
219
220  local kernel_smoke=""
221  if [ -f $kernel_smoke_filename ]; then
222    kernel_smoke="$(cat $kernel_smoke_filename)"
223  else
224    kernel_smoke="$kernel"
225  fi
226
227  # Replace template variables in unit test files (if any)
228  replace_variables $unit_filename $unit_output "$kernel" "$test" "$op" "$init" "$guard" "$masked" "$op_name" "$kernel_smoke"
229
230  local gen_perf_tests=$generate_perf_tests
231  if [[ $template == *"-Broadcast-"* ]] || [[ $template == "Miscellaneous" ]] ||
232     [[ $template == *"Compare-Masked"* ]] || [[ $template == *"Compare-Broadcast"* ]]; then
233    gen_perf_tests=false
234  fi
235  if [ $gen_perf_tests == true ]; then
236    # Replace template variables in performance test files (if any)
237    local perf_wrapper_filename="${TEMPLATE_FOLDER}/Perf-wrapper.template"
238    local perf_vector_filename="${TEMPLATE_FOLDER}/Perf-${template}.template"
239    local perf_scalar_filename="${TEMPLATE_FOLDER}/Perf-Scalar-${template}.template"
240
241    if [ -f $perf_vector_filename ]; then
242      replace_variables $perf_vector_filename  $perf_output "$kernel" "$test" "$op" "$init" "$guard" "$masked" "$op_name" ""
243    elif [ -f $kernel_filename ]; then
244      replace_variables $perf_wrapper_filename $perf_output "$kernel" "$test" "$op" "$init" "$guard" "$masked" "$op_name" ""
245    elif [[ $template != *"-Scalar-"* ]] && [[ $template != "Get-op" ]] && [[ $template != "With-Op" ]]; then
246      echo "Warning: missing perf: $@"
247    fi
248
249    if [ -f $perf_scalar_filename ]; then
250      replace_variables $perf_scalar_filename $perf_scalar_output "$kernel" "$test" "$op" "$init" "$guard" "$masked" "$op_name" ""
251    elif [[ $template != *"-Scalar-"* ]] && [[ $template != "Get-op" ]] && [[ $template != "With-Op" ]]; then
252      echo "Warning: Missing PERF SCALAR: $perf_scalar_filename"
253    fi
254  fi
255}
256
257function gen_binary_alu_op {
258  echo "Generating binary op $1 ($2)..."
259  gen_op_tmpl $binary "$@"
260  gen_op_tmpl $binary_masked "$@"
261}
262
263function gen_binary_alu_bcst_op {
264  echo "Generating binary broadcast op $1 ($2)..."
265  gen_op_tmpl $binary_broadcast "$@"
266  gen_op_tmpl $binary_broadcast_masked "$@"
267}
268
269function gen_binary_alu_bcst_long_op {
270  echo "Generating binary broadcast long op $1 ($2)..."
271  gen_op_tmpl $binary_broadcast_long "$@"
272  gen_op_tmpl $binary_broadcast_masked_long "$@"
273}
274
275function gen_shift_cst_op {
276  echo "Generating Shift constant op $1 ($2)..."
277  gen_op_tmpl $shift_template "$@"
278  gen_op_tmpl $shift_masked_template "$@"
279}
280
281function gen_unary_alu_op {
282  echo "Generating unary op $1 ($2)..."
283  gen_op_tmpl $unary_scalar "$@"
284  gen_op_tmpl $unary "$@"
285  gen_op_tmpl $unary_masked "$@"
286}
287
288function gen_ternary_alu_op {
289  echo "Generating ternary op $1 ($2)..."
290  gen_op_tmpl $ternary_scalar "$@"
291  gen_op_tmpl $ternary "$@"
292  gen_op_tmpl $ternary_masked "$@"
293}
294
295function gen_ternary_alu_bcst_op {
296  echo "Generating ternary broadcast op $1 ($2)..."
297  gen_op_tmpl $ternary_broadcast "$@"
298  gen_op_tmpl $ternary_broadcast_masked "$@"
299}
300
301function gen_ternary_alu_double_bcst_op {
302  echo "Generating ternary double broadcast op $1 ($2)..."
303  gen_op_tmpl $ternary_double_broadcast "$@"
304  gen_op_tmpl $ternary_double_broadcast_masked "$@"
305}
306
307function gen_binary_op {
308  echo "Generating binary op $1 ($2)..."
309#  gen_op_tmpl $binary_scalar "$@"
310  gen_op_tmpl $binary "$@"
311  gen_op_tmpl $binary_masked "$@"
312}
313
314function gen_binary_op_no_masked {
315  echo "Generating binary op $1 ($2)..."
316#  gen_op_tmpl $binary_scalar "$@"
317  gen_op_tmpl $binary "$@"
318}
319
320function gen_binary_bcst_op_no_masked {
321  echo "Generating binary broadcast op $1 ($2)..."
322  gen_op_tmpl $binary_broadcast "$@"
323}
324
325function gen_compare_op {
326  echo "Generating compare op $1 ($2)..."
327  gen_op_tmpl $compare_template "$@"
328  gen_op_tmpl $compare_masked_template "$@"
329}
330
331function gen_compare_bcst_op {
332  echo "Generating compare broadcast op $1 ($2)..."
333  gen_op_tmpl $compare_broadcast_template "$@"
334}
335
336function gen_reduction_op {
337  echo "Generating reduction op $1 ($2)..."
338  gen_op_tmpl $reduction_scalar "$@"
339  gen_op_tmpl $reduction_op "$@"
340  gen_op_tmpl $reduction_scalar_masked "$@"
341  gen_op_tmpl $reduction_op_masked "$@"
342}
343
344function gen_reduction_op_min {
345  echo "Generating reduction op $1 ($2)..."
346  gen_op_tmpl $reduction_scalar_min "$@"
347  gen_op_tmpl $reduction_op_min "$@"
348  gen_op_tmpl $reduction_scalar_min_masked "$@"
349  gen_op_tmpl $reduction_op_min_masked "$@"
350}
351
352function gen_reduction_op_max {
353  echo "Generating reduction op $1 ($2)..."
354  gen_op_tmpl $reduction_scalar_max "$@"
355  gen_op_tmpl $reduction_op_max "$@"
356  gen_op_tmpl $reduction_scalar_max_masked "$@"
357  gen_op_tmpl $reduction_op_max_masked "$@"
358}
359
360function gen_bool_reduction_op {
361  echo "Generating boolean reduction op $1 ($2)..."
362  gen_op_tmpl $bool_reduction_scalar "$@"
363  gen_op_tmpl $bool_reduction_template "$@"
364}
365
366function gen_with_op {
367  echo "Generating with op $1 ($2)..."
368  gen_op_tmpl $with_op_template "$@"
369}
370
371function gen_get_op {
372  echo "Generating get op $1 ($2)..."
373  gen_op_tmpl $get_template "$@"
374}
375
376function gen_unit_header {
377  cat $TEMPLATE_FOLDER/Unit-header.template > $1
378}
379
380function gen_unit_footer {
381  cat $TEMPLATE_FOLDER/Unit-footer.template >> $1
382}
383
384function gen_perf_header {
385  cat $TEMPLATE_FOLDER/Perf-header.template > $1
386}
387
388function gen_perf_footer {
389  cat $TEMPLATE_FOLDER/Perf-footer.template >> $1
390}
391
392function gen_perf_scalar_header {
393  cat $TEMPLATE_FOLDER/Perf-Scalar-header.template > $1
394}
395
396function gen_perf_scalar_footer {
397  cat $TEMPLATE_FOLDER/Perf-Scalar-footer.template >> $1
398}
399
400gen_unit_header $unit_output
401
402if [ $generate_perf_tests == true ]; then
403  gen_perf_header $perf_output
404  gen_perf_scalar_header $perf_scalar_output
405fi
406
407# ALU binary ops.
408# 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.
409gen_binary_alu_op "ADD+add+withMask" "a + b"
410gen_binary_alu_op "SUB+sub+withMask" "a - b"
411gen_binary_alu_op "MUL+mul+withMask" "a \* b"
412gen_binary_alu_op "DIV+div+withMask" "a \/ b" "FP"
413gen_op_tmpl "Binary-op_bitwise-div" "DIV+div+withMask" "a \/ b" "BITWISE"
414gen_op_tmpl "Binary-Masked-op_bitwise-div" "DIV+div+withMask" "a \/ b" "BITWISE"
415gen_binary_alu_op "FIRST_NONZERO" "{#if[FP]?Double.doubleToLongBits}(a)!=0?a:b"
416gen_binary_alu_op "AND+and"   "a \& b"  "BITWISE"
417gen_binary_alu_op "AND_NOT" "a \& ~b" "BITWISE"
418gen_binary_alu_op "OR+or"    "a | b"   "BITWISE"
419# Missing:        "OR_UNCHECKED"
420gen_binary_alu_op "XOR"   "a ^ b"   "BITWISE"
421# Generate the broadcast versions
422gen_binary_alu_bcst_op "add+withMask" "a + b"
423gen_binary_alu_bcst_op "sub+withMask" "a - b"
424gen_binary_alu_bcst_op "mul+withMask" "a \* b"
425gen_binary_alu_bcst_op "div+withMask" "a \/ b" "FP"
426gen_op_tmpl "Binary-Broadcast-op_bitwise-div" "div+withMask" "a \/ b" "BITWISE"
427gen_op_tmpl "Binary-Broadcast-Masked-op_bitwise-div" "div+withMask" "a \/ b" "BITWISE"
428gen_binary_alu_bcst_op "OR+or"    "a | b"   "BITWISE"
429gen_binary_alu_bcst_op "AND+and"    "a \& b"   "BITWISE"
430gen_binary_alu_bcst_long_op "OR"     "a | b"   "BITWISE"
431gen_binary_alu_bcst_long_op "ADD"    "a + b"
432
433# Shifts
434gen_binary_alu_op "LSHL" "(a << b)" "intOrLong"
435gen_binary_alu_op "LSHL" "(a << (b \& 0x7))" "byte"
436gen_binary_alu_op "LSHL" "(a << (b \& 0xF))" "short"
437gen_binary_alu_op "ASHR" "(a >> b)" "intOrLong"
438gen_binary_alu_op "ASHR" "(a >> (b \& 0x7))" "byte"
439gen_binary_alu_op "ASHR" "(a >> (b \& 0xF))" "short"
440gen_binary_alu_op "LSHR" "(a >>> b)" "intOrLong"
441gen_binary_alu_op "LSHR" "((a \& 0xFF) >>> (b \& 0x7))" "byte"
442gen_binary_alu_op "LSHR" "((a \& 0xFFFF) >>> (b \& 0xF))" "short"
443gen_shift_cst_op  "LSHL" "(a << b)" "intOrLong"
444gen_shift_cst_op  "LSHL" "(a << (b \& 7))" "byte"
445gen_shift_cst_op  "LSHL" "(a << (b \& 15))" "short"
446gen_shift_cst_op  "LSHR" "(a >>> b)" "intOrLong"
447gen_shift_cst_op  "LSHR" "((a \& 0xFF) >>> (b \& 7))" "byte"
448gen_shift_cst_op  "LSHR" "((a \& 0xFFFF) >>> (b \& 15))" "short"
449gen_shift_cst_op  "ASHR" "(a >> b)" "intOrLong"
450gen_shift_cst_op  "ASHR" "(a >> (b \& 7))" "byte"
451gen_shift_cst_op  "ASHR" "(a >> (b \& 15))" "short"
452
453# Masked reductions.
454gen_binary_op_no_masked "MIN+min" "Math.min(a, b)"
455gen_binary_op_no_masked "MAX+max" "Math.max(a, b)"
456gen_binary_bcst_op_no_masked "MIN+min" "Math.min(a, b)"
457gen_binary_bcst_op_no_masked "MAX+max" "Math.max(a, b)"
458
459# Reductions.
460gen_reduction_op "AND" "\&" "BITWISE" "-1"
461gen_reduction_op "OR" "|" "BITWISE" "0"
462gen_reduction_op "XOR" "^" "BITWISE" "0"
463gen_reduction_op "ADD" "+" "" "0"
464gen_reduction_op "MUL" "*" "" "1"
465gen_reduction_op_min "MIN" "" "" "\$Wideboxtype\$.\$MaxValue\$"
466gen_reduction_op_max "MAX" "" "" "\$Wideboxtype\$.\$MinValue\$"
467#gen_reduction_op "reduce_FIRST_NONZERO" "lanewise_FIRST_NONZERO" "{#if[FP]?Double.doubleToLongBits}(a)=0?a:b" "" "1"
468
469# Boolean reductions.
470gen_bool_reduction_op "anyTrue" "|" "BITWISE" "false"
471gen_bool_reduction_op "allTrue" "\&" "BITWISE" "true"
472
473#Insert
474gen_with_op "withLane" "" "" ""
475
476# Tests
477gen_op_tmpl $test_template "IS_DEFAULT" "bits(a)==0"
478gen_op_tmpl $test_template "IS_NEGATIVE" "bits(a)<0"
479gen_op_tmpl $test_template "IS_FINITE" "\$Boxtype\$.isFinite(a)" "FP"
480gen_op_tmpl $test_template "IS_NAN" "\$Boxtype\$.isNaN(a)" "FP"
481gen_op_tmpl $test_template "IS_INFINITE" "\$Boxtype\$.isInfinite(a)" "FP"
482
483# Compares
484gen_compare_op "LT+lt" "<"
485gen_compare_op "GT" ">"
486gen_compare_op "EQ+eq" "=="
487gen_compare_op "NE" "!="
488gen_compare_op "LE" "<="
489gen_compare_op "GE" ">="
490gen_compare_bcst_op "LT" "<"
491gen_compare_bcst_op "EQ" "=="
492
493# Blend.
494gen_op_tmpl $blend "blend" ""
495
496# Rearrange
497gen_op_tmpl $rearrange_template "rearrange" ""
498
499# Get
500gen_get_op "lane" ""
501
502# Broadcast
503gen_op_tmpl $broadcast_template "broadcast" ""
504
505# Zero
506gen_op_tmpl $zero_template "zero" ""
507
508# Slice
509gen_op_tmpl $slice_template "sliceUnary" ""
510gen_op_tmpl $slice1_template "sliceBinary" ""
511gen_op_tmpl $slice1_masked_template "slice" ""
512
513# Unslice
514gen_op_tmpl $unslice_template "unsliceUnary" ""
515gen_op_tmpl $unslice1_template "unsliceBinary" ""
516gen_op_tmpl $unslice1_masked_template "unslice" ""
517
518# Math
519gen_op_tmpl $unary_math_template "SIN" "Math.sin((double)a)" "FP"
520gen_op_tmpl $unary_math_template "EXP" "Math.exp((double)a)" "FP"
521gen_op_tmpl $unary_math_template "LOG1P" "Math.log1p((double)a)" "FP"
522gen_op_tmpl $unary_math_template "LOG" "Math.log((double)a)" "FP"
523gen_op_tmpl $unary_math_template "LOG10" "Math.log10((double)a)" "FP"
524gen_op_tmpl $unary_math_template "EXPM1" "Math.expm1((double)a)" "FP"
525gen_op_tmpl $unary_math_template "COS" "Math.cos((double)a)" "FP"
526gen_op_tmpl $unary_math_template "TAN" "Math.tan((double)a)" "FP"
527gen_op_tmpl $unary_math_template "SINH" "Math.sinh((double)a)" "FP"
528gen_op_tmpl $unary_math_template "COSH" "Math.cosh((double)a)" "FP"
529gen_op_tmpl $unary_math_template "TANH" "Math.tanh((double)a)" "FP"
530gen_op_tmpl $unary_math_template "ASIN" "Math.asin((double)a)" "FP"
531gen_op_tmpl $unary_math_template "ACOS" "Math.acos((double)a)" "FP"
532gen_op_tmpl $unary_math_template "ATAN" "Math.atan((double)a)" "FP"
533gen_op_tmpl $unary_math_template "CBRT" "Math.cbrt((double)a)" "FP"
534gen_op_tmpl $binary_math_template "HYPOT" "Math.hypot((double)a, (double)b)" "FP"
535gen_op_tmpl $binary_math_template "POW+pow" "Math.pow((double)a, (double)b)" "FP"
536gen_op_tmpl $binary_math_template "ATAN2" "Math.atan2((double)a, (double)b)" "FP"
537gen_op_tmpl $binary_math_broadcast_template "POW+pow" "Math.pow((double)a, (double)b)" "FP"
538
539# Ternary operations.
540gen_ternary_alu_op "FMA+fma" "Math.fma(a, b, c)" "FP"
541gen_ternary_alu_op "BITWISE_BLEND+bitwiseBlend" "(a\&~(c))|(b\&c)" "BITWISE"
542gen_ternary_alu_bcst_op "FMA" "Math.fma(a, b, c)" "FP"
543gen_ternary_alu_bcst_op "BITWISE_BLEND+bitwiseBlend" "(a\&~(c))|(b\&c)" "BITWISE"
544gen_ternary_alu_double_bcst_op "FMA+fma" "Math.fma(a, b, c)" "FP"
545gen_ternary_alu_double_bcst_op "BITWISE_BLEND+bitwiseBlend" "(a\&~(c))|(b\&c)" "BITWISE"
546
547# Unary operations.
548gen_unary_alu_op "NEG+neg" "-((\$type\$)a)"
549gen_unary_alu_op "ABS+abs" "Math.abs((\$type\$)a)"
550gen_unary_alu_op "NOT+not" "~((\$type\$)a)" "BITWISE"
551gen_unary_alu_op "ZOMO" "(a==0?0:-1)" "BITWISE"
552gen_unary_alu_op "SQRT+sqrt" "Math.sqrt((double)a)" "FP"
553
554# Gather Scatter operations.
555gen_op_tmpl $gather_template "gather" ""
556gen_op_tmpl $gather_masked_template "gather" ""
557gen_op_tmpl $scatter_template "scatter" ""
558gen_op_tmpl $scatter_masked_template "scatter" ""
559
560# Miscellaneous Smoke Tests
561gen_op_tmpl $miscellaneous_template "MISC" "" ""
562
563gen_unit_footer $unit_output
564
565if [ $generate_perf_tests == true ]; then
566  gen_perf_footer $perf_output
567  gen_perf_scalar_footer $perf_scalar_output
568fi
569
570rm -f templates/*.current*
571