From 7ec6380d6dd814319f976228cdbae474851a3c24 Mon Sep 17 00:00:00 2001 From: Pengfei Xu Date: Fri, 24 May 2024 16:47:40 +0800 Subject: [PATCH] avx512vbmi: add 32 avx512vbmi instruction cases Signed-off-by: Pengfei Xu --- BM/README.md | 1 + BM/avx512vbmi/.gitignore | 1 + BM/avx512vbmi/Makefile | 12 ++ BM/avx512vbmi/README.md | 20 +++ BM/avx512vbmi/tests | 38 +++++ BM/avx512vbmi/vbmi_func.sh | 274 +++++++++++++++++++++++++++++++++++++ BM/avx512vbmi/vbmi_test.c | 107 +++++++++++++++ README.md | 1 + 8 files changed, 454 insertions(+) create mode 100644 BM/avx512vbmi/.gitignore create mode 100644 BM/avx512vbmi/Makefile create mode 100644 BM/avx512vbmi/README.md create mode 100644 BM/avx512vbmi/tests create mode 100755 BM/avx512vbmi/vbmi_func.sh create mode 100644 BM/avx512vbmi/vbmi_test.c diff --git a/BM/README.md b/BM/README.md index 3c309970..6e2180be 100644 --- a/BM/README.md +++ b/BM/README.md @@ -2,6 +2,7 @@ ## Features * [AMX](amx/README.md) + * [avx512vbmi](avx512vbmi/README.md) * [cet(Control flow Enhancement Technology)](cet/README.md) * [cstate](cstate/README.md) * [DSA](dsa/README.md) diff --git a/BM/avx512vbmi/.gitignore b/BM/avx512vbmi/.gitignore new file mode 100644 index 00000000..5e21c6a7 --- /dev/null +++ b/BM/avx512vbmi/.gitignore @@ -0,0 +1 @@ +vbmi_test diff --git a/BM/avx512vbmi/Makefile b/BM/avx512vbmi/Makefile new file mode 100644 index 00000000..0f55829b --- /dev/null +++ b/BM/avx512vbmi/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2022 Intel Corporation. + +BIN := vbmi_test + +all: $(BIN) + +vbmi_test: vbmi_test.c + $(CC) -o $@ $^ + +clean: + rm -rf $(BIN) *.o diff --git a/BM/avx512vbmi/README.md b/BM/avx512vbmi/README.md new file mode 100644 index 00000000..eb7bb348 --- /dev/null +++ b/BM/avx512vbmi/README.md @@ -0,0 +1,20 @@ +# avx512vbmi (avx512 Vector Byte Manipulation Instructions) + +avx512vbmi is a set of instructions for Intel Tiger Lake and subsequent +platforms. Here is the test of some vbmi instructions. + +You can run the cases one by one, e.g. command + +``` +./vbmi_func.sh -n vbmi_test -p "1 ff b" +./vbmi_func.sh -n vbmi_test -p random +``` + +You also can run the cases together with runtests command, e.g. +``` +cd .. +./runtests -f avx512vbmi/tests -o logfile + +If the platform CPU you are testing does not support avx512vbmi, it will exit +immediately and remind you to check the /tmp/lkvs_dependence log. +``` diff --git a/BM/avx512vbmi/tests b/BM/avx512vbmi/tests new file mode 100644 index 00000000..815dfea4 --- /dev/null +++ b/BM/avx512vbmi/tests @@ -0,0 +1,38 @@ +# This file collects the VBMI(Vector Byte Manipulation Instructions) tests on +# IntelĀ® Architecture-based platforms. +# @hw_dep: cpuid_check 7 0 0 0 c 1 @ CPU doesn't support VBMI CPUID.(EAX=07H,ECX=0H):ECX[bit 1] +# @other_dep: +# @other_warn: + +vbmi_func.sh -n vbmi_test -p "0 ff b" +vbmi_func.sh -n vbmi_test -p "1 ff b" +vbmi_func.sh -n vbmi_test -p "2 ff b" +vbmi_func.sh -n vbmi_test -p "3 ff b" +vbmi_func.sh -n vbmi_test -p "4 ff b" +vbmi_func.sh -n vbmi_test -p "5 ff b" +vbmi_func.sh -n vbmi_test -p "6 ff b" +vbmi_func.sh -n vbmi_test -p "7 ff b" +vbmi_func.sh -n vbmi_test -p "18 ff b" +vbmi_func.sh -n vbmi_test -p "19 ff b" +vbmi_func.sh -n vbmi_test -p "1F ff b" +vbmi_func.sh -n vbmi_test -p "20 ff b" +vbmi_func.sh -n vbmi_test -p "21 ff b" +vbmi_func.sh -n vbmi_test -p "30 ff b" +vbmi_func.sh -n vbmi_test -p "3A ff b" +vbmi_func.sh -n vbmi_test -p "3F ff b" +vbmi_func.sh -n vbmi_test -p "40 ff b" +vbmi_func.sh -n vbmi_test -p "41 ff b" +vbmi_func.sh -n vbmi_test -p "42 ff b" +vbmi_func.sh -n vbmi_test -p "43 ff b" +vbmi_func.sh -n vbmi_test -p "50 ff b" +vbmi_func.sh -n vbmi_test -p "60 ff b" +vbmi_func.sh -n vbmi_test -p "ff ff b" +vbmi_func.sh -n vbmi_test -p "0 0 b" +vbmi_func.sh -n vbmi_test -p "0 1 b" +vbmi_func.sh -n vbmi_test -p "0 5 b" +vbmi_func.sh -n vbmi_test -p "0 A b" +vbmi_func.sh -n vbmi_test -p "0 F b" +vbmi_func.sh -n vbmi_test -p "0 1FF b" +vbmi_func.sh -n vbmi_test -p "0 FFFF b" +vbmi_func.sh -n vbmi_test -p "0 1FFFF b" +vbmi_func.sh -n vbmi_test -p random diff --git a/BM/avx512vbmi/vbmi_func.sh b/BM/avx512vbmi/vbmi_func.sh new file mode 100755 index 00000000..898efeb4 --- /dev/null +++ b/BM/avx512vbmi/vbmi_func.sh @@ -0,0 +1,274 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2023 Intel Corporation +# Author: Pengfei Xu +# Description: Test script to verify VBMI instruction + +cd "$(dirname "$0")" 2>/dev/null || exit 1 +# shellcheck disable=SC1091 +source ../.env +# shellcheck disable=SC1091 +source "ifs_common.sh" + +usage() { + cat <<__EOF + usage: ./${0##*/} [-n BIN_NAME][-p parameter][-h] + -n Test cpu bin name like vpmadd and so on + -p Test bin file parameter like "2 3 b" and so on + -h show This +__EOF +} + +# Check test bin results should contain "RESULTS" and no "[fail]" in it +# Input: log path +# Return: 0 for true, otherwise false or die +log_common_check() { + log=$1 + + grep -q -i "\[FAIL\]" "$log" && die "$log contain [FAIL]" + test_print_trc "Check $log pass, no [FAIL] in it" +} + +# Show key test info in log +# Input: +# $1: log path +# $2: filter key info in log, "all" for w/o filter, other for filter key name +# Return: 0 for true, otherwise false or die +show_test_info() { + local log=$1 + local key=$2 + local all="all" + local key_info="" + + test_print_trc "Show $key info in $log:" + if [[ "$key" == "$all" ]]; then + key_info=$(cat "$log") + else + key_info=$(grep -i "$key" "$log") + fi + test_print_trc "$key_info" + test_print_trc "$log end." +} + +# Convert the number to binary and only get the low 8 bits +# Input: $1 the number which need convert +# Return low 8 bits with format "xxxx xxxx", otherwise false +convert_binary() { + num=$1 + local gap="" + local bin_num="" + local bin_num_len="" + local low_num="" + local byte_num="" + local i=0 + local j=0 + local end_point + + [ -n "$num" ] || die "Num is null:$num" + bin_num=$(echo "obase=2;$num"|bc) + bin_num_len=${#bin_num} + if [ "$bin_num_len" -lt 4 ]; then + low_num=${bin_num:0-$bin_num_len} + end_point=$((4 - bin_num_len)) + for ((i=0; i $log" + else + log="${log_path}/${bin_name}_${bin_parm_name}.log" + eval "$bin $bin_parm > $log" + fi + + [ -e "$log" ] || die "No $log file" + case $name in + vbmi) + show_test_info "$log" "$all" + log_common_check "$log" + test_vbmi "$bin_parm" "$log" + ;; + *) + show_test_info "$log" "$all" + test_print_trc "No need extra check for $name" + ;; + esac + return 0 +} + +main() { + local func_name="vbmi" + local random_par="" + local a="" + local b="" + local ax="" + local bx="" + local times=10 + local t=1 + + test_print_trc "Test $BIN_NAME, parameter: $PARM" + + if [ "$PARM" == "random" ]; then + for((t=1;t<=times;t++)); do + test_print_trc "******* $t round test:" + ((a=RANDOM%256)) + ((b=RANDOM%256)) + ax=$(echo "obase=16;$a"|bc) + bx=$(echo "obase=16;$b"|bc) + random_par="$ax"' '"$bx"' '"b" + cpu_func_parm_test "$BIN_NAME" "$random_par" "$func_name" + done + else + cpu_func_parm_test "$BIN_NAME" "$PARM" "$func_name" + fi +} + +while getopts :n:p:h arg; do + case $arg in + n) + BIN_NAME=$OPTARG + ;; + p) + PARM=$OPTARG + ;; + h) + usage + exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +main diff --git a/BM/avx512vbmi/vbmi_test.c b/BM/avx512vbmi/vbmi_test.c new file mode 100644 index 00000000..c9c7931f --- /dev/null +++ b/BM/avx512vbmi/vbmi_test.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2022 Intel Corporation. + +/* + * vbmi_test.c: Vector Byte Manipulation Instructions + * + * Author: Pengfei, Xu + * - Add parameter and usage to add new instruction next + * - Check output binary result + * - Check zmm1 output relation with zmm2 and zmm3 + * - Solved stack smashing and core dump issue after execute program + */ + +/*****************************************************************************/ + +#include +#include +#define N 64 + +typedef unsigned long long al __attribute__((aligned (64))); +static unsigned long pp1[16] = {0}; +static al c; + +void h_to_b(unsigned long n, int bit) +{ + int i, j = 0; + int a[bit]; + + for (i = 0; i != bit; ++i) { + a[bit - 1 - i] = n % 2; + n /= 2; + } + for (i = 0; i != bit; ++i) { + printf("%d", a[i]); + if ((i + 1) % 4 == 0) + printf(" "); + } +} + +static inline void vbmi(unsigned int r1, unsigned int r2) +{ + al a, b; + + a = r1; + b = r2; + asm volatile("vmovdqa32 %0, %%zmm2\n\t" + "vmovdqa32 %1, %%zmm3\n\t" + : + : "m"(a), "m"(b)); + + asm volatile("vpmultishiftqb %zmm3, %zmm2, %zmm1"); + + asm volatile("vmovdqa32 %%zmm1,%0" : : "m"(c)); +} + +void usage(void) +{ + printf("Usage: [Num1] [Num2] [b]\n"); + printf(" Num1 Hex number for zmm2\n"); + printf(" Num2 Hex number for zmm3\n"); + printf(" b Test vbmi\n"); +} + +int main(int argc, char *argv[]) +{ + unsigned int r1, r2, p1, i; + char feature; + + if (argc == 4) { + if (sscanf(argv[1], "%x", &r1) != 1) { + printf("Invalid argv[1]: %s\n", argv[1]); + return 2; + } + if (sscanf(argv[2], "%x", &r2) != 1) { + printf("Invalid argv[2]: %s\n", argv[2]); + return 2; + } + if (sscanf(argv[3], "%c", &feature) != 1) { + printf("Invalid argv[3]: %s\n", argv[3]); + return 2; + } + printf("r1(zmm2):%d, r2(zmm3):%d, feature: %c\n", + r1, r2, feature); + switch (feature) { + case 'b': + printf("vbmi:\n"); + vbmi(r1, r2); + pp1[0] = c; + printf("Test vpmultishiftqb results:\n"); + printf("Result c size : %zu bytes\n", sizeof(c)); + + for (i = 0; i < 4; i++) { + printf("pp1[%d]:%-24lx|", i, pp1[i]); + h_to_b(pp1[i], N); + printf("\n"); + } + break; + default: + usage(); + exit(1); + } + } else { + usage(); + exit(1); + } + return 0; +} diff --git a/README.md b/README.md index b4cb9268..72476634 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ More details please refer to following. ## BM Features * [AMX](BM/amx/README.md) + * [avx512vbmi](BM/avx512vbmi/README.md) * [cet(Control flow Enhancement Technology)](BM/cet/README.md) * [cstate](BM/cstate/README.md) * [DSA](BM/dsa/README.md)