From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-yw1-x1130.google.com (mail-yw1-x1130.google.com [IPv6:2607:f8b0:4864:20::1130]) by sourceware.org (Postfix) with ESMTPS id 089683858D28 for ; Fri, 19 Aug 2022 00:56:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 089683858D28 Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-333b049f231so85560467b3.1 for ; Thu, 18 Aug 2022 17:56:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc; bh=UJ8Bq/p7Fw4I9IZIOsY7lukEafUSr2fucBv/7lNMSL4=; b=WQM8lJZseBgQF89IN07+PvHbgngSDj5YvyEMkCri5GG3rmKP7eLp7b6oLn7FAIBr7R XbUqcfm7gZ2ve5GgOGT0FAyJvpz+qIOPXhJktmWKH3M8JHMfdTdel/XlZWHsmqJWn9MD fjLhfq4qIngtlB/vl7JNGQfqKlNjztRhSWmkn3Y75JXajfx2q4YqjsOHYTIQpez02UoA J22s70sDNgPyuUtSLISfnWev65X6tNfHzMQgQxI5NetRq2nC9Azx6ZjqDvjJpBZSLDgl 6QOxAceR+7iVQMGKyMjaLNQzo62HL4udpDrbkBiUwHJs+aXyIsSMWeAF9G7gbuncW+cw 2QGQ== X-Gm-Message-State: ACgBeo3wGk8PRYomQMGK7Tr8YVH3ZsNjprs88J0biLaDg8h7xk0D9gNS v0b+NzmmDXADpBvNMGtUymbxh86+Yoilu3O1qmSKSjUFTeY= X-Google-Smtp-Source: AA6agR7uBSNDcQr0g5+urqQpcvqjj9WkdCYgBnzCQbZEg74cAiXTR0oc6e9zOkkWUZ6k/5BySZt1Gsih0RNdI6t2pPw= X-Received: by 2002:a81:1087:0:b0:334:371e:4fd0 with SMTP id 129-20020a811087000000b00334371e4fd0mr5465212ywq.186.1660870564482; Thu, 18 Aug 2022 17:56:04 -0700 (PDT) MIME-Version: 1.0 References: <20220818073405.5527-1-haochen.jiang@intel.com> In-Reply-To: <20220818073405.5527-1-haochen.jiang@intel.com> From: Hongtao Liu Date: Fri, 19 Aug 2022 08:58:13 +0800 Message-ID: Subject: Re: [PATCH] Add ABI test for __bf16 type To: Haochen Jiang Cc: gcc-patches@gcc.gnu.org, hongtao.liu@intel.com Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SCC_5_SHORT_WORD_LINES, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Aug 2022 00:56:19 -0000 On Thu, Aug 18, 2022 at 3:36 PM Haochen Jiang via Gcc-patches wrote: > > Hi all, > > This patch aims to add bf16 abi test after the whole __bf16 type is added. > > Regtested on x86_64-pc-linux-gnu. Ok for trunk? Ok. > > BRs, > Haochen > > gcc/testsuite/ChangeLog: > > * gcc.target/x86_64/abi/bf16/abi-bf16.exp: New test. > * gcc.target/x86_64/abi/bf16/args.h: Ditto. > * gcc.target/x86_64/abi/bf16/asm-support.S: Ditto. > * gcc.target/x86_64/abi/bf16/bf16-check.h: Ditto. > * gcc.target/x86_64/abi/bf16/bf16-helper.h: Ditto. > * gcc.target/x86_64/abi/bf16/defines.h: Ditto. > * gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp: Ditto. > * gcc.target/x86_64/abi/bf16/m256bf16/args.h: Ditto. > * gcc.target/x86_64/abi/bf16/m256bf16/asm-support.S: Ditto. > * gcc.target/x86_64/abi/bf16/m256bf16/bf16-ymm-check.h: Ditto. > * gcc.target/x86_64/abi/bf16/m256bf16/test_m256_returning.c: Ditto. > * gcc.target/x86_64/abi/bf16/m256bf16/test_passing_m256.c: Ditto. > * gcc.target/x86_64/abi/bf16/m256bf16/test_passing_structs.c: Ditto. > * gcc.target/x86_64/abi/bf16/m256bf16/test_passing_unions.c: Ditto. > * gcc.target/x86_64/abi/bf16/m256bf16/test_varargs-m256.c: Ditto. > * gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp: Ditto. > * gcc.target/x86_64/abi/bf16/m512bf16/args.h: Ditto. > * gcc.target/x86_64/abi/bf16/m512bf16/asm-support.S: Ditto. > * gcc.target/x86_64/abi/bf16/m512bf16/bf16-zmm-check.h: Ditto. > * gcc.target/x86_64/abi/bf16/m512bf16/test_m512_returning.c: Ditto. > * gcc.target/x86_64/abi/bf16/m512bf16/test_passing_m512.c: Ditto. > * gcc.target/x86_64/abi/bf16/m512bf16/test_passing_structs.c: Ditto. > * gcc.target/x86_64/abi/bf16/m512bf16/test_passing_unions.c: Ditto. > * gcc.target/x86_64/abi/bf16/m512bf16/test_varargs-m512.c: Ditto. > * gcc.target/x86_64/abi/bf16/macros.h: Ditto. > * gcc.target/x86_64/abi/bf16/test_3_element_struct_and_unions.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_basic_alignment.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_basic_array_size_and_align.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_basic_returning.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_basic_sizes.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_basic_struct_size_and_align.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_basic_union_size_and_align.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_m128_returning.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_passing_floats.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_passing_m128.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_passing_structs.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_passing_unions.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_struct_returning.c: Ditto. > * gcc.target/x86_64/abi/bf16/test_varargs-m128.c: Ditto. > --- > .../gcc.target/x86_64/abi/bf16/abi-bf16.exp | 46 +++ > .../gcc.target/x86_64/abi/bf16/args.h | 164 +++++++++ > .../gcc.target/x86_64/abi/bf16/asm-support.S | 84 +++++ > .../gcc.target/x86_64/abi/bf16/bf16-check.h | 24 ++ > .../gcc.target/x86_64/abi/bf16/bf16-helper.h | 41 +++ > .../gcc.target/x86_64/abi/bf16/defines.h | 163 +++++++++ > .../x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp | 46 +++ > .../x86_64/abi/bf16/m256bf16/args.h | 152 +++++++++ > .../x86_64/abi/bf16/m256bf16/asm-support.S | 84 +++++ > .../x86_64/abi/bf16/m256bf16/bf16-ymm-check.h | 24 ++ > .../abi/bf16/m256bf16/test_m256_returning.c | 38 +++ > .../abi/bf16/m256bf16/test_passing_m256.c | 235 +++++++++++++ > .../abi/bf16/m256bf16/test_passing_structs.c | 69 ++++ > .../abi/bf16/m256bf16/test_passing_unions.c | 179 ++++++++++ > .../abi/bf16/m256bf16/test_varargs-m256.c | 107 ++++++ > .../x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp | 46 +++ > .../x86_64/abi/bf16/m512bf16/args.h | 155 +++++++++ > .../x86_64/abi/bf16/m512bf16/asm-support.S | 100 ++++++ > .../x86_64/abi/bf16/m512bf16/bf16-zmm-check.h | 23 ++ > .../abi/bf16/m512bf16/test_m512_returning.c | 44 +++ > .../abi/bf16/m512bf16/test_passing_m512.c | 243 ++++++++++++++ > .../abi/bf16/m512bf16/test_passing_structs.c | 77 +++++ > .../abi/bf16/m512bf16/test_passing_unions.c | 222 +++++++++++++ > .../abi/bf16/m512bf16/test_varargs-m512.c | 111 +++++++ > .../gcc.target/x86_64/abi/bf16/macros.h | 53 +++ > .../bf16/test_3_element_struct_and_unions.c | 214 ++++++++++++ > .../x86_64/abi/bf16/test_basic_alignment.c | 14 + > .../bf16/test_basic_array_size_and_align.c | 13 + > .../x86_64/abi/bf16/test_basic_returning.c | 20 ++ > .../x86_64/abi/bf16/test_basic_sizes.c | 14 + > .../bf16/test_basic_struct_size_and_align.c | 14 + > .../bf16/test_basic_union_size_and_align.c | 12 + > .../x86_64/abi/bf16/test_m128_returning.c | 38 +++ > .../x86_64/abi/bf16/test_passing_floats.c | 312 ++++++++++++++++++ > .../x86_64/abi/bf16/test_passing_m128.c | 238 +++++++++++++ > .../x86_64/abi/bf16/test_passing_structs.c | 67 ++++ > .../x86_64/abi/bf16/test_passing_unions.c | 160 +++++++++ > .../x86_64/abi/bf16/test_struct_returning.c | 176 ++++++++++ > .../x86_64/abi/bf16/test_varargs-m128.c | 111 +++++++ > 39 files changed, 3933 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/abi-bf16.exp > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/args.h > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/asm-support.S > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/bf16-check.h > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/bf16-helper.h > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/defines.h > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/args.h > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/asm-support.S > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/bf16-ymm-check.h > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_m256_returning.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_m256.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_structs.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_unions.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_varargs-m256.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/args.h > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/asm-support.S > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/bf16-zmm-check.h > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_m512_returning.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_m512.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_structs.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_unions.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_varargs-m512.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/macros.h > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_3_element_struct_and_unions.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_alignment.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_array_size_and_align.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_returning.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_sizes.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_struct_size_and_align.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_union_size_and_align.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_m128_returning.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_floats.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_m128.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_structs.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_unions.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_struct_returning.c > create mode 100644 gcc/testsuite/gcc.target/x86_64/abi/bf16/test_varargs-m128.c > > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/abi-bf16.exp b/gcc/testsuite/gcc.target/x86_64/abi/bf16/abi-bf16.exp > new file mode 100644 > index 00000000000..bd386f2a560 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/abi-bf16.exp > @@ -0,0 +1,46 @@ > +# Copyright (C) 2022 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with GCC; see the file COPYING3. If not see > +# . > + > +# The x86-64 ABI testsuite needs one additional assembler file for most > +# testcases. For simplicity we will just link it into each test. > + > +load_lib c-torture.exp > +load_lib target-supports.exp > +load_lib torture-options.exp > +load_lib clearcap.exp > + > +if { (![istarget x86_64-*-*] && ![istarget i?86-*-*]) > + || ![is-effective-target lp64] > + || ![is-effective-target sse2] } then { > + return > +} > + > + > +torture-init > +clearcap-init > +set-torture-options $C_TORTURE_OPTIONS > +set additional_flags "-W -Wall -msse2" > + > +foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] { > + if {[runtest_file_p $runtests $src]} { > + c-torture-execute [list $src \ > + $srcdir/$subdir/asm-support.S] \ > + $additional_flags > + } > +} > + > +clearcap-finish > +torture-finish > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/args.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/args.h > new file mode 100644 > index 00000000000..11d7e2b3a1c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/args.h > @@ -0,0 +1,164 @@ > +#ifndef INCLUDED_ARGS_H > +#define INCLUDED_ARGS_H > + > +#include > + > +/* This defines the calling sequences for integers and floats. */ > +#define I0 rdi > +#define I1 rsi > +#define I2 rdx > +#define I3 rcx > +#define I4 r8 > +#define I5 r9 > +#define F0 xmm0 > +#define F1 xmm1 > +#define F2 xmm2 > +#define F3 xmm3 > +#define F4 xmm4 > +#define F5 xmm5 > +#define F6 xmm6 > +#define F7 xmm7 > + > +typedef union { > + __bf16 ___bf16[8]; > + float _float[4]; > + double _double[2]; > + long long _longlong[2]; > + int _int[4]; > + ulonglong _ulonglong[2]; > +#ifdef CHECK_M64_M128 > + __m64 _m64[2]; > + __m128 _m128[1]; > + __m128bf16 _m128bf16[1]; > +#endif > +} XMM_T; > + > +typedef union { > + __bf16 ___bf16; > + float _float; > + double _double; > + ldouble _ldouble; > + ulonglong _ulonglong[2]; > +} X87_T; > +extern void (*callthis)(void); > +extern unsigned long long rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15; > +XMM_T xmm_regs[16]; > +X87_T x87_regs[8]; > +extern volatile unsigned long long volatile_var; > +extern void snapshot (void); > +extern void snapshot_ret (void); > +#define WRAP_CALL(N) \ > + (callthis = (void (*)()) (N), (typeof (&N)) snapshot) > +#define WRAP_RET(N) \ > + (callthis = (void (*)()) (N), (typeof (&N)) snapshot_ret) > + > +/* Clear all integer registers. */ > +#define clear_int_hardware_registers \ > + asm __volatile__ ("xor %%rax, %%rax\n\t" \ > + "xor %%rbx, %%rbx\n\t" \ > + "xor %%rcx, %%rcx\n\t" \ > + "xor %%rdx, %%rdx\n\t" \ > + "xor %%rsi, %%rsi\n\t" \ > + "xor %%rdi, %%rdi\n\t" \ > + "xor %%r8, %%r8\n\t" \ > + "xor %%r9, %%r9\n\t" \ > + "xor %%r10, %%r10\n\t" \ > + "xor %%r11, %%r11\n\t" \ > + "xor %%r12, %%r12\n\t" \ > + "xor %%r13, %%r13\n\t" \ > + "xor %%r14, %%r14\n\t" \ > + "xor %%r15, %%r15\n\t" \ > + ::: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", \ > + "r9", "r10", "r11", "r12", "r13", "r14", "r15"); > + > +/* This is the list of registers available for passing arguments. Not all of > + these are used or even really available. */ > +struct IntegerRegisters > +{ > + unsigned long long rax, rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15; > +}; > +struct FloatRegisters > +{ > + double mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7; > + ldouble st0, st1, st2, st3, st4, st5, st6, st7; > + XMM_T xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, > + xmm10, xmm11, xmm12, xmm13, xmm14, xmm15; > +}; > + > +/* Implemented in scalarargs.c */ > +extern struct IntegerRegisters iregs; > +extern struct FloatRegisters fregs; > +extern unsigned int num_iregs, num_fregs; > + > +/* Clear register struct. */ > +#define clear_struct_registers \ > + rax = rbx = rcx = rdx = rdi = rsi = rbp = rsp \ > + = r8 = r9 = r10 = r11 = r12 = r13 = r14 = r15 = 0; \ > + memset (&iregs, 0, sizeof (iregs)); \ > + memset (&fregs, 0, sizeof (fregs)); \ > + memset (xmm_regs, 0, sizeof (xmm_regs)); \ > + memset (x87_regs, 0, sizeof (x87_regs)); > + > +/* Clear both hardware and register structs for integers. */ > +#define clear_int_registers \ > + clear_struct_registers \ > + clear_int_hardware_registers > + > +/* Do the checking. */ > +#define check_f_arguments(T) do { \ > + assert (num_fregs <= 0 || check_bf16 (fregs.xmm0._ ## T [0], xmm_regs[0]._ ## T [0]) == 1); \ > + assert (num_fregs <= 1 || check_bf16 (fregs.xmm1._ ## T [0], xmm_regs[1]._ ## T [0]) == 1); \ > + assert (num_fregs <= 2 || check_bf16 (fregs.xmm2._ ## T [0], xmm_regs[2]._ ## T [0]) == 1); \ > + assert (num_fregs <= 3 || check_bf16 (fregs.xmm3._ ## T [0], xmm_regs[3]._ ## T [0]) == 1); \ > + assert (num_fregs <= 4 || check_bf16 (fregs.xmm4._ ## T [0], xmm_regs[4]._ ## T [0]) == 1); \ > + assert (num_fregs <= 5 || check_bf16 (fregs.xmm5._ ## T [0], xmm_regs[5]._ ## T [0]) == 1); \ > + assert (num_fregs <= 6 || check_bf16 (fregs.xmm6._ ## T [0], xmm_regs[6]._ ## T [0]) == 1); \ > + assert (num_fregs <= 7 || check_bf16 (fregs.xmm7._ ## T [0], xmm_regs[7]._ ## T [0]) == 1); \ > + } while (0) > + > +#define check_bf16_arguments check_f_arguments(__bf16) > + > +#define check_vector_arguments(T,O) do { \ > + assert (num_fregs <= 0 \ > + || memcmp (((char *) &fregs.xmm0) + (O), \ > + &xmm_regs[0], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 1 \ > + || memcmp (((char *) &fregs.xmm1) + (O), \ > + &xmm_regs[1], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 2 \ > + || memcmp (((char *) &fregs.xmm2) + (O), \ > + &xmm_regs[2], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 3 \ > + || memcmp (((char *) &fregs.xmm3) + (O), \ > + &xmm_regs[3], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 4 \ > + || memcmp (((char *) &fregs.xmm4) + (O), \ > + &xmm_regs[4], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 5 \ > + || memcmp (((char *) &fregs.xmm5) + (O), \ > + &xmm_regs[5], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 6 \ > + || memcmp (((char *) &fregs.xmm6) + (O), \ > + &xmm_regs[6], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 7 \ > + || memcmp (((char *) &fregs.xmm7) + (O), \ > + &xmm_regs[7], \ > + sizeof (__ ## T) - (O)) == 0); \ > + } while (0) > + > +#define check_m128_arguments check_vector_arguments(m128, 0) > + > +#define clear_float_registers \ > + clear_struct_registers > + > +#define clear_x87_registers \ > + clear_struct_registers > + > +#endif /* INCLUDED_ARGS_H */ > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/bf16/asm-support.S > new file mode 100644 > index 00000000000..a8165d86317 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/asm-support.S > @@ -0,0 +1,84 @@ > + .text > + .p2align 4,,15 > +.globl snapshot > + .type snapshot, @function > +snapshot: > +.LFB3: > + movq %rax, rax(%rip) > + movq %rbx, rbx(%rip) > + movq %rcx, rcx(%rip) > + movq %rdx, rdx(%rip) > + movq %rdi, rdi(%rip) > + movq %rsi, rsi(%rip) > + movq %rbp, rbp(%rip) > + movq %rsp, rsp(%rip) > + movq %r8, r8(%rip) > + movq %r9, r9(%rip) > + movq %r10, r10(%rip) > + movq %r11, r11(%rip) > + movq %r12, r12(%rip) > + movq %r13, r13(%rip) > + movq %r14, r14(%rip) > + movq %r15, r15(%rip) > + vmovdqu %xmm0, xmm_regs+0(%rip) > + vmovdqu %xmm1, xmm_regs+16(%rip) > + vmovdqu %xmm2, xmm_regs+32(%rip) > + vmovdqu %xmm3, xmm_regs+48(%rip) > + vmovdqu %xmm4, xmm_regs+64(%rip) > + vmovdqu %xmm5, xmm_regs+80(%rip) > + vmovdqu %xmm6, xmm_regs+96(%rip) > + vmovdqu %xmm7, xmm_regs+112(%rip) > + vmovdqu %xmm8, xmm_regs+128(%rip) > + vmovdqu %xmm9, xmm_regs+144(%rip) > + vmovdqu %xmm10, xmm_regs+160(%rip) > + vmovdqu %xmm11, xmm_regs+176(%rip) > + vmovdqu %xmm12, xmm_regs+192(%rip) > + vmovdqu %xmm13, xmm_regs+208(%rip) > + vmovdqu %xmm14, xmm_regs+224(%rip) > + vmovdqu %xmm15, xmm_regs+240(%rip) > + jmp *callthis(%rip) > +.LFE3: > + .size snapshot, .-snapshot > + > + .p2align 4,,15 > +.globl snapshot_ret > + .type snapshot_ret, @function > +snapshot_ret: > + movq %rdi, rdi(%rip) > + subq $8, %rsp > + call *callthis(%rip) > + addq $8, %rsp > + movq %rax, rax(%rip) > + movq %rdx, rdx(%rip) > + vmovdqu %xmm0, xmm_regs+0(%rip) > + vmovdqu %xmm1, xmm_regs+16(%rip) > + fstpt x87_regs(%rip) > + fstpt x87_regs+16(%rip) > + fldt x87_regs+16(%rip) > + fldt x87_regs(%rip) > + ret > + .size snapshot_ret, .-snapshot_ret > + > + .comm callthis,8,8 > + .comm rax,8,8 > + .comm rbx,8,8 > + .comm rcx,8,8 > + .comm rdx,8,8 > + .comm rsi,8,8 > + .comm rdi,8,8 > + .comm rsp,8,8 > + .comm rbp,8,8 > + .comm r8,8,8 > + .comm r9,8,8 > + .comm r10,8,8 > + .comm r11,8,8 > + .comm r12,8,8 > + .comm r13,8,8 > + .comm r14,8,8 > + .comm r15,8,8 > + .comm xmm_regs,256,32 > + .comm x87_regs,128,32 > + .comm volatile_var,8,8 > +#ifdef __linux__ > + .section .note.GNU-stack,"",@progbits > +#endif > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/bf16-check.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/bf16-check.h > new file mode 100644 > index 00000000000..25448fc6863 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/bf16-check.h > @@ -0,0 +1,24 @@ > +#include > +#include "bf16-helper.h" > + > +static void do_test (void); > + > +int > +main () > +{ > + > + if (__builtin_cpu_supports ("sse2")) > + { > + do_test (); > +#ifdef DEBUG > + printf ("PASSED\n"); > +#endif > + return 0; > + } > + > +#ifdef DEBUG > + printf ("SKIPPED\n"); > +#endif > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/bf16-helper.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/bf16-helper.h > new file mode 100644 > index 00000000000..83d89fcf62c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/bf16-helper.h > @@ -0,0 +1,41 @@ > +typedef union > +{ > + float f; > + unsigned int u; > + __bf16 b[2]; > +} unionf_b; > + > +static __bf16 make_f32_bf16 (float f) > +{ > + unionf_b tmp; > + tmp.f = f; > + return tmp.b[1]; > +} > + > +static float make_bf16_f32 (__bf16 bf) > +{ > + unionf_b tmp; > + tmp.u = 0; > + tmp.b[1] = bf; > + return tmp.f; > +} > + > +static int check_bf16 (__bf16 bf1, __bf16 bf2) > +{ > + unionf_b tmp1, tmp2; > + tmp1.u = 0; > + tmp2.u = 0; > + tmp1.b[1] = bf1; > + tmp2.b[1] = bf2; > + return (tmp1.u == tmp2.u); > +} > + > +static int check_bf16_float (__bf16 bf, float f) > +{ > + unionf_b tmp1, tmp2; > + tmp1.u = 0; > + tmp1.b[0] = bf; > + tmp2.f = f; > + tmp2.u >>= 16; > + return (tmp1.u == tmp2.u); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/defines.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/defines.h > new file mode 100644 > index 00000000000..a4df0b0528d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/defines.h > @@ -0,0 +1,163 @@ > +#ifndef DEFINED_DEFINES_H > +#define DEFINED_DEFINES_H > + > +/* Get __m64 and __m128. */ > +#include > + > +typedef unsigned long long ulonglong; > +typedef long double ldouble; > + > +/* These defines determines what part of the test should be run. When > + GCC implements these parts, the defines should be uncommented to > + enable testing. */ > + > +/* Scalar type __int128. */ > +/* #define CHECK_INT128 */ > + > +/* Scalar type long double. */ > +#define CHECK_LONG_DOUBLE > + > +/* Scalar type __float128. */ > +/* #define CHECK_FLOAT128 */ > + > +/* Scalar types __m64 and __m128. */ > +#define CHECK_M64_M128 > + > +/* Structs with size >= 16. */ > +#define CHECK_LARGER_STRUCTS > + > +/* Checks for passing floats and doubles. */ > +#define CHECK_FLOAT_DOUBLE_PASSING > + > +/* Union passing with not-extremely-simple unions. */ > +#define CHECK_LARGER_UNION_PASSING > + > +/* Variable args. */ > +#define CHECK_VARARGS > + > +/* Check argument passing and returning for scalar types with sizeof = 16. */ > +/* TODO: Implement these tests. Don't activate them for now. */ > +#define CHECK_LARGE_SCALAR_PASSING > + > +/* Defines for sizing and alignment. */ > + > +#define TYPE_SIZE_CHAR 1 > +#define TYPE_SIZE_SHORT 2 > +#define TYPE_SIZE_INT 4 > +#ifdef __ILP32__ > +# define TYPE_SIZE_LONG 4 > +#else > +# define TYPE_SIZE_LONG 8 > +#endif > +#define TYPE_SIZE_LONG_LONG 8 > +#define TYPE_SIZE_INT128 16 > +#define TYPE_SIZE_BF16 2 > +#define TYPE_SIZE_FLOAT 4 > +#define TYPE_SIZE_DOUBLE 8 > +#define TYPE_SIZE_LONG_DOUBLE 16 > +#define TYPE_SIZE_FLOAT128 16 > +#define TYPE_SIZE_M64 8 > +#define TYPE_SIZE_M128 16 > +#define TYPE_SIZE_ENUM 4 > +#ifdef __ILP32__ > +# define TYPE_SIZE_POINTER 4 > +#else > +# define TYPE_SIZE_POINTER 8 > +#endif > + > +#define TYPE_ALIGN_CHAR 1 > +#define TYPE_ALIGN_SHORT 2 > +#define TYPE_ALIGN_INT 4 > +#ifdef __ILP32__ > +# define TYPE_ALIGN_LONG 4 > +#else > +# define TYPE_ALIGN_LONG 8 > +#endif > +#define TYPE_ALIGN_LONG_LONG 8 > +#define TYPE_ALIGN_INT128 16 > +#define TYPE_ALIGN_BF16 2 > +#define TYPE_ALIGN_FLOAT 4 > +#define TYPE_ALIGN_DOUBLE 8 > +#define TYPE_ALIGN_LONG_DOUBLE 16 > +#define TYPE_ALIGN_FLOAT128 16 > +#define TYPE_ALIGN_M64 8 > +#define TYPE_ALIGN_M128 16 > +#define TYPE_ALIGN_ENUM 4 > +#ifdef __ILP32__ > +# define TYPE_ALIGN_POINTER 4 > +#else > +# define TYPE_ALIGN_POINTER 8 > +#endif > + > +/* These defines control the building of the list of types to check. There > + is a string identifying the type (with a comma after), a size of the type > + (also with a comma and an integer for adding to the total amount of types) > + and an alignment of the type (which is currently not really needed since > + the abi specifies that alignof == sizeof for all scalar types). */ > +#ifdef CHECK_INT128 > +#define CI128_STR "__int128", > +#define CI128_SIZ TYPE_SIZE_INT128, > +#define CI128_ALI TYPE_ALIGN_INT128, > +#define CI128_RET "???", > +#else > +#define CI128_STR > +#define CI128_SIZ > +#define CI128_ALI > +#define CI128_RET > +#endif > +#ifdef CHECK_LONG_DOUBLE > +#define CLD_STR "long double", > +#define CLD_SIZ TYPE_SIZE_LONG_DOUBLE, > +#define CLD_ALI TYPE_ALIGN_LONG_DOUBLE, > +#define CLD_RET "x87_regs[0]._ldouble", > +#else > +#define CLD_STR > +#define CLD_SIZ > +#define CLD_ALI > +#define CLD_RET > +#endif > +#ifdef CHECK_FLOAT128 > +#define CF128_STR "__float128", > +#define CF128_SIZ TYPE_SIZE_FLOAT128, > +#define CF128_ALI TYPE_ALIGN_FLOAT128, > +#define CF128_RET "???", > +#else > +#define CF128_STR > +#define CF128_SIZ > +#define CF128_ALI > +#define CF128_RET > +#endif > +#ifdef CHECK_M64_M128 > +#define CMM_STR "__m64", "__m128", > +#define CMM_SIZ TYPE_SIZE_M64, TYPE_SIZE_M128, > +#define CMM_ALI TYPE_ALIGN_M64, TYPE_ALIGN_M128, > +#define CMM_RET "???", "???", > +#else > +#define CMM_STR > +#define CMM_SIZ > +#define CMM_ALI > +#define CMM_RET > +#endif > + > +/* Used in size and alignment tests. */ > +enum dummytype { enumtype }; > + > +extern void abort (void); > + > +/* Assertion macro. */ > +#define assert(test) if (!(test)) abort() > + > +#ifdef __GNUC__ > +#define ATTRIBUTE_UNUSED __attribute__((__unused__)) > +#else > +#define ATTRIBUTE_UNUSED > +#endif > + > +#ifdef __GNUC__ > +#define PACKED __attribute__((__packed__)) > +#else > +#warning Some tests will fail due to missing __packed__ support > +#define PACKED > +#endif > + > +#endif /* DEFINED_DEFINES_H */ > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp > new file mode 100644 > index 00000000000..309db8ff12e > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp > @@ -0,0 +1,46 @@ > +# Copyright (C) 2022 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with GCC; see the file COPYING3. If not see > +# . > + > +# The x86-64 ABI testsuite needs one additional assembler file for most > +# testcases. For simplicity we will just link it into each test. > + > +load_lib c-torture.exp > +load_lib target-supports.exp > +load_lib torture-options.exp > +load_lib clearcap.exp > + > +if { (![istarget x86_64-*-*] && ![istarget i?86-*-*]) > + || ![is-effective-target lp64] > + || ![is-effective-target avx2] } then { > + return > +} > + > + > +torture-init > +clearcap-init > +set-torture-options $C_TORTURE_OPTIONS > +set additional_flags "-W -Wall -mavx2" > + > +foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] { > + if {[runtest_file_p $runtests $src]} { > + c-torture-execute [list $src \ > + $srcdir/$subdir/asm-support.S] \ > + $additional_flags > + } > +} > + > +clearcap-finish > +torture-finish > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/args.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/args.h > new file mode 100644 > index 00000000000..94627ffbd44 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/args.h > @@ -0,0 +1,152 @@ > +#ifndef INCLUDED_ARGS_H > +#define INCLUDED_ARGS_H > + > +#include > +#include > + > +/* Assertion macro. */ > +#define assert(test) if (!(test)) abort() > + > +#ifdef __GNUC__ > +#define ATTRIBUTE_UNUSED __attribute__((__unused__)) > +#else > +#define ATTRIBUTE_UNUSED > +#endif > + > +/* This defines the calling sequences for integers and floats. */ > +#define I0 rdi > +#define I1 rsi > +#define I2 rdx > +#define I3 rcx > +#define I4 r8 > +#define I5 r9 > +#define F0 ymm0 > +#define F1 ymm1 > +#define F2 ymm2 > +#define F3 ymm3 > +#define F4 ymm4 > +#define F5 ymm5 > +#define F6 ymm6 > +#define F7 ymm7 > + > +typedef union { > + __bf16 ___bf16[16]; > + float _float[8]; > + double _double[4]; > + long long _longlong[4]; > + int _int[8]; > + unsigned long long _ulonglong[4]; > + __m64 _m64[4]; > + __m128 _m128[2]; > + __m256 _m256[1]; > + __m256bf16 _m256bf16[1]; > +} YMM_T; > + > +typedef union { > + float _float; > + double _double; > + long double _ldouble; > + unsigned long long _ulonglong[2]; > +} X87_T; > +extern void (*callthis)(void); > +extern unsigned long long rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15; > +YMM_T ymm_regs[16]; > +X87_T x87_regs[8]; > +extern volatile unsigned long long volatile_var; > +extern void snapshot (void); > +extern void snapshot_ret (void); > +#define WRAP_CALL(N) \ > + (callthis = (void (*)()) (N), (typeof (&N)) snapshot) > +#define WRAP_RET(N) \ > + (callthis = (void (*)()) (N), (typeof (&N)) snapshot_ret) > + > +/* Clear all integer registers. */ > +#define clear_int_hardware_registers \ > + asm __volatile__ ("xor %%rax, %%rax\n\t" \ > + "xor %%rbx, %%rbx\n\t" \ > + "xor %%rcx, %%rcx\n\t" \ > + "xor %%rdx, %%rdx\n\t" \ > + "xor %%rsi, %%rsi\n\t" \ > + "xor %%rdi, %%rdi\n\t" \ > + "xor %%r8, %%r8\n\t" \ > + "xor %%r9, %%r9\n\t" \ > + "xor %%r10, %%r10\n\t" \ > + "xor %%r11, %%r11\n\t" \ > + "xor %%r12, %%r12\n\t" \ > + "xor %%r13, %%r13\n\t" \ > + "xor %%r14, %%r14\n\t" \ > + "xor %%r15, %%r15\n\t" \ > + ::: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", \ > + "r9", "r10", "r11", "r12", "r13", "r14", "r15"); > + > +/* This is the list of registers available for passing arguments. Not all of > + these are used or even really available. */ > +struct IntegerRegisters > +{ > + unsigned long long rax, rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15; > +}; > +struct FloatRegisters > +{ > + double mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7; > + long double st0, st1, st2, st3, st4, st5, st6, st7; > + YMM_T ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, ymm8, ymm9, > + ymm10, ymm11, ymm12, ymm13, ymm14, ymm15; > +}; > + > +/* Implemented in scalarargs.c */ > +extern struct IntegerRegisters iregs; > +extern struct FloatRegisters fregs; > +extern unsigned int num_iregs, num_fregs; > + > +/* Clear register struct. */ > +#define clear_struct_registers \ > + rax = rbx = rcx = rdx = rdi = rsi = rbp = rsp \ > + = r8 = r9 = r10 = r11 = r12 = r13 = r14 = r15 = 0; \ > + memset (&iregs, 0, sizeof (iregs)); \ > + memset (&fregs, 0, sizeof (fregs)); \ > + memset (ymm_regs, 0, sizeof (ymm_regs)); \ > + memset (x87_regs, 0, sizeof (x87_regs)); > + > +/* Clear both hardware and register structs for integers. */ > +#define clear_int_registers \ > + clear_struct_registers \ > + clear_int_hardware_registers > + > +#define check_vector_arguments(T,O) do { \ > + assert (num_fregs <= 0 \ > + || memcmp (((char *) &fregs.ymm0) + (O), \ > + &ymm_regs[0], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 1 \ > + || memcmp (((char *) &fregs.ymm1) + (O), \ > + &ymm_regs[1], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 2 \ > + || memcmp (((char *) &fregs.ymm2) + (O), \ > + &ymm_regs[2], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 3 \ > + || memcmp (((char *) &fregs.ymm3) + (O), \ > + &ymm_regs[3], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 4 \ > + || memcmp (((char *) &fregs.ymm4) + (O), \ > + &ymm_regs[4], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 5 \ > + || memcmp (((char *) &fregs.ymm5) + (O), \ > + &ymm_regs[5], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 6 \ > + || memcmp (((char *) &fregs.ymm6) + (O), \ > + &ymm_regs[6], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 7 \ > + || memcmp (((char *) &fregs.ymm7) + (O), \ > + &ymm_regs[7], \ > + sizeof (__ ## T) - (O)) == 0); \ > + } while (0) > + > +#define check_m256_arguments check_vector_arguments(m256, 0) > + > +#endif /* INCLUDED_ARGS_H */ > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/asm-support.S > new file mode 100644 > index 00000000000..24c8b3c9023 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/asm-support.S > @@ -0,0 +1,84 @@ > + .text > + .p2align 4,,15 > +.globl snapshot > + .type snapshot, @function > +snapshot: > +.LFB3: > + movq %rax, rax(%rip) > + movq %rbx, rbx(%rip) > + movq %rcx, rcx(%rip) > + movq %rdx, rdx(%rip) > + movq %rdi, rdi(%rip) > + movq %rsi, rsi(%rip) > + movq %rbp, rbp(%rip) > + movq %rsp, rsp(%rip) > + movq %r8, r8(%rip) > + movq %r9, r9(%rip) > + movq %r10, r10(%rip) > + movq %r11, r11(%rip) > + movq %r12, r12(%rip) > + movq %r13, r13(%rip) > + movq %r14, r14(%rip) > + movq %r15, r15(%rip) > + vmovdqu %ymm0, ymm_regs+0(%rip) > + vmovdqu %ymm1, ymm_regs+32(%rip) > + vmovdqu %ymm2, ymm_regs+64(%rip) > + vmovdqu %ymm3, ymm_regs+96(%rip) > + vmovdqu %ymm4, ymm_regs+128(%rip) > + vmovdqu %ymm5, ymm_regs+160(%rip) > + vmovdqu %ymm6, ymm_regs+192(%rip) > + vmovdqu %ymm7, ymm_regs+224(%rip) > + vmovdqu %ymm8, ymm_regs+256(%rip) > + vmovdqu %ymm9, ymm_regs+288(%rip) > + vmovdqu %ymm10, ymm_regs+320(%rip) > + vmovdqu %ymm11, ymm_regs+352(%rip) > + vmovdqu %ymm12, ymm_regs+384(%rip) > + vmovdqu %ymm13, ymm_regs+416(%rip) > + vmovdqu %ymm14, ymm_regs+448(%rip) > + vmovdqu %ymm15, ymm_regs+480(%rip) > + jmp *callthis(%rip) > +.LFE3: > + .size snapshot, .-snapshot > + > + .p2align 4,,15 > +.globl snapshot_ret > + .type snapshot_ret, @function > +snapshot_ret: > + movq %rdi, rdi(%rip) > + subq $8, %rsp > + call *callthis(%rip) > + addq $8, %rsp > + movq %rax, rax(%rip) > + movq %rdx, rdx(%rip) > + vmovdqu %ymm0, ymm_regs+0(%rip) > + vmovdqu %ymm1, ymm_regs+32(%rip) > + fstpt x87_regs(%rip) > + fstpt x87_regs+16(%rip) > + fldt x87_regs+16(%rip) > + fldt x87_regs(%rip) > + ret > + .size snapshot_ret, .-snapshot_ret > + > + .comm callthis,8,8 > + .comm rax,8,8 > + .comm rbx,8,8 > + .comm rcx,8,8 > + .comm rdx,8,8 > + .comm rsi,8,8 > + .comm rdi,8,8 > + .comm rsp,8,8 > + .comm rbp,8,8 > + .comm r8,8,8 > + .comm r9,8,8 > + .comm r10,8,8 > + .comm r11,8,8 > + .comm r12,8,8 > + .comm r13,8,8 > + .comm r14,8,8 > + .comm r15,8,8 > + .comm ymm_regs,512,32 > + .comm x87_regs,128,32 > + .comm volatile_var,8,8 > +#ifdef __linux__ > + .section .note.GNU-stack,"",@progbits > +#endif > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/bf16-ymm-check.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/bf16-ymm-check.h > new file mode 100644 > index 00000000000..479ebc3ec3f > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/bf16-ymm-check.h > @@ -0,0 +1,24 @@ > +#include > +#include "../bf16-helper.h" > + > +static void do_test (void); > + > +int > +main () > +{ > + > + if (__builtin_cpu_supports ("avx2")) > + { > + do_test (); > +#ifdef DEBUG > + printf ("PASSED\n"); > +#endif > + return 0; > + } > + > +#ifdef DEBUG > + printf ("SKIPPED\n"); > +#endif > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_m256_returning.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_m256_returning.c > new file mode 100644 > index 00000000000..ea7512850ae > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_m256_returning.c > @@ -0,0 +1,38 @@ > +#include > +#include "bf16-ymm-check.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +volatile __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16; > + > +__m256bf16 > +fun_test_returning___m256bf16 (void) > +{ > + volatile_var++; > + return (__m256bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16}; > +} > + > +__m256bf16 test_256bf16; > + > +static void > +do_test (void) > +{ > + unsigned failed = 0; > + YMM_T ymmt1, ymmt2; > + > + clear_struct_registers; > + test_256bf16 = (__m256bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16}; > + ymmt1._m256bf16[0] = test_256bf16; > + ymmt2._m256bf16[0] = WRAP_RET (fun_test_returning___m256bf16) (); > + if (memcmp (&ymmt1, &ymmt2, sizeof (ymmt2)) != 0) > + printf ("fail m256bf16\n"), failed++; > + > + if (failed) > + abort (); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_m256.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_m256.c > new file mode 100644 > index 00000000000..3fb2d7d20f8 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_m256.c > @@ -0,0 +1,235 @@ > +#include > +#include "bf16-ymm-check.h" > +#include "args.h" > + > +struct IntegerRegisters iregs; > +struct FloatRegisters fregs; > +unsigned int num_iregs, num_fregs; > + > +/* This struct holds values for argument checking. */ > +struct > +{ > + YMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, > + i16, i17, i18, i19, i20, i21, i22, i23; > +} values; > + > +char *pass; > +int failed = 0; > + > +#undef assert > +#define assert(c) do { \ > + if (!(c)) {failed++; printf ("failed %s\n", pass); } \ > +} while (0) > + > +#define compare(X1,X2,T) do { \ > + assert (memcmp (&X1, &X2, sizeof (T)) == 0); \ > +} while (0) > + > +fun_check_passing_m256bf16_8_values (__m256bf16 i0 ATTRIBUTE_UNUSED, > + __m256bf16 i1 ATTRIBUTE_UNUSED, > + __m256bf16 i2 ATTRIBUTE_UNUSED, > + __m256bf16 i3 ATTRIBUTE_UNUSED, > + __m256bf16 i4 ATTRIBUTE_UNUSED, > + __m256bf16 i5 ATTRIBUTE_UNUSED, > + __m256bf16 i6 ATTRIBUTE_UNUSED, > + __m256bf16 i7 ATTRIBUTE_UNUSED) > +{ > + /* Check argument values. */ > + compare (values.i0, i0, __m256bf16); > + compare (values.i1, i1, __m256bf16); > + compare (values.i2, i2, __m256bf16); > + compare (values.i3, i3, __m256bf16); > + compare (values.i4, i4, __m256bf16); > + compare (values.i5, i5, __m256bf16); > + compare (values.i6, i6, __m256bf16); > + compare (values.i7, i7, __m256bf16); > +} > + > +void > +fun_check_passing_m256bf16_8_regs (__m256bf16 i0 ATTRIBUTE_UNUSED, > + __m256bf16 i1 ATTRIBUTE_UNUSED, > + __m256bf16 i2 ATTRIBUTE_UNUSED, > + __m256bf16 i3 ATTRIBUTE_UNUSED, > + __m256bf16 i4 ATTRIBUTE_UNUSED, > + __m256bf16 i5 ATTRIBUTE_UNUSED, > + __m256bf16 i6 ATTRIBUTE_UNUSED, > + __m256bf16 i7 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m256_arguments; > +} > + > +void > +fun_check_passing_m256bf16_20_values (__m256bf16 i0 ATTRIBUTE_UNUSED, > + __m256bf16 i1 ATTRIBUTE_UNUSED, > + __m256bf16 i2 ATTRIBUTE_UNUSED, > + __m256bf16 i3 ATTRIBUTE_UNUSED, > + __m256bf16 i4 ATTRIBUTE_UNUSED, > + __m256bf16 i5 ATTRIBUTE_UNUSED, > + __m256bf16 i6 ATTRIBUTE_UNUSED, > + __m256bf16 i7 ATTRIBUTE_UNUSED, > + __m256bf16 i8 ATTRIBUTE_UNUSED, > + __m256bf16 i9 ATTRIBUTE_UNUSED, > + __m256bf16 i10 ATTRIBUTE_UNUSED, > + __m256bf16 i11 ATTRIBUTE_UNUSED, > + __m256bf16 i12 ATTRIBUTE_UNUSED, > + __m256bf16 i13 ATTRIBUTE_UNUSED, > + __m256bf16 i14 ATTRIBUTE_UNUSED, > + __m256bf16 i15 ATTRIBUTE_UNUSED, > + __m256bf16 i16 ATTRIBUTE_UNUSED, > + __m256bf16 i17 ATTRIBUTE_UNUSED, > + __m256bf16 i18 ATTRIBUTE_UNUSED, > + __m256bf16 i19 ATTRIBUTE_UNUSED) > +{ > + /* Check argument values. */ > + compare (values.i0, i0, __m256bf16); > + compare (values.i1, i1, __m256bf16); > + compare (values.i2, i2, __m256bf16); > + compare (values.i3, i3, __m256bf16); > + compare (values.i4, i4, __m256bf16); > + compare (values.i5, i5, __m256bf16); > + compare (values.i6, i6, __m256bf16); > + compare (values.i7, i7, __m256bf16); > + compare (values.i8, i8, __m256bf16); > + compare (values.i9, i9, __m256bf16); > + compare (values.i10, i10, __m256bf16); > + compare (values.i11, i11, __m256bf16); > + compare (values.i12, i12, __m256bf16); > + compare (values.i13, i13, __m256bf16); > + compare (values.i14, i14, __m256bf16); > + compare (values.i15, i15, __m256bf16); > + compare (values.i16, i16, __m256bf16); > + compare (values.i17, i17, __m256bf16); > + compare (values.i18, i18, __m256bf16); > + compare (values.i19, i19, __m256bf16); > +} > + > +void > +fun_check_passing_m256bf16_20_regs (__m256bf16 i0 ATTRIBUTE_UNUSED, > + __m256bf16 i1 ATTRIBUTE_UNUSED, > + __m256bf16 i2 ATTRIBUTE_UNUSED, > + __m256bf16 i3 ATTRIBUTE_UNUSED, > + __m256bf16 i4 ATTRIBUTE_UNUSED, > + __m256bf16 i5 ATTRIBUTE_UNUSED, > + __m256bf16 i6 ATTRIBUTE_UNUSED, > + __m256bf16 i7 ATTRIBUTE_UNUSED, > + __m256bf16 i8 ATTRIBUTE_UNUSED, > + __m256bf16 i9 ATTRIBUTE_UNUSED, > + __m256bf16 i10 ATTRIBUTE_UNUSED, > + __m256bf16 i11 ATTRIBUTE_UNUSED, > + __m256bf16 i12 ATTRIBUTE_UNUSED, > + __m256bf16 i13 ATTRIBUTE_UNUSED, > + __m256bf16 i14 ATTRIBUTE_UNUSED, > + __m256bf16 i15 ATTRIBUTE_UNUSED, > + __m256bf16 i16 ATTRIBUTE_UNUSED, > + __m256bf16 i17 ATTRIBUTE_UNUSED, > + __m256bf16 i18 ATTRIBUTE_UNUSED, > + __m256bf16 i19 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m256_arguments; > +} > + > +#define def_check_passing8(_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _func1, _func2, TYPE) \ > + values.i0.TYPE[0] = _i0; \ > + values.i1.TYPE[0] = _i1; \ > + values.i2.TYPE[0] = _i2; \ > + values.i3.TYPE[0] = _i3; \ > + values.i4.TYPE[0] = _i4; \ > + values.i5.TYPE[0] = _i5; \ > + values.i6.TYPE[0] = _i6; \ > + values.i7.TYPE[0] = _i7; \ > + WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7); \ > + clear_struct_registers; \ > + fregs.F0.TYPE[0] = _i0; \ > + fregs.F1.TYPE[0] = _i1; \ > + fregs.F2.TYPE[0] = _i2; \ > + fregs.F3.TYPE[0] = _i3; \ > + fregs.F4.TYPE[0] = _i4; \ > + fregs.F5.TYPE[0] = _i5; \ > + fregs.F6.TYPE[0] = _i6; \ > + fregs.F7.TYPE[0] = _i7; \ > + num_fregs = 8; \ > + WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7); > + > +#define def_check_passing20(_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ > + _i8, _i9, _i10, _i11, _i12, _i13, _i14, \ > + _i15, _i16, _i17, _i18, _i19, _func1, \ > + _func2, TYPE) \ > + values.i0.TYPE[0] = _i0; \ > + values.i1.TYPE[0] = _i1; \ > + values.i2.TYPE[0] = _i2; \ > + values.i3.TYPE[0] = _i3; \ > + values.i4.TYPE[0] = _i4; \ > + values.i5.TYPE[0] = _i5; \ > + values.i6.TYPE[0] = _i6; \ > + values.i7.TYPE[0] = _i7; \ > + values.i8.TYPE[0] = _i8; \ > + values.i9.TYPE[0] = _i9; \ > + values.i10.TYPE[0] = _i10; \ > + values.i11.TYPE[0] = _i11; \ > + values.i12.TYPE[0] = _i12; \ > + values.i13.TYPE[0] = _i13; \ > + values.i14.TYPE[0] = _i14; \ > + values.i15.TYPE[0] = _i15; \ > + values.i16.TYPE[0] = _i16; \ > + values.i17.TYPE[0] = _i17; \ > + values.i18.TYPE[0] = _i18; \ > + values.i19.TYPE[0] = _i19; \ > + WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ > + _i9, _i10, _i11, _i12, _i13, _i14, _i15, \ > + _i16, _i17, _i18, _i19); \ > + clear_struct_registers; \ > + fregs.F0.TYPE[0] = _i0; \ > + fregs.F1.TYPE[0] = _i1; \ > + fregs.F2.TYPE[0] = _i2; \ > + fregs.F3.TYPE[0] = _i3; \ > + fregs.F4.TYPE[0] = _i4; \ > + fregs.F5.TYPE[0] = _i5; \ > + fregs.F6.TYPE[0] = _i6; \ > + fregs.F7.TYPE[0] = _i7; \ > + num_fregs = 8; \ > + WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ > + _i9, _i10, _i11, _i12, _i13, _i14, _i15, \ > + _i16, _i17, _i18, _i19); > + > +volatile __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16; > + > +void > +test_m256bf16_on_stack () > +{ > + __m256bf16 x[8]; > + int i; > + for (i = 0; i < 8; i++) > + x[i] = (__m256bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16}; > + pass = "m256bf16-8"; > + def_check_passing8 (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], > + fun_check_passing_m256bf16_8_values, > + fun_check_passing_m256bf16_8_regs, _m256bf16); > +} > + > +void > +test_too_many_m256bf16 () > +{ > + __m256bf16 x[20]; > + int i; > + for (i = 0; i < 20; i++) > + x[i] = (__m256bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16}; > + pass = "m256bf16-20"; > + def_check_passing20 (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], > + x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16], > + x[17], x[18], x[19], fun_check_passing_m256bf16_20_values, > + fun_check_passing_m256bf16_20_regs, _m256bf16); > +} > + > +static void > +do_test (void) > +{ > + test_m256bf16_on_stack (); > + test_too_many_m256bf16 (); > + if (failed) > + abort (); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_structs.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_structs.c > new file mode 100644 > index 00000000000..e06350ed493 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_structs.c > @@ -0,0 +1,69 @@ > +#include "bf16-ymm-check.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +struct m256bf16_struct > +{ > + __m256bf16 x; > +}; > + > +struct m256bf16_2_struct > +{ > + __m256bf16 x1, x2; > +}; > + > +/* Check that the struct is passed as the individual members in fregs. */ > +void > +check_struct_passing1bf16 (struct m256bf16_struct ms1 ATTRIBUTE_UNUSED, > + struct m256bf16_struct ms2 ATTRIBUTE_UNUSED, > + struct m256bf16_struct ms3 ATTRIBUTE_UNUSED, > + struct m256bf16_struct ms4 ATTRIBUTE_UNUSED, > + struct m256bf16_struct ms5 ATTRIBUTE_UNUSED, > + struct m256bf16_struct ms6 ATTRIBUTE_UNUSED, > + struct m256bf16_struct ms7 ATTRIBUTE_UNUSED, > + struct m256bf16_struct ms8 ATTRIBUTE_UNUSED) > +{ > + check_m256_arguments; > +} > + > +void > +check_struct_passing2bf16 (struct m256bf16_2_struct ms ATTRIBUTE_UNUSED) > +{ > + /* Check the passing on the stack by comparing the address of the > + stack elements to the expected place on the stack. */ > + assert ((unsigned long)&ms.x1 == rsp+8); > + assert ((unsigned long)&ms.x2 == rsp+40); > +} > + > +volatile __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16; > + > +static void > +do_test (void) > +{ > + struct m256bf16_struct m256bf16s [8]; > + struct m256bf16_2_struct m256bf16_2s = { > + { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16}, > + { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16}, > + }; > + int i; > + > + for (i = 0; i < 8; i++) > + { > + m256bf16s[i].x = (__m256bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16}; > + } > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + (&fregs.ymm0)[i]._m256bf16[0] = m256bf16s[i].x; > + num_fregs = 8; > + WRAP_CALL (check_struct_passing1bf16) (m256bf16s[0], m256bf16s[1], m256bf16s[2], m256bf16s[3], > + m256bf16s[4], m256bf16s[5], m256bf16s[6], m256bf16s[7]); > + WRAP_CALL (check_struct_passing2bf16) (m256bf16_2s); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_unions.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_unions.c > new file mode 100644 > index 00000000000..6d663b88b1a > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_passing_unions.c > @@ -0,0 +1,179 @@ > +#include "bf16-ymm-check.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +union un1b > +{ > + __m256bf16 x; > + float f; > +}; > + > +union un1bb > +{ > + __m256bf16 x; > + __bf16 f; > +}; > + > +union un2b > +{ > + __m256bf16 x; > + double d; > +}; > + > +union un3b > +{ > + __m256bf16 x; > + __m128 v; > +}; > + > +union un4b > +{ > + __m256bf16 x; > + long double ld; > +}; > + > +union un5b > +{ > + __m256bf16 x; > + int i; > +}; > + > +void > +check_union_passing1b (union un1b u1 ATTRIBUTE_UNUSED, > + union un1b u2 ATTRIBUTE_UNUSED, > + union un1b u3 ATTRIBUTE_UNUSED, > + union un1b u4 ATTRIBUTE_UNUSED, > + union un1b u5 ATTRIBUTE_UNUSED, > + union un1b u6 ATTRIBUTE_UNUSED, > + union un1b u7 ATTRIBUTE_UNUSED, > + union un1b u8 ATTRIBUTE_UNUSED) > +{ > + check_m256_arguments; > +} > + > +void > +check_union_passing1bb (union un1bb u1 ATTRIBUTE_UNUSED, > + union un1bb u2 ATTRIBUTE_UNUSED, > + union un1bb u3 ATTRIBUTE_UNUSED, > + union un1bb u4 ATTRIBUTE_UNUSED, > + union un1bb u5 ATTRIBUTE_UNUSED, > + union un1bb u6 ATTRIBUTE_UNUSED, > + union un1bb u7 ATTRIBUTE_UNUSED, > + union un1bb u8 ATTRIBUTE_UNUSED) > +{ > + check_m256_arguments; > +} > + > +void > +check_union_passing2b (union un2b u1 ATTRIBUTE_UNUSED, > + union un2b u2 ATTRIBUTE_UNUSED, > + union un2b u3 ATTRIBUTE_UNUSED, > + union un2b u4 ATTRIBUTE_UNUSED, > + union un2b u5 ATTRIBUTE_UNUSED, > + union un2b u6 ATTRIBUTE_UNUSED, > + union un2b u7 ATTRIBUTE_UNUSED, > + union un2b u8 ATTRIBUTE_UNUSED) > +{ > + check_m256_arguments; > +} > + > +void > +check_union_passing3b (union un3b u1 ATTRIBUTE_UNUSED, > + union un3b u2 ATTRIBUTE_UNUSED, > + union un3b u3 ATTRIBUTE_UNUSED, > + union un3b u4 ATTRIBUTE_UNUSED, > + union un3b u5 ATTRIBUTE_UNUSED, > + union un3b u6 ATTRIBUTE_UNUSED, > + union un3b u7 ATTRIBUTE_UNUSED, > + union un3b u8 ATTRIBUTE_UNUSED) > +{ > + check_m256_arguments; > +} > + > +void > +check_union_passing4b (union un4b u ATTRIBUTE_UNUSED) > +{ > + /* Check the passing on the stack by comparing the address of the > + stack elements to the expected place on the stack. */ > + assert ((unsigned long)&u.x == rsp+8); > + assert ((unsigned long)&u.ld == rsp+8); > +} > + > +void > +check_union_passing5b (union un5b u ATTRIBUTE_UNUSED) > +{ > + /* Check the passing on the stack by comparing the address of the > + stack elements to the expected place on the stack. */ > + assert ((unsigned long)&u.x == rsp+8); > + assert ((unsigned long)&u.i == rsp+8); > +} > + > +#define check_union_passing1b WRAP_CALL(check_union_passing1b) > +#define check_union_passing1bb WRAP_CALL(check_union_passing1bb) > +#define check_union_passing2b WRAP_CALL(check_union_passing2b) > +#define check_union_passing3b WRAP_CALL(check_union_passing3b) > +#define check_union_passing4b WRAP_CALL(check_union_passing4b) > +#define check_union_passing5b WRAP_CALL(check_union_passing5b) > + > +static void > +do_test (void) > +{ > + union un1b u1b[8]; > + union un1bb u1bb[8]; > + union un2b u2b[8]; > + union un3b u3b[8]; > + union un4b u4b; > + union un5b u5b; > + int i; > + __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16; > + > + for (i = 0; i < 8; i++) > + { > + u1b[i].x = (__m256bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16 }; > + } > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + (&fregs.ymm0)[i]._m256bf16[0] = u1b[i].x; > + num_fregs = 8; > + check_union_passing1b (u1b[0], u1b[1], u1b[2], u1b[3], > + u1b[4], u1b[5], u1b[6], u1b[7]); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u1bb[i].x = u1b[i].x; > + (&fregs.ymm0)[i]._m256bf16[0] = u1bb[i].x; > + } > + num_fregs = 8; > + check_union_passing1bb (u1bb[0], u1bb[1], u1bb[2], u1bb[3], > + u1bb[4], u1bb[5], u1bb[6], u1bb[7]); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u2b[i].x = u1b[i].x; > + (&fregs.ymm0)[i]._m256bf16[0] = u2b[i].x; > + } > + num_fregs = 8; > + check_union_passing2b (u2b[0], u2b[1], u2b[2], u2b[3], > + u2b[4], u2b[5], u2b[6], u2b[7]); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u3b[i].x = u1b[i].x; > + (&fregs.ymm0)[i]._m256bf16[0] = u3b[i].x; > + } > + num_fregs = 8; > + check_union_passing3b (u3b[0], u3b[1], u3b[2], u3b[3], > + u3b[4], u3b[5], u3b[6], u3b[7]); > + > + check_union_passing4b (u4b); > + check_union_passing5b (u5b); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_varargs-m256.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_varargs-m256.c > new file mode 100644 > index 00000000000..b69e095d808 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/test_varargs-m256.c > @@ -0,0 +1,107 @@ > +/* Test variable number of 256-bit vector arguments passed to functions. */ > + > +#include > +#include "bf16-ymm-check.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > + > +/* This struct holds values for argument checking. */ > +struct > +{ > + YMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; > +} values; > + > +char *pass; > +int failed = 0; > + > +#undef assert > +#define assert(c) do { \ > + if (!(c)) {failed++; printf ("failed %s\n", pass); } \ > +} while (0) > + > +#define compare(X1,X2,T) do { \ > + assert (memcmp (&X1, &X2, sizeof (T)) == 0); \ > +} while (0) > + > +void > +fun_check_passing_m256bf16_varargs (__m256bf16 i0, __m256bf16 i1, __m256bf16 i2, > + __m256bf16 i3, ...) > +{ > + /* Check argument values. */ > + void **fp = __builtin_frame_address (0); > + void *ra = __builtin_return_address (0); > + __m256bf16 *argp; > + > + compare (values.i0, i0, __m256bf16); > + compare (values.i1, i1, __m256bf16); > + compare (values.i2, i2, __m256bf16); > + compare (values.i3, i3, __m256bf16); > + > + /* Get the pointer to the return address on stack. */ > + while (*fp != ra) > + fp++; > + > + /* Skip the return address stack slot. */ > + argp = (__m256bf16 *)(((char *) fp) + 8); > + > + /* Check __m256bf16 arguments passed on stack. */ > + compare (values.i4, argp[0], __m256bf16); > + compare (values.i5, argp[1], __m256bf16); > + compare (values.i6, argp[2], __m256bf16); > + compare (values.i7, argp[3], __m256bf16); > + compare (values.i8, argp[4], __m256bf16); > + compare (values.i9, argp[5], __m256bf16); > + > + /* Check register contents. */ > + compare (fregs.ymm0, ymm_regs[0], __m256bf16); > + compare (fregs.ymm1, ymm_regs[1], __m256bf16); > + compare (fregs.ymm2, ymm_regs[2], __m256bf16); > + compare (fregs.ymm3, ymm_regs[3], __m256bf16); > +} > + > +#define def_check_int_passing_varargs(_i0, _i1, _i2, _i3, _i4, _i5, \ > + _i6, _i7, _i8, _i9, \ > + _func, TYPE) \ > + values.i0.TYPE[0] = _i0; \ > + values.i1.TYPE[0] = _i1; \ > + values.i2.TYPE[0] = _i2; \ > + values.i3.TYPE[0] = _i3; \ > + values.i4.TYPE[0] = _i4; \ > + values.i5.TYPE[0] = _i5; \ > + values.i6.TYPE[0] = _i6; \ > + values.i7.TYPE[0] = _i7; \ > + values.i8.TYPE[0] = _i8; \ > + values.i9.TYPE[0] = _i9; \ > + clear_struct_registers; \ > + fregs.F0.TYPE[0] = _i0; \ > + fregs.F1.TYPE[0] = _i1; \ > + fregs.F2.TYPE[0] = _i2; \ > + fregs.F3.TYPE[0] = _i3; \ > + WRAP_CALL(_func) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9); > + > +void > +test_m256bf16_varargs (void) > +{ > + __m256bf16 x[10]; > + int i; > + __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16; > + for (i = 0; i < 10; i++) > + x[i] = (__m256bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16 }; > + pass = "m256bf16-varargs"; > + def_check_int_passing_varargs (x[0], x[1], x[2], x[3], x[4], x[5], > + x[6], x[7], x[8], x[9], > + fun_check_passing_m256bf16_varargs, > + _m256bf16); > +} > + > +void > +do_test (void) > +{ > + test_m256bf16_varargs (); > + if (failed) > + abort (); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp > new file mode 100644 > index 00000000000..b6e0fed4cb4 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp > @@ -0,0 +1,46 @@ > +# Copyright (C) 2022 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with GCC; see the file COPYING3. If not see > +# . > + > +# The x86-64 ABI testsuite needs one additional assembler file for most > +# testcases. For simplicity we will just link it into each test. > + > +load_lib c-torture.exp > +load_lib target-supports.exp > +load_lib torture-options.exp > +load_lib clearcap.exp > + > +if { (![istarget x86_64-*-*] && ![istarget i?86-*-*]) > + || ![is-effective-target lp64] > + || ![is-effective-target avx512f] } then { > + return > +} > + > + > +torture-init > +clearcap-init > +set-torture-options $C_TORTURE_OPTIONS > +set additional_flags "-W -Wall -mavx512f" > + > +foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] { > + if {[runtest_file_p $runtests $src]} { > + c-torture-execute [list $src \ > + $srcdir/$subdir/asm-support.S] \ > + $additional_flags > + } > +} > + > +clearcap-finish > +torture-finish > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/args.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/args.h > new file mode 100644 > index 00000000000..64b24783833 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/args.h > @@ -0,0 +1,155 @@ > +#ifndef INCLUDED_ARGS_H > +#define INCLUDED_ARGS_H > + > +#include > +#include > + > +/* Assertion macro. */ > +#define assert(test) if (!(test)) abort() > + > +#ifdef __GNUC__ > +#define ATTRIBUTE_UNUSED __attribute__((__unused__)) > +#else > +#define ATTRIBUTE_UNUSED > +#endif > + > +/* This defines the calling sequences for integers and floats. */ > +#define I0 rdi > +#define I1 rsi > +#define I2 rdx > +#define I3 rcx > +#define I4 r8 > +#define I5 r9 > +#define F0 zmm0 > +#define F1 zmm1 > +#define F2 zmm2 > +#define F3 zmm3 > +#define F4 zmm4 > +#define F5 zmm5 > +#define F6 zmm6 > +#define F7 zmm7 > + > +typedef union { > + __bf16 ___bf16[32]; > + float _float[16]; > + double _double[8]; > + long long _longlong[8]; > + int _int[16]; > + unsigned long long _ulonglong[8]; > + __m64 _m64[8]; > + __m128 _m128[4]; > + __m256 _m256[2]; > + __m512 _m512[1]; > + __m512bf16 _m512bf16[1]; > +} ZMM_T; > + > +typedef union { > + float _float; > + double _double; > + long double _ldouble; > + unsigned long long _ulonglong[2]; > +} X87_T; > +extern void (*callthis)(void); > +extern unsigned long long rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15; > +ZMM_T zmm_regs[32]; > +X87_T x87_regs[8]; > +extern volatile unsigned long long volatile_var; > +extern void snapshot (void); > +extern void snapshot_ret (void); > +#define WRAP_CALL(N) \ > + (callthis = (void (*)()) (N), (typeof (&N)) snapshot) > +#define WRAP_RET(N) \ > + (callthis = (void (*)()) (N), (typeof (&N)) snapshot_ret) > + > +/* Clear all integer registers. */ > +#define clear_int_hardware_registers \ > + asm __volatile__ ("xor %%rax, %%rax\n\t" \ > + "xor %%rbx, %%rbx\n\t" \ > + "xor %%rcx, %%rcx\n\t" \ > + "xor %%rdx, %%rdx\n\t" \ > + "xor %%rsi, %%rsi\n\t" \ > + "xor %%rdi, %%rdi\n\t" \ > + "xor %%r8, %%r8\n\t" \ > + "xor %%r9, %%r9\n\t" \ > + "xor %%r10, %%r10\n\t" \ > + "xor %%r11, %%r11\n\t" \ > + "xor %%r12, %%r12\n\t" \ > + "xor %%r13, %%r13\n\t" \ > + "xor %%r14, %%r14\n\t" \ > + "xor %%r15, %%r15\n\t" \ > + ::: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", \ > + "r9", "r10", "r11", "r12", "r13", "r14", "r15"); > + > +/* This is the list of registers available for passing arguments. Not all of > + these are used or even really available. */ > +struct IntegerRegisters > +{ > + unsigned long long rax, rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15; > +}; > +struct FloatRegisters > +{ > + double mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7; > + long double st0, st1, st2, st3, st4, st5, st6, st7; > + ZMM_T zmm0, zmm1, zmm2, zmm3, zmm4, zmm5, zmm6, zmm7, zmm8, zmm9, > + zmm10, zmm11, zmm12, zmm13, zmm14, zmm15, zmm16, zmm17, zmm18, > + zmm19, zmm20, zmm21, zmm22, zmm23, zmm24, zmm25, zmm26, zmm27, > + zmm28, zmm29, zmm30, zmm31; > +}; > + > +/* Implemented in scalarargs.c */ > +extern struct IntegerRegisters iregs; > +extern struct FloatRegisters fregs; > +extern unsigned int num_iregs, num_fregs; > + > +/* Clear register struct. */ > +#define clear_struct_registers \ > + rax = rbx = rcx = rdx = rdi = rsi = rbp = rsp \ > + = r8 = r9 = r10 = r11 = r12 = r13 = r14 = r15 = 0; \ > + memset (&iregs, 0, sizeof (iregs)); \ > + memset (&fregs, 0, sizeof (fregs)); \ > + memset (zmm_regs, 0, sizeof (zmm_regs)); \ > + memset (x87_regs, 0, sizeof (x87_regs)); > + > +/* Clear both hardware and register structs for integers. */ > +#define clear_int_registers \ > + clear_struct_registers \ > + clear_int_hardware_registers > + > +#define check_vector_arguments(T,O) do { \ > + assert (num_fregs <= 0 \ > + || memcmp (((char *) &fregs.zmm0) + (O), \ > + &zmm_regs[0], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 1 \ > + || memcmp (((char *) &fregs.zmm1) + (O), \ > + &zmm_regs[1], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 2 \ > + || memcmp (((char *) &fregs.zmm2) + (O), \ > + &zmm_regs[2], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 3 \ > + || memcmp (((char *) &fregs.zmm3) + (O), \ > + &zmm_regs[3], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 4 \ > + || memcmp (((char *) &fregs.zmm4) + (O), \ > + &zmm_regs[4], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 5 \ > + || memcmp (((char *) &fregs.zmm5) + (O), \ > + &zmm_regs[5], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 6 \ > + || memcmp (((char *) &fregs.zmm6) + (O), \ > + &zmm_regs[6], \ > + sizeof (__ ## T) - (O)) == 0); \ > + assert (num_fregs <= 7 \ > + || memcmp (((char *) &fregs.zmm7) + (O), \ > + &zmm_regs[7], \ > + sizeof (__ ## T) - (O)) == 0); \ > + } while (0) > + > +#define check_m512_arguments check_vector_arguments(m512, 0) > + > +#endif /* INCLUDED_ARGS_H */ > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/asm-support.S > new file mode 100644 > index 00000000000..86d54d11c58 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/asm-support.S > @@ -0,0 +1,100 @@ > + .text > + .p2align 4,,15 > +.globl snapshot > + .type snapshot, @function > +snapshot: > +.LFB3: > + movq %rax, rax(%rip) > + movq %rbx, rbx(%rip) > + movq %rcx, rcx(%rip) > + movq %rdx, rdx(%rip) > + movq %rdi, rdi(%rip) > + movq %rsi, rsi(%rip) > + movq %rbp, rbp(%rip) > + movq %rsp, rsp(%rip) > + movq %r8, r8(%rip) > + movq %r9, r9(%rip) > + movq %r10, r10(%rip) > + movq %r11, r11(%rip) > + movq %r12, r12(%rip) > + movq %r13, r13(%rip) > + movq %r14, r14(%rip) > + movq %r15, r15(%rip) > + vmovdqu32 %zmm0, zmm_regs+0(%rip) > + vmovdqu32 %zmm1, zmm_regs+64(%rip) > + vmovdqu32 %zmm2, zmm_regs+128(%rip) > + vmovdqu32 %zmm3, zmm_regs+192(%rip) > + vmovdqu32 %zmm4, zmm_regs+256(%rip) > + vmovdqu32 %zmm5, zmm_regs+320(%rip) > + vmovdqu32 %zmm6, zmm_regs+384(%rip) > + vmovdqu32 %zmm7, zmm_regs+448(%rip) > + vmovdqu32 %zmm8, zmm_regs+512(%rip) > + vmovdqu32 %zmm9, zmm_regs+576(%rip) > + vmovdqu32 %zmm10, zmm_regs+640(%rip) > + vmovdqu32 %zmm11, zmm_regs+704(%rip) > + vmovdqu32 %zmm12, zmm_regs+768(%rip) > + vmovdqu32 %zmm13, zmm_regs+832(%rip) > + vmovdqu32 %zmm14, zmm_regs+896(%rip) > + vmovdqu32 %zmm15, zmm_regs+960(%rip) > + vmovdqu32 %zmm16, zmm_regs+1024(%rip) > + vmovdqu32 %zmm17, zmm_regs+1088(%rip) > + vmovdqu32 %zmm18, zmm_regs+1152(%rip) > + vmovdqu32 %zmm19, zmm_regs+1216(%rip) > + vmovdqu32 %zmm20, zmm_regs+1280(%rip) > + vmovdqu32 %zmm21, zmm_regs+1344(%rip) > + vmovdqu32 %zmm22, zmm_regs+1408(%rip) > + vmovdqu32 %zmm23, zmm_regs+1472(%rip) > + vmovdqu32 %zmm24, zmm_regs+1536(%rip) > + vmovdqu32 %zmm25, zmm_regs+1600(%rip) > + vmovdqu32 %zmm26, zmm_regs+1664(%rip) > + vmovdqu32 %zmm27, zmm_regs+1728(%rip) > + vmovdqu32 %zmm28, zmm_regs+1792(%rip) > + vmovdqu32 %zmm29, zmm_regs+1856(%rip) > + vmovdqu32 %zmm30, zmm_regs+1920(%rip) > + vmovdqu32 %zmm31, zmm_regs+1984(%rip) > + jmp *callthis(%rip) > +.LFE3: > + .size snapshot, .-snapshot > + > + .p2align 4,,15 > +.globl snapshot_ret > + .type snapshot_ret, @function > +snapshot_ret: > + movq %rdi, rdi(%rip) > + subq $8, %rsp > + call *callthis(%rip) > + addq $8, %rsp > + movq %rax, rax(%rip) > + movq %rdx, rdx(%rip) > + vmovdqu32 %zmm0, zmm_regs+0(%rip) > + vmovdqu32 %zmm1, zmm_regs+64(%rip) > + fstpt x87_regs(%rip) > + fstpt x87_regs+16(%rip) > + fldt x87_regs+16(%rip) > + fldt x87_regs(%rip) > + ret > + .size snapshot_ret, .-snapshot_ret > + > + .comm callthis,8,8 > + .comm rax,8,8 > + .comm rbx,8,8 > + .comm rcx,8,8 > + .comm rdx,8,8 > + .comm rsi,8,8 > + .comm rdi,8,8 > + .comm rsp,8,8 > + .comm rbp,8,8 > + .comm r8,8,8 > + .comm r9,8,8 > + .comm r10,8,8 > + .comm r11,8,8 > + .comm r12,8,8 > + .comm r13,8,8 > + .comm r14,8,8 > + .comm r15,8,8 > + .comm zmm_regs,2048,64 > + .comm x87_regs,128,32 > + .comm volatile_var,8,8 > +#ifdef __linux__ > + .section .note.GNU-stack,"",@progbits > +#endif > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/bf16-zmm-check.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/bf16-zmm-check.h > new file mode 100644 > index 00000000000..8379fcfaf8c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/bf16-zmm-check.h > @@ -0,0 +1,23 @@ > +#include > + > +static void do_test (void); > + > +int > +main () > +{ > + > + if (__builtin_cpu_supports ("avx512f")) > + { > + do_test (); > +#ifdef DEBUG > + printf ("PASSED\n"); > +#endif > + return 0; > + } > + > +#ifdef DEBUG > + printf ("SKIPPED\n"); > +#endif > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_m512_returning.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_m512_returning.c > new file mode 100644 > index 00000000000..1a2500bd883 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_m512_returning.c > @@ -0,0 +1,44 @@ > +#include > +#include "bf16-zmm-check.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +volatile __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32; > + > +__m512bf16 > +fun_test_returning___m512bf16 (void) > +{ > + volatile_var++; > + return (__m512bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32 }; > +} > + > +__m512bf16 test_512bf16; > + > +static void > +do_test (void) > +{ > + unsigned failed = 0; > + ZMM_T zmmt1, zmmt2; > + > + clear_struct_registers; > + test_512bf16 = (__m512bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32 }; > + zmmt1._m512bf16[0] = test_512bf16; > + zmmt2._m512bf16[0] = WRAP_RET (fun_test_returning___m512bf16)(); > + if (memcmp (&zmmt1, &zmmt2, sizeof (zmmt2)) != 0) > + printf ("fail m512bf16\n"), failed++; > + > + if (failed) > + abort (); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_m512.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_m512.c > new file mode 100644 > index 00000000000..1c5c407efee > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_m512.c > @@ -0,0 +1,243 @@ > +#include > +#include "bf16-zmm-check.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +/* This struct holds values for argument checking. */ > +struct > +{ > + ZMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, > + i16, i17, i18, i19, i20, i21, i22, i23; > +} values; > + > +char *pass; > +int failed = 0; > + > +#undef assert > +#define assert(c) do { \ > + if (!(c)) {failed++; printf ("failed %s\n", pass); } \ > +} while (0) > + > +#define compare(X1,X2,T) do { \ > + assert (memcmp (&X1, &X2, sizeof (T)) == 0); \ > +} while (0) > + > +fun_check_passing_m512bf16_8_values (__m512bf16 i0 ATTRIBUTE_UNUSED, > + __m512bf16 i1 ATTRIBUTE_UNUSED, > + __m512bf16 i2 ATTRIBUTE_UNUSED, > + __m512bf16 i3 ATTRIBUTE_UNUSED, > + __m512bf16 i4 ATTRIBUTE_UNUSED, > + __m512bf16 i5 ATTRIBUTE_UNUSED, > + __m512bf16 i6 ATTRIBUTE_UNUSED, > + __m512bf16 i7 ATTRIBUTE_UNUSED) > +{ > + /* Check argument values. */ > + compare (values.i0, i0, __m512bf16); > + compare (values.i1, i1, __m512bf16); > + compare (values.i2, i2, __m512bf16); > + compare (values.i3, i3, __m512bf16); > + compare (values.i4, i4, __m512bf16); > + compare (values.i5, i5, __m512bf16); > + compare (values.i6, i6, __m512bf16); > + compare (values.i7, i7, __m512bf16); > +} > + > +void > +fun_check_passing_m512bf16_8_regs (__m512bf16 i0 ATTRIBUTE_UNUSED, > + __m512bf16 i1 ATTRIBUTE_UNUSED, > + __m512bf16 i2 ATTRIBUTE_UNUSED, > + __m512bf16 i3 ATTRIBUTE_UNUSED, > + __m512bf16 i4 ATTRIBUTE_UNUSED, > + __m512bf16 i5 ATTRIBUTE_UNUSED, > + __m512bf16 i6 ATTRIBUTE_UNUSED, > + __m512bf16 i7 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m512_arguments; > +} > + > +void > +fun_check_passing_m512bf16_20_values (__m512bf16 i0 ATTRIBUTE_UNUSED, > + __m512bf16 i1 ATTRIBUTE_UNUSED, > + __m512bf16 i2 ATTRIBUTE_UNUSED, > + __m512bf16 i3 ATTRIBUTE_UNUSED, > + __m512bf16 i4 ATTRIBUTE_UNUSED, > + __m512bf16 i5 ATTRIBUTE_UNUSED, > + __m512bf16 i6 ATTRIBUTE_UNUSED, > + __m512bf16 i7 ATTRIBUTE_UNUSED, > + __m512bf16 i8 ATTRIBUTE_UNUSED, > + __m512bf16 i9 ATTRIBUTE_UNUSED, > + __m512bf16 i10 ATTRIBUTE_UNUSED, > + __m512bf16 i11 ATTRIBUTE_UNUSED, > + __m512bf16 i12 ATTRIBUTE_UNUSED, > + __m512bf16 i13 ATTRIBUTE_UNUSED, > + __m512bf16 i14 ATTRIBUTE_UNUSED, > + __m512bf16 i15 ATTRIBUTE_UNUSED, > + __m512bf16 i16 ATTRIBUTE_UNUSED, > + __m512bf16 i17 ATTRIBUTE_UNUSED, > + __m512bf16 i18 ATTRIBUTE_UNUSED, > + __m512bf16 i19 ATTRIBUTE_UNUSED) > +{ > + /* Check argument values. */ > + compare (values.i0, i0, __m512bf16); > + compare (values.i1, i1, __m512bf16); > + compare (values.i2, i2, __m512bf16); > + compare (values.i3, i3, __m512bf16); > + compare (values.i4, i4, __m512bf16); > + compare (values.i5, i5, __m512bf16); > + compare (values.i6, i6, __m512bf16); > + compare (values.i7, i7, __m512bf16); > + compare (values.i8, i8, __m512bf16); > + compare (values.i9, i9, __m512bf16); > + compare (values.i10, i10, __m512bf16); > + compare (values.i11, i11, __m512bf16); > + compare (values.i12, i12, __m512bf16); > + compare (values.i13, i13, __m512bf16); > + compare (values.i14, i14, __m512bf16); > + compare (values.i15, i15, __m512bf16); > + compare (values.i16, i16, __m512bf16); > + compare (values.i17, i17, __m512bf16); > + compare (values.i18, i18, __m512bf16); > + compare (values.i19, i19, __m512bf16); > +} > + > +void > +fun_check_passing_m512bf16_20_regs (__m512bf16 i0 ATTRIBUTE_UNUSED, > + __m512bf16 i1 ATTRIBUTE_UNUSED, > + __m512bf16 i2 ATTRIBUTE_UNUSED, > + __m512bf16 i3 ATTRIBUTE_UNUSED, > + __m512bf16 i4 ATTRIBUTE_UNUSED, > + __m512bf16 i5 ATTRIBUTE_UNUSED, > + __m512bf16 i6 ATTRIBUTE_UNUSED, > + __m512bf16 i7 ATTRIBUTE_UNUSED, > + __m512bf16 i8 ATTRIBUTE_UNUSED, > + __m512bf16 i9 ATTRIBUTE_UNUSED, > + __m512bf16 i10 ATTRIBUTE_UNUSED, > + __m512bf16 i11 ATTRIBUTE_UNUSED, > + __m512bf16 i12 ATTRIBUTE_UNUSED, > + __m512bf16 i13 ATTRIBUTE_UNUSED, > + __m512bf16 i14 ATTRIBUTE_UNUSED, > + __m512bf16 i15 ATTRIBUTE_UNUSED, > + __m512bf16 i16 ATTRIBUTE_UNUSED, > + __m512bf16 i17 ATTRIBUTE_UNUSED, > + __m512bf16 i18 ATTRIBUTE_UNUSED, > + __m512bf16 i19 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m512_arguments; > +} > + > +#define def_check_passing8(_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _func1, _func2, TYPE) \ > + values.i0.TYPE[0] = _i0; \ > + values.i1.TYPE[0] = _i1; \ > + values.i2.TYPE[0] = _i2; \ > + values.i3.TYPE[0] = _i3; \ > + values.i4.TYPE[0] = _i4; \ > + values.i5.TYPE[0] = _i5; \ > + values.i6.TYPE[0] = _i6; \ > + values.i7.TYPE[0] = _i7; \ > + WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7); \ > + \ > + clear_struct_registers; \ > + fregs.F0.TYPE[0] = _i0; \ > + fregs.F1.TYPE[0] = _i1; \ > + fregs.F2.TYPE[0] = _i2; \ > + fregs.F3.TYPE[0] = _i3; \ > + fregs.F4.TYPE[0] = _i4; \ > + fregs.F5.TYPE[0] = _i5; \ > + fregs.F6.TYPE[0] = _i6; \ > + fregs.F7.TYPE[0] = _i7; \ > + num_fregs = 8; \ > + WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7); > + > +#define def_check_passing20(_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, \ > + _i10, _i11, _i12, _i13, _i14, _i15, _i16, _i17, \ > + _i18, _i19, _func1, _func2, TYPE) \ > + values.i0.TYPE[0] = _i0; \ > + values.i1.TYPE[0] = _i1; \ > + values.i2.TYPE[0] = _i2; \ > + values.i3.TYPE[0] = _i3; \ > + values.i4.TYPE[0] = _i4; \ > + values.i5.TYPE[0] = _i5; \ > + values.i6.TYPE[0] = _i6; \ > + values.i7.TYPE[0] = _i7; \ > + values.i8.TYPE[0] = _i8; \ > + values.i9.TYPE[0] = _i9; \ > + values.i10.TYPE[0] = _i10; \ > + values.i11.TYPE[0] = _i11; \ > + values.i12.TYPE[0] = _i12; \ > + values.i13.TYPE[0] = _i13; \ > + values.i14.TYPE[0] = _i14; \ > + values.i15.TYPE[0] = _i15; \ > + values.i16.TYPE[0] = _i16; \ > + values.i17.TYPE[0] = _i17; \ > + values.i18.TYPE[0] = _i18; \ > + values.i19.TYPE[0] = _i19; \ > + WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, \ > + _i10, _i11, _i12, _i13, _i14, _i15, _i16, _i17, \ > + _i18, _i19); \ > + \ > + clear_struct_registers; \ > + fregs.F0.TYPE[0] = _i0; \ > + fregs.F1.TYPE[0] = _i1; \ > + fregs.F2.TYPE[0] = _i2; \ > + fregs.F3.TYPE[0] = _i3; \ > + fregs.F4.TYPE[0] = _i4; \ > + fregs.F5.TYPE[0] = _i5; \ > + fregs.F6.TYPE[0] = _i6; \ > + fregs.F7.TYPE[0] = _i7; \ > + num_fregs = 8; \ > + WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, \ > + _i10, _i11, _i12, _i13, _i14, _i15, _i16, _i17, \ > + _i18, _i19); > + > +volatile __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32; > + > +void > +test_m512bf16_on_stack () > +{ > + __m512bf16 x[8]; > + int i; > + for (i = 0; i < 8; i++) > + x[i] = (__m512bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32 }; > + > + pass = "m512bf16-8"; > + def_check_passing8 (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], > + fun_check_passing_m512bf16_8_values, > + fun_check_passing_m512bf16_8_regs, _m512bf16); > +} > + > +void > +test_too_many_m512bf16 () > +{ > + __m512bf16 x[20]; > + int i; > + for (i = 0; i < 20; i++) > + x[i] = (__m512bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32 }; > + pass = "m512bf16-20"; > + def_check_passing20 (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], > + x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16], > + x[17], x[18], x[19], fun_check_passing_m512bf16_20_values, > + fun_check_passing_m512bf16_20_regs, _m512bf16); > +} > + > +static void > +do_test (void) > +{ > + test_m512bf16_on_stack (); > + test_too_many_m512bf16 (); > + if (failed) > + abort (); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_structs.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_structs.c > new file mode 100644 > index 00000000000..f93a2b81086 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_structs.c > @@ -0,0 +1,77 @@ > +#include "bf16-zmm-check.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +struct m512bf16_struct > +{ > + __m512bf16 x; > +}; > + > +struct m512bf16_2_struct > +{ > + __m512bf16 x1, x2; > +}; > + > +/* Check that the struct is passed as the individual members in fregs. */ > +void > +check_struct_passing1bf16 (struct m512bf16_struct ms1 ATTRIBUTE_UNUSED, > + struct m512bf16_struct ms2 ATTRIBUTE_UNUSED, > + struct m512bf16_struct ms3 ATTRIBUTE_UNUSED, > + struct m512bf16_struct ms4 ATTRIBUTE_UNUSED, > + struct m512bf16_struct ms5 ATTRIBUTE_UNUSED, > + struct m512bf16_struct ms6 ATTRIBUTE_UNUSED, > + struct m512bf16_struct ms7 ATTRIBUTE_UNUSED, > + struct m512bf16_struct ms8 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m512_arguments; > +} > + > +void > +check_struct_passing2bf16 (struct m512bf16_2_struct ms ATTRIBUTE_UNUSED) > +{ > + /* Check the passing on the stack by comparing the address of the > + stack elements to the expected place on the stack. */ > + assert ((unsigned long)&ms.x1 == rsp+8); > + assert ((unsigned long)&ms.x2 == rsp+72); > +} > + > +static void > +do_test (void) > +{ > + __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32; > + struct m512bf16_struct m512bf16s [8]; > + struct m512bf16_2_struct m512bf16_2s = { > + { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32 }, > + { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32 } > + }; > + int i; > + > + for (i = 0; i < 8; i++) > + { > + m512bf16s[i].x = (__m512bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32 }; > + } > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + (&fregs.zmm0)[i]._m512bf16[0] = m512bf16s[i].x; > + num_fregs = 8; > + WRAP_CALL (check_struct_passing1bf16) (m512bf16s[0], m512bf16s[1], m512bf16s[2], m512bf16s[3], > + m512bf16s[4], m512bf16s[5], m512bf16s[6], m512bf16s[7]); > + WRAP_CALL (check_struct_passing2bf16) (m512bf16_2s); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_unions.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_unions.c > new file mode 100644 > index 00000000000..3769b38aeb7 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_passing_unions.c > @@ -0,0 +1,222 @@ > +#include "bf16-zmm-check.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +union un1b > +{ > + __m512bf16 x; > + float f; > +}; > + > +union un1bb > +{ > + __m512bf16 x; > + __bf16 f; > +}; > + > +union un2b > +{ > + __m512bf16 x; > + double d; > +}; > + > +union un3b > +{ > + __m512bf16 x; > + __m128 v; > +}; > + > +union un4b > +{ > + __m512bf16 x; > + long double ld; > +}; > + > +union un5b > +{ > + __m512bf16 x; > + int i; > +}; > + > +union un6b > +{ > + __m512bf16 x; > + __m256 v; > +}; > + > +void > +check_union_passing1b (union un1b u1 ATTRIBUTE_UNUSED, > + union un1b u2 ATTRIBUTE_UNUSED, > + union un1b u3 ATTRIBUTE_UNUSED, > + union un1b u4 ATTRIBUTE_UNUSED, > + union un1b u5 ATTRIBUTE_UNUSED, > + union un1b u6 ATTRIBUTE_UNUSED, > + union un1b u7 ATTRIBUTE_UNUSED, > + union un1b u8 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m512_arguments; > +} > + > +void > +check_union_passing1bb (union un1bb u1 ATTRIBUTE_UNUSED, > + union un1bb u2 ATTRIBUTE_UNUSED, > + union un1bb u3 ATTRIBUTE_UNUSED, > + union un1bb u4 ATTRIBUTE_UNUSED, > + union un1bb u5 ATTRIBUTE_UNUSED, > + union un1bb u6 ATTRIBUTE_UNUSED, > + union un1bb u7 ATTRIBUTE_UNUSED, > + union un1bb u8 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m512_arguments; > +} > + > + > +void > +check_union_passing2b (union un2b u1 ATTRIBUTE_UNUSED, > + union un2b u2 ATTRIBUTE_UNUSED, > + union un2b u3 ATTRIBUTE_UNUSED, > + union un2b u4 ATTRIBUTE_UNUSED, > + union un2b u5 ATTRIBUTE_UNUSED, > + union un2b u6 ATTRIBUTE_UNUSED, > + union un2b u7 ATTRIBUTE_UNUSED, > + union un2b u8 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m512_arguments; > +} > + > +void > +check_union_passing3b (union un3b u1 ATTRIBUTE_UNUSED, > + union un3b u2 ATTRIBUTE_UNUSED, > + union un3b u3 ATTRIBUTE_UNUSED, > + union un3b u4 ATTRIBUTE_UNUSED, > + union un3b u5 ATTRIBUTE_UNUSED, > + union un3b u6 ATTRIBUTE_UNUSED, > + union un3b u7 ATTRIBUTE_UNUSED, > + union un3b u8 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m512_arguments; > +} > + > +void > +check_union_passing4b (union un4b u ATTRIBUTE_UNUSED) > +{ > + /* Check the passing on the stack by comparing the address of the > + stack elements to the expected place on the stack. */ > + assert ((unsigned long)&u.x == rsp+8); > + assert ((unsigned long)&u.ld == rsp+8); > +} > + > +void > +check_union_passing5b (union un5b u ATTRIBUTE_UNUSED) > +{ > + /* Check the passing on the stack by comparing the address of the > + stack elements to the expected place on the stack. */ > + assert ((unsigned long)&u.x == rsp+8); > + assert ((unsigned long)&u.i == rsp+8); > +} > + > +void > +check_union_passing6b (union un6b u1 ATTRIBUTE_UNUSED, > + union un6b u2 ATTRIBUTE_UNUSED, > + union un6b u3 ATTRIBUTE_UNUSED, > + union un6b u4 ATTRIBUTE_UNUSED, > + union un6b u5 ATTRIBUTE_UNUSED, > + union un6b u6 ATTRIBUTE_UNUSED, > + union un6b u7 ATTRIBUTE_UNUSED, > + union un6b u8 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m512_arguments; > +} > + > +#define check_union_passing1b WRAP_CALL(check_union_passing1b) > +#define check_union_passing1bf WRAP_CALL(check_union_passing1bf) > +#define check_union_passing1bb WRAP_CALL(check_union_passing1bb) > +#define check_union_passing2b WRAP_CALL(check_union_passing2b) > +#define check_union_passing3b WRAP_CALL(check_union_passing3b) > +#define check_union_passing4b WRAP_CALL(check_union_passing4b) > +#define check_union_passing5b WRAP_CALL(check_union_passing5b) > +#define check_union_passing6b WRAP_CALL(check_union_passing6b) > + > + > +static void > +do_test (void) > +{ > + __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32; > + union un1b u1b[8]; > + union un1bb u1bb[8]; > + union un2b u2b[8]; > + union un3b u3b[8]; > + union un4b u4b; > + union un5b u5b; > + union un6b u6b[8]; > + int i; > + > + for (i = 0; i < 8; i++) > + { > + u1b[i].x = (__m512bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32 }; > + } > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + (&fregs.zmm0)[i]._m512bf16[0] = u1b[i].x; > + num_fregs = 8; > + check_union_passing1b (u1b[0], u1b[1], u1b[2], u1b[3], > + u1b[4], u1b[5], u1b[6], u1b[7]); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u1bb[i].x = u1b[i].x; > + (&fregs.zmm0)[i]._m512bf16[0] = u1bb[i].x; > + } > + num_fregs = 8; > + check_union_passing1bb (u1bb[0], u1bb[1], u1bb[2], u1bb[3], > + u1bb[4], u1bb[5], u1bb[6], u1bb[7]); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u2b[i].x = u1bb[i].x; > + (&fregs.zmm0)[i]._m512bf16[0] = u2b[i].x; > + } > + num_fregs = 8; > + check_union_passing2b (u2b[0], u2b[1], u2b[2], u2b[3], > + u2b[4], u2b[5], u2b[6], u2b[7]); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u3b[i].x = u1b[i].x; > + (&fregs.zmm0)[i]._m512bf16[0] = u3b[i].x; > + } > + num_fregs = 8; > + check_union_passing3b (u3b[0], u3b[1], u3b[2], u3b[3], > + u3b[4], u3b[5], u3b[6], u3b[7]); > + > + check_union_passing4b (u4b); > + check_union_passing5b (u5b); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u6b[i].x = u1b[i].x; > + (&fregs.zmm0)[i]._m512bf16[0] = u6b[i].x; > + } > + num_fregs = 8; > + check_union_passing6b (u6b[0], u6b[1], u6b[2], u6b[3], > + u6b[4], u6b[5], u6b[6], u6b[7]); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_varargs-m512.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_varargs-m512.c > new file mode 100644 > index 00000000000..2be57b8b5fb > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/test_varargs-m512.c > @@ -0,0 +1,111 @@ > +/* Test variable number of 512-bit vector arguments passed to functions. */ > + > +#include > +#include "bf16-zmm-check.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > + > +/* This struct holds values for argument checking. */ > +struct > +{ > + ZMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; > +} values; > + > +char *pass; > +int failed = 0; > + > +#undef assert > +#define assert(c) do { \ > + if (!(c)) {failed++; printf ("failed %s\n", pass); } \ > +} while (0) > + > +#define compare(X1,X2,T) do { \ > + assert (memcmp (&X1, &X2, sizeof (T)) == 0); \ > +} while (0) > + > +void > +fun_check_passing_m512bf16_varargs (__m512bf16 i0, __m512bf16 i1, __m512bf16 i2, > + __m512bf16 i3, ...) > +{ > + /* Check argument values. */ > + void **fp = __builtin_frame_address (0); > + void *ra = __builtin_return_address (0); > + __m512bf16 *argp; > + > + compare (values.i0, i0, __m512bf16); > + compare (values.i1, i1, __m512bf16); > + compare (values.i2, i2, __m512bf16); > + compare (values.i3, i3, __m512bf16); > + > + /* Get the pointer to the return address on stack. */ > + while (*fp != ra) > + fp++; > + > + /* Skip the return address stack slot. */ > + argp = (__m512bf16 *)(((char *) fp) + 8); > + > + /* Check __m512bf16 arguments passed on stack. */ > + compare (values.i4, argp[0], __m512bf16); > + compare (values.i5, argp[1], __m512bf16); > + compare (values.i6, argp[2], __m512bf16); > + compare (values.i7, argp[3], __m512bf16); > + compare (values.i8, argp[4], __m512bf16); > + compare (values.i9, argp[5], __m512bf16); > + > + /* Check register contents. */ > + compare (fregs.zmm0, zmm_regs[0], __m512bf16); > + compare (fregs.zmm1, zmm_regs[1], __m512bf16); > + compare (fregs.zmm2, zmm_regs[2], __m512bf16); > + compare (fregs.zmm3, zmm_regs[3], __m512bf16); > +} > + > +#define def_check_int_passing_varargs(_i0, _i1, _i2, _i3, _i4, _i5, \ > + _i6, _i7, _i8, _i9, \ > + _func, TYPE) \ > + values.i0.TYPE[0] = _i0; \ > + values.i1.TYPE[0] = _i1; \ > + values.i2.TYPE[0] = _i2; \ > + values.i3.TYPE[0] = _i3; \ > + values.i4.TYPE[0] = _i4; \ > + values.i5.TYPE[0] = _i5; \ > + values.i6.TYPE[0] = _i6; \ > + values.i7.TYPE[0] = _i7; \ > + values.i8.TYPE[0] = _i8; \ > + values.i9.TYPE[0] = _i9; \ > + clear_struct_registers; \ > + fregs.F0.TYPE[0] = _i0; \ > + fregs.F1.TYPE[0] = _i1; \ > + fregs.F2.TYPE[0] = _i2; \ > + fregs.F3.TYPE[0] = _i3; \ > + WRAP_CALL(_func) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9); > + > +void > +test_m512bf16_varargs (void) > +{ > + __m512bf16 x[10]; > + __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32; > + int i; > + for (i = 0; i < 10; i++) > + x[i] = (__m512bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + bf17,bf18,bf19,bf20,bf21,bf22,bf23,bf24, > + bf25,bf26,bf27,bf28,bf29,bf30,bf31,bf32 }; > + pass = "m512bf16-varargs"; > + def_check_int_passing_varargs (x[0], x[1], x[2], x[3], x[4], x[5], > + x[6], x[7], x[8], x[9], > + fun_check_passing_m512bf16_varargs, > + _m512bf16); > +} > + > +void > +do_test (void) > +{ > + test_m512bf16_varargs (); > + if (failed) > + abort (); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/macros.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/macros.h > new file mode 100644 > index 00000000000..98fbc660f27 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/macros.h > @@ -0,0 +1,53 @@ > +#ifndef MACROS_H > + > +#define check_size(_t, _size) assert(sizeof(_t) == (_size)) > + > +#define check_align(_t, _align) assert(__alignof__(_t) == (_align)) > + > +#define check_align_lv(_t, _align) assert(__alignof__(_t) == (_align) \ > + && (((unsigned long)&(_t)) & ((_align) - 1) ) == 0) > + > +#define check_basic_struct_size_and_align(_type, _size, _align) { \ > + struct _str { _type dummy; } _t; \ > + check_size(_t, _size); \ > + check_align_lv(_t, _align); \ > +} > + > +#define check_array_size_and_align(_type, _size, _align) { \ > + _type _a[1]; _type _b[2]; _type _c[16]; \ > + struct _str { _type _a[1]; } _s; \ > + check_align_lv(_a[0], _align); \ > + check_size(_a, _size); \ > + check_size(_b, (_size*2)); \ > + check_size(_c, (_size*16)); \ > + check_size(_s, _size); \ > + check_align_lv(_s._a[0], _align); \ > +} > + > +#define check_basic_union_size_and_align(_type, _size, _align) { \ > + union _union { _type dummy; } _u; \ > + check_size(_u, _size); \ > + check_align_lv(_u, _align); \ > +} > + > +#define run_signed_tests2(_function, _arg1, _arg2) \ > + _function(_arg1, _arg2); \ > + _function(signed _arg1, _arg2); \ > + _function(unsigned _arg1, _arg2); > + > +#define run_signed_tests3(_function, _arg1, _arg2, _arg3) \ > + _function(_arg1, _arg2, _arg3); \ > + _function(signed _arg1, _arg2, _arg3); \ > + _function(unsigned _arg1, _arg2, _arg3); > + > +/* Check size of a struct and a union of three types. */ > + > +#define check_struct_and_union3(type1, type2, type3, struct_size, align_size) \ > +{ \ > + struct _str { type1 t1; type2 t2; type3 t3; } _t; \ > + union _uni { type1 t1; type2 t2; type3 t3; } _u; \ > + check_size(_t, struct_size); \ > + check_size(_u, align_size); \ > +} > + > +#endif // MACROS_H > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_3_element_struct_and_unions.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_3_element_struct_and_unions.c > new file mode 100644 > index 00000000000..0c58db101e5 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_3_element_struct_and_unions.c > @@ -0,0 +1,214 @@ > +/* This is an autogenerated file. Do not edit. */ > + > +#include "defines.h" > +#include "macros.h" > + > +/* Check structs and unions of all permutations of 3 basic types. */ > +int > +main (void) > +{ > + check_struct_and_union3(char, char, __bf16, 4, 2); > + check_struct_and_union3(char, __bf16, char, 6, 2); > + check_struct_and_union3(char, __bf16, __bf16, 6, 2); > + check_struct_and_union3(char, __bf16, int, 8, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(char, __bf16, long, 16, 8); > +#endif > + check_struct_and_union3(char, __bf16, long long, 16, 8); > + check_struct_and_union3(char, __bf16, float, 8, 4); > + check_struct_and_union3(char, __bf16, double, 16, 8); > + check_struct_and_union3(char, __bf16, long double, 32, 16); > + check_struct_and_union3(char, int, __bf16, 12, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(char, long, __bf16, 24, 8); > +#endif > + check_struct_and_union3(char, long long, __bf16, 24, 8); > + check_struct_and_union3(char, float, __bf16, 12, 4); > + check_struct_and_union3(char, double, __bf16, 24, 8); > + check_struct_and_union3(char, long double, __bf16, 48, 16); > + check_struct_and_union3(__bf16, char, char, 4, 2); > + check_struct_and_union3(__bf16, char, __bf16, 6, 2); > + check_struct_and_union3(__bf16, char, int, 8, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(__bf16, char, long, 16, 8); > +#endif > + check_struct_and_union3(__bf16, char, long long, 16, 8); > + check_struct_and_union3(__bf16, char, float, 8, 4); > + check_struct_and_union3(__bf16, char, double, 16, 8); > + check_struct_and_union3(__bf16, char, long double, 32, 16); > + check_struct_and_union3(__bf16, __bf16, char, 6, 2); > + check_struct_and_union3(__bf16, __bf16, __bf16, 6, 2); > + check_struct_and_union3(__bf16, __bf16, int, 8, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(__bf16, __bf16, long, 16, 8); > +#endif > + check_struct_and_union3(__bf16, __bf16, long long, 16, 8); > + check_struct_and_union3(__bf16, __bf16, float, 8, 4); > + check_struct_and_union3(__bf16, __bf16, double, 16, 8); > + check_struct_and_union3(__bf16, __bf16, long double, 32, 16); > + check_struct_and_union3(__bf16, int, char, 12, 4); > + check_struct_and_union3(__bf16, int, __bf16, 12, 4); > + check_struct_and_union3(__bf16, int, int, 12, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(__bf16, int, long, 16, 8); > +#endif > + check_struct_and_union3(__bf16, int, long long, 16, 8); > + check_struct_and_union3(__bf16, int, float, 12, 4); > + check_struct_and_union3(__bf16, int, double, 16, 8); > + check_struct_and_union3(__bf16, int, long double, 32, 16); > +#ifndef __ILP32__ > + check_struct_and_union3(__bf16, long, char, 24, 8); > + check_struct_and_union3(__bf16, long, __bf16, 24, 8); > + check_struct_and_union3(__bf16, long, int, 24, 8); > + check_struct_and_union3(__bf16, long, long, 24, 8); > + check_struct_and_union3(__bf16, long, long long, 24, 8); > + check_struct_and_union3(__bf16, long, float, 24, 8); > + check_struct_and_union3(__bf16, long, double, 24, 8); > +#endif > + check_struct_and_union3(__bf16, long, long double, 32, 16); > + check_struct_and_union3(__bf16, long long, char, 24, 8); > + check_struct_and_union3(__bf16, long long, __bf16, 24, 8); > + check_struct_and_union3(__bf16, long long, int, 24, 8); > + check_struct_and_union3(__bf16, long long, long, 24, 8); > + check_struct_and_union3(__bf16, long long, long long, 24, 8); > + check_struct_and_union3(__bf16, long long, float, 24, 8); > + check_struct_and_union3(__bf16, long long, double, 24, 8); > + check_struct_and_union3(__bf16, long long, long double, 32, 16); > + check_struct_and_union3(__bf16, float, char, 12, 4); > + check_struct_and_union3(__bf16, float, __bf16, 12, 4); > + check_struct_and_union3(__bf16, float, int, 12, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(__bf16, float, long, 16, 8); > +#endif > + check_struct_and_union3(__bf16, float, long long, 16, 8); > + check_struct_and_union3(__bf16, float, float, 12, 4); > + check_struct_and_union3(__bf16, float, double, 16, 8); > + check_struct_and_union3(__bf16, float, long double, 32, 16); > + check_struct_and_union3(__bf16, double, char, 24, 8); > + check_struct_and_union3(__bf16, double, __bf16, 24, 8); > + check_struct_and_union3(__bf16, double, int, 24, 8); > + check_struct_and_union3(__bf16, double, long, 24, 8); > + check_struct_and_union3(__bf16, double, long long, 24, 8); > + check_struct_and_union3(__bf16, double, float, 24, 8); > + check_struct_and_union3(__bf16, double, double, 24, 8); > + check_struct_and_union3(__bf16, double, long double, 32, 16); > + check_struct_and_union3(__bf16, long double, char, 48, 16); > + check_struct_and_union3(__bf16, long double, __bf16, 48, 16); > + check_struct_and_union3(__bf16, long double, int, 48, 16); > + check_struct_and_union3(__bf16, long double, long, 48, 16); > + check_struct_and_union3(__bf16, long double, long long, 48, 16); > + check_struct_and_union3(__bf16, long double, float, 48, 16); > + check_struct_and_union3(__bf16, long double, double, 48, 16); > + check_struct_and_union3(__bf16, long double, long double, 48, 16); > + check_struct_and_union3(int, char, __bf16, 8, 4); > + check_struct_and_union3(int, __bf16, char, 8, 4); > + check_struct_and_union3(int, __bf16, __bf16, 8, 4); > + check_struct_and_union3(int, __bf16, int, 12, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(int, __bf16, long, 16, 8); > +#endif > + check_struct_and_union3(int, __bf16, long long, 16, 8); > + check_struct_and_union3(int, __bf16, float, 12, 4); > + check_struct_and_union3(int, __bf16, double, 16, 8); > + check_struct_and_union3(int, __bf16, long double, 32, 16); > + check_struct_and_union3(int, int, __bf16, 12, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(int, long, __bf16, 24, 8); > +#endif > + check_struct_and_union3(int, long long, __bf16, 24, 8); > + check_struct_and_union3(int, float, __bf16, 12, 4); > + check_struct_and_union3(int, double, __bf16, 24, 8); > + check_struct_and_union3(int, long double, __bf16, 48, 16); > +#ifndef __ILP32__ > + check_struct_and_union3(long, char, __bf16, 16, 8); > + check_struct_and_union3(long, __bf16, char, 16, 8); > + check_struct_and_union3(long, __bf16, __bf16, 16, 8); > + check_struct_and_union3(long, __bf16, int, 16, 8); > + check_struct_and_union3(long, __bf16, long, 24, 8); > + check_struct_and_union3(long, __bf16, long long, 24, 8); > + check_struct_and_union3(long, __bf16, float, 16, 8); > + check_struct_and_union3(long, __bf16, double, 24, 8); > +#endif > + check_struct_and_union3(long, __bf16, long double, 32, 16); > +#ifndef __ILP32__ > + check_struct_and_union3(long, int, __bf16, 16, 8); > + check_struct_and_union3(long, long, __bf16, 24, 8); > + check_struct_and_union3(long, long long, __bf16, 24, 8); > + check_struct_and_union3(long, float, __bf16, 16, 8); > + check_struct_and_union3(long, double, __bf16, 24, 8); > +#endif > + check_struct_and_union3(long, long double, __bf16, 48, 16); > + check_struct_and_union3(long long, char, __bf16, 16, 8); > + check_struct_and_union3(long long, __bf16, char, 16, 8); > + check_struct_and_union3(long long, __bf16, __bf16, 16, 8); > + check_struct_and_union3(long long, __bf16, int, 16, 8); > +#ifndef __ILP32__ > + check_struct_and_union3(long long, __bf16, long, 24, 8); > +#endif > + check_struct_and_union3(long long, __bf16, long long, 24, 8); > + check_struct_and_union3(long long, __bf16, float, 16, 8); > + check_struct_and_union3(long long, __bf16, double, 24, 8); > + check_struct_and_union3(long long, __bf16, long double, 32, 16); > + check_struct_and_union3(long long, int, __bf16, 16, 8); > +#ifndef __ILP32__ > + check_struct_and_union3(long long, long, __bf16, 24, 8); > +#endif > + check_struct_and_union3(long long, long long, __bf16, 24, 8); > + check_struct_and_union3(long long, float, __bf16, 16, 8); > + check_struct_and_union3(long long, double, __bf16, 24, 8); > + check_struct_and_union3(long long, long double, __bf16, 48, 16); > + check_struct_and_union3(float, char, __bf16, 8, 4); > + check_struct_and_union3(float, __bf16, char, 8, 4); > + check_struct_and_union3(float, __bf16, __bf16, 8, 4); > + check_struct_and_union3(float, __bf16, int, 12, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(float, __bf16, long, 16, 8); > +#endif > + check_struct_and_union3(float, __bf16, long long, 16, 8); > + check_struct_and_union3(float, __bf16, float, 12, 4); > + check_struct_and_union3(float, __bf16, double, 16, 8); > + check_struct_and_union3(float, __bf16, long double, 32, 16); > + check_struct_and_union3(float, int, __bf16, 12, 4); > +#ifndef __ILP32__ > + check_struct_and_union3(float, long, __bf16, 24, 8); > +#endif > + check_struct_and_union3(float, long long, __bf16, 24, 8); > + check_struct_and_union3(float, float, __bf16, 12, 4); > + check_struct_and_union3(float, double, __bf16, 24, 8); > + check_struct_and_union3(float, long double, __bf16, 48, 16); > + check_struct_and_union3(double, char, __bf16, 16, 8); > + check_struct_and_union3(double, __bf16, char, 16, 8); > + check_struct_and_union3(double, __bf16, __bf16, 16, 8); > + check_struct_and_union3(double, __bf16, int, 16, 8); > +#ifndef __ILP32__ > + check_struct_and_union3(double, __bf16, long, 24, 8); > +#endif > + check_struct_and_union3(double, __bf16, long long, 24, 8); > + check_struct_and_union3(double, __bf16, float, 16, 8); > + check_struct_and_union3(double, __bf16, double, 24, 8); > + check_struct_and_union3(double, __bf16, long double, 32, 16); > + check_struct_and_union3(double, int, __bf16, 16, 8); > +#ifndef __ILP32__ > + check_struct_and_union3(double, long, __bf16, 24, 8); > +#endif > + check_struct_and_union3(double, long long, __bf16, 24, 8); > + check_struct_and_union3(double, float, __bf16, 16, 8); > + check_struct_and_union3(double, double, __bf16, 24, 8); > + check_struct_and_union3(double, long double, __bf16, 48, 16); > + check_struct_and_union3(long double, char, __bf16, 32, 16); > + check_struct_and_union3(long double, __bf16, char, 32, 16); > + check_struct_and_union3(long double, __bf16, __bf16, 32, 16); > + check_struct_and_union3(long double, __bf16, int, 32, 16); > + check_struct_and_union3(long double, __bf16, long, 32, 16); > + check_struct_and_union3(long double, __bf16, long long, 32, 16); > + check_struct_and_union3(long double, __bf16, float, 32, 16); > + check_struct_and_union3(long double, __bf16, double, 32, 16); > + check_struct_and_union3(long double, __bf16, long double, 48, 16); > + check_struct_and_union3(long double, int, __bf16, 32, 16); > + check_struct_and_union3(long double, long, __bf16, 32, 16); > + check_struct_and_union3(long double, long long, __bf16, 32, 16); > + check_struct_and_union3(long double, float, __bf16, 32, 16); > + check_struct_and_union3(long double, double, __bf16, 32, 16); > + check_struct_and_union3(long double, long double, __bf16, 48, 16); > + return 0; > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_alignment.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_alignment.c > new file mode 100644 > index 00000000000..6490a5228ca > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_alignment.c > @@ -0,0 +1,14 @@ > +/* This checks alignment of basic types. */ > + > +#include "defines.h" > +#include "macros.h" > + > + > +int > +main (void) > +{ > + /* __bf16 point types. */ > + check_align(__bf16, TYPE_ALIGN_BF16); > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_array_size_and_align.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_array_size_and_align.c > new file mode 100644 > index 00000000000..c004c35bb83 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_array_size_and_align.c > @@ -0,0 +1,13 @@ > +/* This checks . */ > + > +#include "defines.h" > +#include "macros.h" > + > + > +int > +main (void) > +{ > + check_array_size_and_align(__bf16, TYPE_SIZE_BF16, TYPE_ALIGN_BF16); > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_returning.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_returning.c > new file mode 100644 > index 00000000000..cfea2224733 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_returning.c > @@ -0,0 +1,20 @@ > +#include "bf16-check.h" > +#include "defines.h" > +#include "macros.h" > +#include "args.h" > + > +__bf16 > +fun_test_returning_bf16 (void) > +{ > + __bf16 b = make_f32_bf16 (72.0f); > + volatile_var++; > + return b; > +} > + > +static void > +do_test (void) > +{ > + __bf16 var = WRAP_RET (fun_test_returning_bf16) (); > + assert (check_bf16_float (xmm_regs[0].___bf16[0], 72.0f) == 1); > + assert (check_bf16_float (var, 72.0f) == 1); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_sizes.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_sizes.c > new file mode 100644 > index 00000000000..b81a8d971b5 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_sizes.c > @@ -0,0 +1,14 @@ > +/* This checks sizes of basic types. */ > + > +#include "defines.h" > +#include "macros.h" > + > + > +int > +main (void) > +{ > + /* Floating point types. */ > + check_size(__bf16, TYPE_SIZE_BF16); > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_struct_size_and_align.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_struct_size_and_align.c > new file mode 100644 > index 00000000000..f282506703c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_struct_size_and_align.c > @@ -0,0 +1,14 @@ > +/* This checks size and alignment of structs with a single basic type > + element. All basic types are checked. */ > + > +#include "bf16-check.h" > +#include "defines.h" > +#include "macros.h" > + > + > +static void > +do_test (void) > +{ > + /* Floating point types. */ > + check_basic_struct_size_and_align(__bf16, TYPE_SIZE_BF16, TYPE_ALIGN_BF16); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_union_size_and_align.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_union_size_and_align.c > new file mode 100644 > index 00000000000..03afa68c0e4 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_basic_union_size_and_align.c > @@ -0,0 +1,12 @@ > +/* Test of simple unions, size and alignment. */ > + > +#include "bf16-check.h" > +#include "defines.h" > +#include "macros.h" > + > +static void > +do_test (void) > +{ > + /* Floating point types. */ > + check_basic_union_size_and_align(__bf16, TYPE_SIZE_BF16, TYPE_ALIGN_BF16); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_m128_returning.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_m128_returning.c > new file mode 100644 > index 00000000000..64857ce7b71 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_m128_returning.c > @@ -0,0 +1,38 @@ > +#include > +#include "bf16-check.h" > +#include "defines.h" > +#include "macros.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +volatile __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8; > + > +__m128bf16 > +fun_test_returning___m128bf16 (void) > +{ > + volatile_var++; > + return (__m128bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8 }; > +} > + > +__m128bf16 test_128bf16; > + > +static void > +do_test (void) > +{ > + unsigned failed = 0; > + XMM_T xmmt1, xmmt2; > + > + clear_struct_registers; > + test_128bf16 = (__m128bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8 }; > + xmmt1._m128bf16[0] = test_128bf16; > + xmmt2._m128bf16[0] = WRAP_RET (fun_test_returning___m128bf16)(); > + if (xmmt1._longlong[0] != xmmt2._longlong[0] > + || xmmt1._longlong[0] != xmm_regs[0]._longlong[0]) > + printf ("fail m128bf16\n"), failed++; > + > + if (failed) > + abort (); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_floats.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_floats.c > new file mode 100644 > index 00000000000..fe08042286b > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_floats.c > @@ -0,0 +1,312 @@ > +/* This is an autogenerated file. Do not edit. */ > + > +#include "bf16-check.h" > +#include "defines.h" > +#include "macros.h" > +#include "args.h" > + > +struct IntegerRegisters iregs; > +struct FloatRegisters fregs; > +unsigned int num_iregs, num_fregs; > + > +/* This struct holds values for argument checking. */ > +struct > +{ > + __bf16 f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, > + f15, f16, f17, f18, f19, f20, f21, f22, f23; > +} values___bf16; > + > +void > +fun_check_bf16_passing_8_values (__bf16 f0 ATTRIBUTE_UNUSED, > + __bf16 f1 ATTRIBUTE_UNUSED, > + __bf16 f2 ATTRIBUTE_UNUSED, > + __bf16 f3 ATTRIBUTE_UNUSED, > + __bf16 f4 ATTRIBUTE_UNUSED, > + __bf16 f5 ATTRIBUTE_UNUSED, > + __bf16 f6 ATTRIBUTE_UNUSED, > + __bf16 f7 ATTRIBUTE_UNUSED) > +{ > + /* Check argument values. */ > + check_bf16 (values___bf16.f0, f0); > + check_bf16 (values___bf16.f1, f1); > + check_bf16 (values___bf16.f2, f2); > + check_bf16 (values___bf16.f3, f3); > + check_bf16 (values___bf16.f4, f4); > + check_bf16 (values___bf16.f5, f5); > + check_bf16 (values___bf16.f6, f6); > + check_bf16 (values___bf16.f7, f7); > +} > + > +void > +fun_check_bf16_passing_8_regs (__bf16 f0 ATTRIBUTE_UNUSED, > + __bf16 f1 ATTRIBUTE_UNUSED, > + __bf16 f2 ATTRIBUTE_UNUSED, > + __bf16 f3 ATTRIBUTE_UNUSED, > + __bf16 f4 ATTRIBUTE_UNUSED, > + __bf16 f5 ATTRIBUTE_UNUSED, > + __bf16 f6 ATTRIBUTE_UNUSED, > + __bf16 f7 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_bf16_arguments; > +} > + > +void > +fun_check_bf16_passing_16_values (__bf16 f0 ATTRIBUTE_UNUSED, > + __bf16 f1 ATTRIBUTE_UNUSED, > + __bf16 f2 ATTRIBUTE_UNUSED, > + __bf16 f3 ATTRIBUTE_UNUSED, > + __bf16 f4 ATTRIBUTE_UNUSED, > + __bf16 f5 ATTRIBUTE_UNUSED, > + __bf16 f6 ATTRIBUTE_UNUSED, > + __bf16 f7 ATTRIBUTE_UNUSED, > + __bf16 f8 ATTRIBUTE_UNUSED, > + __bf16 f9 ATTRIBUTE_UNUSED, > + __bf16 f10 ATTRIBUTE_UNUSED, > + __bf16 f11 ATTRIBUTE_UNUSED, > + __bf16 f12 ATTRIBUTE_UNUSED, > + __bf16 f13 ATTRIBUTE_UNUSED, > + __bf16 f14 ATTRIBUTE_UNUSED, > + __bf16 f15 ATTRIBUTE_UNUSED) > +{ > + /* Check argument values. */ > + check_bf16 (values___bf16.f0, f0); > + check_bf16 (values___bf16.f1, f1); > + check_bf16 (values___bf16.f2, f2); > + check_bf16 (values___bf16.f3, f3); > + check_bf16 (values___bf16.f4, f4); > + check_bf16 (values___bf16.f5, f5); > + check_bf16 (values___bf16.f6, f6); > + check_bf16 (values___bf16.f7, f7); > + check_bf16 (values___bf16.f8, f8); > + check_bf16 (values___bf16.f9, f9); > + check_bf16 (values___bf16.f10, f10); > + check_bf16 (values___bf16.f11, f11); > + check_bf16 (values___bf16.f12, f12); > + check_bf16 (values___bf16.f13, f13); > + check_bf16 (values___bf16.f14, f14); > + check_bf16 (values___bf16.f15, f15); > +} > + > +void > +fun_check_bf16_passing_16_regs (__bf16 f0 ATTRIBUTE_UNUSED, > + __bf16 f1 ATTRIBUTE_UNUSED, > + __bf16 f2 ATTRIBUTE_UNUSED, > + __bf16 f3 ATTRIBUTE_UNUSED, > + __bf16 f4 ATTRIBUTE_UNUSED, > + __bf16 f5 ATTRIBUTE_UNUSED, > + __bf16 f6 ATTRIBUTE_UNUSED, > + __bf16 f7 ATTRIBUTE_UNUSED, > + __bf16 f8 ATTRIBUTE_UNUSED, > + __bf16 f9 ATTRIBUTE_UNUSED, > + __bf16 f10 ATTRIBUTE_UNUSED, > + __bf16 f11 ATTRIBUTE_UNUSED, > + __bf16 f12 ATTRIBUTE_UNUSED, > + __bf16 f13 ATTRIBUTE_UNUSED, > + __bf16 f14 ATTRIBUTE_UNUSED, > + __bf16 f15 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_bf16_arguments; > +} > + > +void > +fun_check_bf16_passing_20_values (__bf16 f0 ATTRIBUTE_UNUSED, > + __bf16 f1 ATTRIBUTE_UNUSED, > + __bf16 f2 ATTRIBUTE_UNUSED, > + __bf16 f3 ATTRIBUTE_UNUSED, > + __bf16 f4 ATTRIBUTE_UNUSED, > + __bf16 f5 ATTRIBUTE_UNUSED, > + __bf16 f6 ATTRIBUTE_UNUSED, > + __bf16 f7 ATTRIBUTE_UNUSED, > + __bf16 f8 ATTRIBUTE_UNUSED, > + __bf16 f9 ATTRIBUTE_UNUSED, > + __bf16 f10 ATTRIBUTE_UNUSED, > + __bf16 f11 ATTRIBUTE_UNUSED, > + __bf16 f12 ATTRIBUTE_UNUSED, > + __bf16 f13 ATTRIBUTE_UNUSED, > + __bf16 f14 ATTRIBUTE_UNUSED, > + __bf16 f15 ATTRIBUTE_UNUSED, > + __bf16 f16 ATTRIBUTE_UNUSED, > + __bf16 f17 ATTRIBUTE_UNUSED, > + __bf16 f18 ATTRIBUTE_UNUSED, > + __bf16 f19 ATTRIBUTE_UNUSED) > +{ > + /* Check argument values. */ > + check_bf16 (values___bf16.f0, f0); > + check_bf16 (values___bf16.f1, f1); > + check_bf16 (values___bf16.f2, f2); > + check_bf16 (values___bf16.f3, f3); > + check_bf16 (values___bf16.f4, f4); > + check_bf16 (values___bf16.f5, f5); > + check_bf16 (values___bf16.f6, f6); > + check_bf16 (values___bf16.f7, f7); > + check_bf16 (values___bf16.f8, f8); > + check_bf16 (values___bf16.f9, f9); > + check_bf16 (values___bf16.f10, f10); > + check_bf16 (values___bf16.f11, f11); > + check_bf16 (values___bf16.f12, f12); > + check_bf16 (values___bf16.f13, f13); > + check_bf16 (values___bf16.f14, f14); > + check_bf16 (values___bf16.f15, f15); > + check_bf16 (values___bf16.f16, f16); > + check_bf16 (values___bf16.f17, f17); > + check_bf16 (values___bf16.f18, f18); > + check_bf16 (values___bf16.f19, f19); > +} > + > +void > +fun_check_bf16_passing_20_regs (__bf16 f0 ATTRIBUTE_UNUSED, > + __bf16 f1 ATTRIBUTE_UNUSED, > + __bf16 f2 ATTRIBUTE_UNUSED, > + __bf16 f3 ATTRIBUTE_UNUSED, > + __bf16 f4 ATTRIBUTE_UNUSED, > + __bf16 f5 ATTRIBUTE_UNUSED, > + __bf16 f6 ATTRIBUTE_UNUSED, > + __bf16 f7 ATTRIBUTE_UNUSED, > + __bf16 f8 ATTRIBUTE_UNUSED, > + __bf16 f9 ATTRIBUTE_UNUSED, > + __bf16 f10 ATTRIBUTE_UNUSED, > + __bf16 f11 ATTRIBUTE_UNUSED, > + __bf16 f12 ATTRIBUTE_UNUSED, > + __bf16 f13 ATTRIBUTE_UNUSED, > + __bf16 f14 ATTRIBUTE_UNUSED, > + __bf16 f15 ATTRIBUTE_UNUSED, > + __bf16 f16 ATTRIBUTE_UNUSED, > + __bf16 f17 ATTRIBUTE_UNUSED, > + __bf16 f18 ATTRIBUTE_UNUSED, > + __bf16 f19 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_bf16_arguments; > +} > + > +#define def_check_bf16_passing8(_f0, _f1, _f2, _f3, _f4, _f5, _f6,\ > + _f7, _func1, _func2, TYPE) \ > + values_ ## TYPE .f0 = _f0; \ > + values_ ## TYPE .f1 = _f1; \ > + values_ ## TYPE .f2 = _f2; \ > + values_ ## TYPE .f3 = _f3; \ > + values_ ## TYPE .f4 = _f4; \ > + values_ ## TYPE .f5 = _f5; \ > + values_ ## TYPE .f6 = _f6; \ > + values_ ## TYPE .f7 = _f7; \ > + WRAP_CALL(_func1) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7); \ > + clear_float_registers; \ > + fregs.F0._ ## TYPE [0] = _f0; \ > + fregs.F1._ ## TYPE [0] = _f1; \ > + fregs.F2._ ## TYPE [0] = _f2; \ > + fregs.F3._ ## TYPE [0] = _f3; \ > + fregs.F4._ ## TYPE [0] = _f4; \ > + fregs.F5._ ## TYPE [0] = _f5; \ > + fregs.F6._ ## TYPE [0] = _f6; \ > + fregs.F7._ ## TYPE [0] = _f7; \ > + num_fregs = 8; \ > + WRAP_CALL(_func2) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7); > + > +#define def_check_bf16_passing16(_f0, _f1, _f2, _f3, _f4, _f5, _f6, \ > + _f7, _f8, _f9, _f10, _f11, _f12, _f13, \ > + _f14, _f15, _func1, _func2, TYPE) \ > + values_ ## TYPE .f0 = _f0; \ > + values_ ## TYPE .f1 = _f1; \ > + values_ ## TYPE .f2 = _f2; \ > + values_ ## TYPE .f3 = _f3; \ > + values_ ## TYPE .f4 = _f4; \ > + values_ ## TYPE .f5 = _f5; \ > + values_ ## TYPE .f6 = _f6; \ > + values_ ## TYPE .f7 = _f7; \ > + values_ ## TYPE .f8 = _f8; \ > + values_ ## TYPE .f9 = _f9; \ > + values_ ## TYPE .f10 = _f10; \ > + values_ ## TYPE .f11 = _f11; \ > + values_ ## TYPE .f12 = _f12; \ > + values_ ## TYPE .f13 = _f13; \ > + values_ ## TYPE .f14 = _f14; \ > + values_ ## TYPE .f15 = _f15; \ > + WRAP_CALL(_func1) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, \ > + _f10, _f11, _f12, _f13, _f14, _f15); \ > + clear_float_registers; \ > + fregs.F0._ ## TYPE [0] = _f0; \ > + fregs.F1._ ## TYPE [0] = _f1; \ > + fregs.F2._ ## TYPE [0] = _f2; \ > + fregs.F3._ ## TYPE [0] = _f3; \ > + fregs.F4._ ## TYPE [0] = _f4; \ > + fregs.F5._ ## TYPE [0] = _f5; \ > + fregs.F6._ ## TYPE [0] = _f6; \ > + fregs.F7._ ## TYPE [0] = _f7; \ > + num_fregs = 8; \ > + WRAP_CALL(_func2) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, \ > + _f10, _f11, _f12, _f13, _f14, _f15); > + > +#define def_check_bf16_passing20(_f0, _f1, _f2, _f3, _f4, _f5, _f6, \ > + _f7, _f8, _f9, _f10, _f11, _f12, \ > + _f13, _f14, _f15, _f16, _f17, \ > + _f18, _f19, _func1, _func2, TYPE) \ > + values_ ## TYPE .f0 = _f0; \ > + values_ ## TYPE .f1 = _f1; \ > + values_ ## TYPE .f2 = _f2; \ > + values_ ## TYPE .f3 = _f3; \ > + values_ ## TYPE .f4 = _f4; \ > + values_ ## TYPE .f5 = _f5; \ > + values_ ## TYPE .f6 = _f6; \ > + values_ ## TYPE .f7 = _f7; \ > + values_ ## TYPE .f8 = _f8; \ > + values_ ## TYPE .f9 = _f9; \ > + values_ ## TYPE .f10 = _f10; \ > + values_ ## TYPE .f11 = _f11; \ > + values_ ## TYPE .f12 = _f12; \ > + values_ ## TYPE .f13 = _f13; \ > + values_ ## TYPE .f14 = _f14; \ > + values_ ## TYPE .f15 = _f15; \ > + values_ ## TYPE .f16 = _f16; \ > + values_ ## TYPE .f17 = _f17; \ > + values_ ## TYPE .f18 = _f18; \ > + values_ ## TYPE .f19 = _f19; \ > + WRAP_CALL(_func1) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, \ > + _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, \ > + _f17, _f18, _f19); \ > + clear_float_registers; \ > + fregs.F0._ ## TYPE [0] = _f0; \ > + fregs.F1._ ## TYPE [0] = _f1; \ > + fregs.F2._ ## TYPE [0] = _f2; \ > + fregs.F3._ ## TYPE [0] = _f3; \ > + fregs.F4._ ## TYPE [0] = _f4; \ > + fregs.F5._ ## TYPE [0] = _f5; \ > + fregs.F6._ ## TYPE [0] = _f6; \ > + fregs.F7._ ## TYPE [0] = _f7; \ > + num_fregs = 8; \ > + WRAP_CALL(_func2) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, \ > + _f10, _f11, _f12, _f13, _f14, _f15, _f16, _f17, \ > + _f18, _f19); > + > +volatile __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9, bf10, > + bf11,bf12,bf13,bf14,bf15,bf16,bf17,bf18,bf19,bf20; > + > +void > +test_bf16_on_stack () > +{ > + def_check_bf16_passing8 (bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + fun_check_bf16_passing_8_values, > + fun_check_bf16_passing_8_regs, __bf16); > + > + def_check_bf16_passing16 (bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16, > + fun_check_bf16_passing_16_values, > + fun_check_bf16_passing_16_regs, __bf16); > +} > + > +void > +test_too_many_bf16 () > +{ > + def_check_bf16_passing20 (bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9, bf10, > + bf11,bf12,bf13,bf14,bf15,bf16,bf17,bf18,bf19,bf20, > + fun_check_bf16_passing_20_values, > + fun_check_bf16_passing_20_regs, __bf16); > +} > + > +static void > +do_test (void) > +{ > + test_bf16_on_stack (); > + test_too_many_bf16 (); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_m128.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_m128.c > new file mode 100644 > index 00000000000..298b644e93d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_m128.c > @@ -0,0 +1,238 @@ > +#include > +#include "bf16-check.h" > +#include "defines.h" > +#include "macros.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +/* This struct holds values for argument checking. */ > +struct > +{ > + XMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, > + i16, i17, i18, i19, i20, i21, i22, i23; > +} values; > + > +char *pass; > +int failed = 0; > + > +#undef assert > +#define assert(c) do { \ > + if (!(c)) {failed++; printf ("failed %s\n", pass); } \ > +} while (0) > + > +#define compare(X1,X2,T) do { \ > + assert (memcmp (&X1, &X2, sizeof (T)) == 0); \ > +} while (0) > + > +void > +fun_check_passing_m128bf16_8_values (__m128bf16 i0 ATTRIBUTE_UNUSED, > + __m128bf16 i1 ATTRIBUTE_UNUSED, > + __m128bf16 i2 ATTRIBUTE_UNUSED, > + __m128bf16 i3 ATTRIBUTE_UNUSED, > + __m128bf16 i4 ATTRIBUTE_UNUSED, > + __m128bf16 i5 ATTRIBUTE_UNUSED, > + __m128bf16 i6 ATTRIBUTE_UNUSED, > + __m128bf16 i7 ATTRIBUTE_UNUSED) > +{ > + /* Check argument values. */ > + compare (values.i0, i0, __m128bf16); > + compare (values.i1, i1, __m128bf16); > + compare (values.i2, i2, __m128bf16); > + compare (values.i3, i3, __m128bf16); > + compare (values.i4, i4, __m128bf16); > + compare (values.i5, i5, __m128bf16); > + compare (values.i6, i6, __m128bf16); > + compare (values.i7, i7, __m128bf16); > +} > + > +void > +fun_check_passing_m128bf16_8_regs (__m128bf16 i0 ATTRIBUTE_UNUSED, > + __m128bf16 i1 ATTRIBUTE_UNUSED, > + __m128bf16 i2 ATTRIBUTE_UNUSED, > + __m128bf16 i3 ATTRIBUTE_UNUSED, > + __m128bf16 i4 ATTRIBUTE_UNUSED, > + __m128bf16 i5 ATTRIBUTE_UNUSED, > + __m128bf16 i6 ATTRIBUTE_UNUSED, > + __m128bf16 i7 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m128_arguments; > +} > + > +void > +fun_check_passing_m128bf16_20_values (__m128bf16 i0 ATTRIBUTE_UNUSED, > + __m128bf16 i1 ATTRIBUTE_UNUSED, > + __m128bf16 i2 ATTRIBUTE_UNUSED, > + __m128bf16 i3 ATTRIBUTE_UNUSED, > + __m128bf16 i4 ATTRIBUTE_UNUSED, > + __m128bf16 i5 ATTRIBUTE_UNUSED, > + __m128bf16 i6 ATTRIBUTE_UNUSED, > + __m128bf16 i7 ATTRIBUTE_UNUSED, > + __m128bf16 i8 ATTRIBUTE_UNUSED, > + __m128bf16 i9 ATTRIBUTE_UNUSED, > + __m128bf16 i10 ATTRIBUTE_UNUSED, > + __m128bf16 i11 ATTRIBUTE_UNUSED, > + __m128bf16 i12 ATTRIBUTE_UNUSED, > + __m128bf16 i13 ATTRIBUTE_UNUSED, > + __m128bf16 i14 ATTRIBUTE_UNUSED, > + __m128bf16 i15 ATTRIBUTE_UNUSED, > + __m128bf16 i16 ATTRIBUTE_UNUSED, > + __m128bf16 i17 ATTRIBUTE_UNUSED, > + __m128bf16 i18 ATTRIBUTE_UNUSED, > + __m128bf16 i19 ATTRIBUTE_UNUSED) > +{ > + /* Check argument values. */ > + compare (values.i0, i0, __m128bf16); > + compare (values.i1, i1, __m128bf16); > + compare (values.i2, i2, __m128bf16); > + compare (values.i3, i3, __m128bf16); > + compare (values.i4, i4, __m128bf16); > + compare (values.i5, i5, __m128bf16); > + compare (values.i6, i6, __m128bf16); > + compare (values.i7, i7, __m128bf16); > + compare (values.i8, i8, __m128bf16); > + compare (values.i9, i9, __m128bf16); > + compare (values.i10, i10, __m128bf16); > + compare (values.i11, i11, __m128bf16); > + compare (values.i12, i12, __m128bf16); > + compare (values.i13, i13, __m128bf16); > + compare (values.i14, i14, __m128bf16); > + compare (values.i15, i15, __m128bf16); > + compare (values.i16, i16, __m128bf16); > + compare (values.i17, i17, __m128bf16); > + compare (values.i18, i18, __m128bf16); > + compare (values.i19, i19, __m128bf16); > +} > + > +void > +fun_check_passing_m128bf16_20_regs (__m128bf16 i0 ATTRIBUTE_UNUSED, > + __m128bf16 i1 ATTRIBUTE_UNUSED, > + __m128bf16 i2 ATTRIBUTE_UNUSED, > + __m128bf16 i3 ATTRIBUTE_UNUSED, > + __m128bf16 i4 ATTRIBUTE_UNUSED, > + __m128bf16 i5 ATTRIBUTE_UNUSED, > + __m128bf16 i6 ATTRIBUTE_UNUSED, > + __m128bf16 i7 ATTRIBUTE_UNUSED, > + __m128bf16 i8 ATTRIBUTE_UNUSED, > + __m128bf16 i9 ATTRIBUTE_UNUSED, > + __m128bf16 i10 ATTRIBUTE_UNUSED, > + __m128bf16 i11 ATTRIBUTE_UNUSED, > + __m128bf16 i12 ATTRIBUTE_UNUSED, > + __m128bf16 i13 ATTRIBUTE_UNUSED, > + __m128bf16 i14 ATTRIBUTE_UNUSED, > + __m128bf16 i15 ATTRIBUTE_UNUSED, > + __m128bf16 i16 ATTRIBUTE_UNUSED, > + __m128bf16 i17 ATTRIBUTE_UNUSED, > + __m128bf16 i18 ATTRIBUTE_UNUSED, > + __m128bf16 i19 ATTRIBUTE_UNUSED) > +{ > + /* Check register contents. */ > + check_m128_arguments; > +} > + > +#define def_check_int_passing8(_i0, _i1, _i2, _i3, \ > + _i4, _i5, _i6, _i7, \ > + _func1, _func2, TYPE) \ > + values.i0.TYPE[0] = _i0; \ > + values.i1.TYPE[0] = _i1; \ > + values.i2.TYPE[0] = _i2; \ > + values.i3.TYPE[0] = _i3; \ > + values.i4.TYPE[0] = _i4; \ > + values.i5.TYPE[0] = _i5; \ > + values.i6.TYPE[0] = _i6; \ > + values.i7.TYPE[0] = _i7; \ > + WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7); \ > + clear_float_registers; \ > + fregs.F0.TYPE[0] = _i0; \ > + fregs.F1.TYPE[0] = _i1; \ > + fregs.F2.TYPE[0] = _i2; \ > + fregs.F3.TYPE[0] = _i3; \ > + fregs.F4.TYPE[0] = _i4; \ > + fregs.F5.TYPE[0] = _i5; \ > + fregs.F6.TYPE[0] = _i6; \ > + fregs.F7.TYPE[0] = _i7; \ > + num_fregs = 8; \ > + WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7); > + > +#define def_check_int_passing20(_i0, _i1, _i2, _i3, _i4, _i5, _i6, \ > + _i7, _i8, _i9, _i10, _i11, _i12, _i13, \ > + _i14, _i15, _i16, _i17, _i18, _i19, \ > + _func1, _func2, TYPE) \ > + values.i0.TYPE[0] = _i0; \ > + values.i1.TYPE[0] = _i1; \ > + values.i2.TYPE[0] = _i2; \ > + values.i3.TYPE[0] = _i3; \ > + values.i4.TYPE[0] = _i4; \ > + values.i5.TYPE[0] = _i5; \ > + values.i6.TYPE[0] = _i6; \ > + values.i7.TYPE[0] = _i7; \ > + values.i8.TYPE[0] = _i8; \ > + values.i9.TYPE[0] = _i9; \ > + values.i10.TYPE[0] = _i10; \ > + values.i11.TYPE[0] = _i11; \ > + values.i12.TYPE[0] = _i12; \ > + values.i13.TYPE[0] = _i13; \ > + values.i14.TYPE[0] = _i14; \ > + values.i15.TYPE[0] = _i15; \ > + values.i16.TYPE[0] = _i16; \ > + values.i17.TYPE[0] = _i17; \ > + values.i18.TYPE[0] = _i18; \ > + values.i19.TYPE[0] = _i19; \ > + WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ > + _i9, _i10, _i11, _i12, _i13, _i14, _i15, _i16, \ > + _i17, _i18, _i19); \ > + clear_float_registers; \ > + fregs.F0.TYPE[0] = _i0; \ > + fregs.F1.TYPE[0] = _i1; \ > + fregs.F2.TYPE[0] = _i2; \ > + fregs.F3.TYPE[0] = _i3; \ > + fregs.F4.TYPE[0] = _i4; \ > + fregs.F5.TYPE[0] = _i5; \ > + fregs.F6.TYPE[0] = _i6; \ > + fregs.F7.TYPE[0] = _i7; \ > + num_fregs = 8; \ > + WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ > + _i9, _i10, _i11, _i12, _i13, _i14, _i15, _i16, \ > + _i17, _i18, _i19); > + > +volatile __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8; > + > +void > +test_m128bf16_on_stack () > +{ > + __m128bf16 x[8]; > + int i; > + for (i = 0; i < 8; i++) > + x[i] = (__m128bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8 }; > + pass = "m128bf16-8"; > + def_check_int_passing8 (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], > + fun_check_passing_m128bf16_8_values, > + fun_check_passing_m128bf16_8_regs, _m128bf16); > +} > + > +void > +test_too_many_m128bf16 () > +{ > + __m128bf16 x[20]; > + int i; > + for (i = 0; i < 20; i++) > + x[i] = (__m128bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8 }; > + pass = "m128bf16-20"; > + def_check_int_passing20 (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], > + x[8], x[9], x[10], x[11], x[12], x[13], x[14], > + x[15], x[16], x[17], x[18], x[19], > + fun_check_passing_m128bf16_20_values, > + fun_check_passing_m128bf16_20_regs, _m128bf16); > +} > + > +static void > +do_test (void) > +{ > + test_m128bf16_on_stack (); > + test_too_many_m128bf16 (); > + if (failed) > + abort (); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_structs.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_structs.c > new file mode 100644 > index 00000000000..8d966005741 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_structs.c > @@ -0,0 +1,67 @@ > +#include "bf16-check.h" > +#include "defines.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +struct m128bf16_struct > +{ > + __m128bf16 x; > +}; > + > +struct m128bf16_2_struct > +{ > + __m128bf16 x1, x2; > +}; > + > +/* Check that the struct is passed as the individual members in fregs. */ > +void > +check_struct_passing1bf16 (struct m128bf16_struct ms1 ATTRIBUTE_UNUSED, > + struct m128bf16_struct ms2 ATTRIBUTE_UNUSED, > + struct m128bf16_struct ms3 ATTRIBUTE_UNUSED, > + struct m128bf16_struct ms4 ATTRIBUTE_UNUSED, > + struct m128bf16_struct ms5 ATTRIBUTE_UNUSED, > + struct m128bf16_struct ms6 ATTRIBUTE_UNUSED, > + struct m128bf16_struct ms7 ATTRIBUTE_UNUSED, > + struct m128bf16_struct ms8 ATTRIBUTE_UNUSED) > +{ > + check_m128_arguments; > +} > + > +void > +check_struct_passing2bf16 (struct m128bf16_2_struct ms ATTRIBUTE_UNUSED) > +{ > + /* Check the passing on the stack by comparing the address of the > + stack elements to the expected place on the stack. */ > + assert ((unsigned long)&ms.x1 == rsp+8); > + assert ((unsigned long)&ms.x2 == rsp+24); > +} > + > +volatile __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, > + bf9, bf10,bf11,bf12,bf13,bf14,bf15,bf16; > + > +static void > +do_test (void) > +{ > + struct m128bf16_struct m128bf16s [8]; > + struct m128bf16_2_struct m128bf16_2s = { > + { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8 }, > + { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8 }, > + }; > + int i; > + > + for (i = 0; i < 8; i++) > + { > + m128bf16s[i].x = (__m128bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8 }; > + } > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + (&fregs.xmm0)[i]._m128bf16[0] = m128bf16s[i].x; > + num_fregs = 8; > + WRAP_CALL (check_struct_passing1bf16) (m128bf16s[0], m128bf16s[1], m128bf16s[2], m128bf16s[3], > + m128bf16s[4], m128bf16s[5], m128bf16s[6], m128bf16s[7]); > + WRAP_CALL (check_struct_passing2bf16) (m128bf16_2s); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_unions.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_unions.c > new file mode 100644 > index 00000000000..83e4380512b > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_unions.c > @@ -0,0 +1,160 @@ > +#include "bf16-check.h" > +#include "defines.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > +unsigned int num_fregs, num_iregs; > + > +union un1b > +{ > + __m128bf16 x; > + float f; > +}; > + > +union un1bb > +{ > + __m128bf16 x; > + __bf16 f; > +}; > + > +union un2b > +{ > + __m128bf16 x; > + double d; > +}; > + > +union un3b > +{ > + __m128bf16 x; > + __m128 v; > +}; > + > +union un4b > +{ > + __m128bf16 x; > + long double ld; > +}; > + > +void > +check_union_passing1b (union un1b u1 ATTRIBUTE_UNUSED, > + union un1b u2 ATTRIBUTE_UNUSED, > + union un1b u3 ATTRIBUTE_UNUSED, > + union un1b u4 ATTRIBUTE_UNUSED, > + union un1b u5 ATTRIBUTE_UNUSED, > + union un1b u6 ATTRIBUTE_UNUSED, > + union un1b u7 ATTRIBUTE_UNUSED, > + union un1b u8 ATTRIBUTE_UNUSED) > +{ > + check_m128_arguments; > +} > + > +void > +check_union_passing1bb (union un1bb u1 ATTRIBUTE_UNUSED, > + union un1bb u2 ATTRIBUTE_UNUSED, > + union un1bb u3 ATTRIBUTE_UNUSED, > + union un1bb u4 ATTRIBUTE_UNUSED, > + union un1bb u5 ATTRIBUTE_UNUSED, > + union un1bb u6 ATTRIBUTE_UNUSED, > + union un1bb u7 ATTRIBUTE_UNUSED, > + union un1bb u8 ATTRIBUTE_UNUSED) > +{ > + check_m128_arguments; > +} > + > +void > +check_union_passing2b (union un2b u1 ATTRIBUTE_UNUSED, > + union un2b u2 ATTRIBUTE_UNUSED, > + union un2b u3 ATTRIBUTE_UNUSED, > + union un2b u4 ATTRIBUTE_UNUSED, > + union un2b u5 ATTRIBUTE_UNUSED, > + union un2b u6 ATTRIBUTE_UNUSED, > + union un2b u7 ATTRIBUTE_UNUSED, > + union un2b u8 ATTRIBUTE_UNUSED) > +{ > + check_m128_arguments; > +} > + > +void > +check_union_passing3b (union un3b u1 ATTRIBUTE_UNUSED, > + union un3b u2 ATTRIBUTE_UNUSED, > + union un3b u3 ATTRIBUTE_UNUSED, > + union un3b u4 ATTRIBUTE_UNUSED, > + union un3b u5 ATTRIBUTE_UNUSED, > + union un3b u6 ATTRIBUTE_UNUSED, > + union un3b u7 ATTRIBUTE_UNUSED, > + union un3b u8 ATTRIBUTE_UNUSED) > +{ > + check_m128_arguments; > +} > + > +void > +check_union_passing4b (union un4b u ATTRIBUTE_UNUSED) > +{ > + /* Check the passing on the stack by comparing the address of the > + stack elements to the expected place on the stack. */ > + assert ((unsigned long)&u.x == rsp+8); > + assert ((unsigned long)&u.ld == rsp+8); > +} > + > +#define check_union_passing1b WRAP_CALL(check_union_passing1b) > +#define check_union_passing1bb WRAP_CALL(check_union_passing1bb) > +#define check_union_passing2b WRAP_CALL(check_union_passing2b) > +#define check_union_passing3b WRAP_CALL(check_union_passing3b) > +#define check_union_passing4b WRAP_CALL(check_union_passing4b) > + > +static void > +do_test (void) > +{ > + union un1b u1b[8]; > + union un1bb u1bb[8]; > + union un2b u2b[8]; > + union un3b u3b[8]; > + union un4b u4b; > + int i; > + __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8; > + > + for (i = 0; i < 8; i++) > + { > + u1b[i].x = (__m128bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8 }; > + } > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + (&fregs.xmm0)[i]._m128bf16[0] = u1b[i].x; > + num_fregs = 8; > + check_union_passing1b (u1b[0], u1b[1], u1b[2], u1b[3], > + u1b[4], u1b[5], u1b[6], u1b[7]); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u1bb[i].x = u1b[i].x; > + (&fregs.xmm0)[i]._m128bf16[0] = u1bb[i].x; > + } > + num_fregs = 8; > + check_union_passing1bb (u1bb[0], u1bb[1], u1bb[2], u1bb[3], > + u1bb[4], u1bb[5], u1bb[6], u1bb[7]); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u2b[i].x = u1b[i].x; > + (&fregs.xmm0)[i]._m128bf16[0] = u2b[i].x; > + } > + num_fregs = 8; > + check_union_passing2b (u2b[0], u2b[1], u2b[2], u2b[3], > + u2b[4], u2b[5], u2b[6], u2b[7]); > + > + clear_struct_registers; > + for (i = 0; i < 8; i++) > + { > + u3b[i].x = u1b[i].x; > + (&fregs.xmm0)[i]._m128bf16[0] = u3b[i].x; > + } > + num_fregs = 8; > + check_union_passing3b (u3b[0], u3b[1], u3b[2], u3b[3], > + u3b[4], u3b[5], u3b[6], u3b[7]); > + > + check_union_passing4b (u4b); > +} > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_struct_returning.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_struct_returning.c > new file mode 100644 > index 00000000000..757ccc26b79 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_struct_returning.c > @@ -0,0 +1,176 @@ > +/* This tests returning of structures. */ > + > +#include > +#include "bf16-check.h" > +#include "defines.h" > +#include "macros.h" > +#include "args.h" > + > +struct IntegerRegisters iregs; > +struct FloatRegisters fregs; > +unsigned int num_iregs, num_fregs; > + > +int current_test; > +int num_failed = 0; > + > +#undef assert > +#define assert(test) do { if (!(test)) {fprintf (stderr, "failed in test %d\n", current_test); num_failed++; } } while (0) > + > +#define xmm0b xmm_regs[0].___bf16 > +#define xmm1b xmm_regs[1].___bf16 > +#define xmm0f xmm_regs[0]._float > +#define xmm0d xmm_regs[0]._double > +#define xmm1f xmm_regs[1]._float > +#define xmm1d xmm_regs[1]._double > + > +typedef enum { > + SSE_B = 0, > + SSE_D, > + MEM, > + INT_SSE, > + SSE_INT, > + SSE_F_H, > + SSE_F_H8 > +} Type; > + > +/* Structures which should be returned in SSE. */ > +#define D(I,MEMBERS,C,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = C; \ > +struct S_ ## I f_ ## I (void) { struct S_ ## I s; memset (&s, 0, sizeof(s)); B; return s; } > + > +D(120,__bf16 f,SSE_B, s.f=make_f32_bf16(42.0f)) > +D(121,__bf16 f;__bf16 f2,SSE_B, s.f=make_f32_bf16(42.0f)) > +D(122,__bf16 f;float d,SSE_B, s.f=make_f32_bf16(42.0f)) > +D(123,__bf16 f;double d,SSE_B, s.f=make_f32_bf16(42.0f)) > +D(124,double d; __bf16 f,SSE_D, s.d=42) > +D(125,__bf16 f[2],SSE_B, s.f[0]=make_f32_bf16(42.0f)) > +D(126,__bf16 f[3],SSE_B, s.f[0]=make_f32_bf16(42.0f)) > +D(127,__bf16 f[4],SSE_B, s.f[0]=make_f32_bf16(42.0f)) > +D(128,__bf16 f[2]; double d,SSE_B, s.f[0]=make_f32_bf16(42.0f)) > +D(129,double d;__bf16 f[2],SSE_D, s.d=42) > + > +#undef D > + > +#define D(I,MEMBERS) struct S_ ## I { MEMBERS ; }; Type class_ ## I = INT_SSE; \ > +struct S_ ## I f_ ## I (void) { struct S_ ## I s = { 42, make_f32_bf16(43.0f) }; return s; } > + > +D(310,char m1; __bf16 m2) > +D(311,short m1; __bf16 m2) > +D(312,int m1; __bf16 m2) > +D(313,long long m1; __bf16 m2) > + > +#undef D > + > +void check_300 (void) > +{ > + XMM_T x; > + x._ulonglong[0] = rax; > + switch (current_test) { > + case 310: assert ((rax & 0xff) == 42 > + && check_bf16_float (x.___bf16[1], 43.0f) == 1); break; > + case 311: assert ((rax & 0xffff) == 42 > + && check_bf16_float (x.___bf16[1], 43.0f) == 1); break; > + case 312: assert ((rax & 0xffffffff) == 42 > + && check_bf16_float (x.___bf16[2], 43.0f) == 1); break; > + case 313: assert (rax == 42 > + && check_bf16_float (xmm0b[0], 43.0f) == 1); break; > + > + default: assert (0); break; > + } > +} > + > +/* Structures which should be returned in SSE (low) and INT (high). */ > +#define D(I,MEMBERS,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = SSE_INT; \ > +struct S_ ## I f_ ## I (void) { struct S_ ## I s; memset (&s, 0, sizeof(s)); B; return s; } > + > +D(402,__bf16 f[4];char c, s.f[0]=make_f32_bf16(42.0f); s.c=43) > + > +#undef D > + > +void check_400 (void) > +{ > + switch (current_test) { > + case 402: assert (check_bf16_float (xmm0b[0], 42.0f) == 1 && (rax & 0xff) == 43); break; > + > + default: assert (0); break; > + } > +} > + > +/* Structures which should be returned in MEM. */ > +void *struct_addr; > +#define D(I,MEMBERS) struct S_ ## I { MEMBERS ; }; Type class_ ## I = MEM; \ > +struct S_ ## I f_ ## I (void) { union {unsigned char c; struct S_ ## I s;} u; memset (&u.s, 0, sizeof(u.s)); u.c = 42; return u.s; } > + > +/* Unnaturally aligned members. */ > +D(540,__bf16 m1[10]) > +D(541,char m1[1];__bf16 f[8]) > + > +#undef D > + > + > +/* Special tests. */ > +#define D(I,MEMBERS,C,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = C; \ > +struct S_ ## I f_ ## I (void) { struct S_ ## I s; B; return s; } > +D(601,__bf16 f[4], SSE_F_H, s.f[0] = s.f[1] = s.f[2] = s.f[3] = make_f32_bf16 (42.0f)) > +D(602,__bf16 f[8], SSE_F_H8, > + s.f[0] = s.f[1] = s.f[2] = s.f[3] = s.f[4] = s.f[5] = s.f[6] = s.f[7] = make_f32_bf16 (42.0f)) > +#undef D > + > +void clear_all (void) > +{ > + clear_int_registers; > +} > + > +void check_all (Type class, unsigned long size) > +{ > + switch (class) { > + case SSE_B: assert (check_bf16_float (xmm0b[0], 42.0f) == 1); break; > + case SSE_D: assert (xmm0d[0] == 42); break; > + case SSE_F_H: assert (check_bf16_float (xmm0b[0], 42) == 1 > + && check_bf16_float (xmm0b[1], 42) == 1 > + && check_bf16_float (xmm0b[2], 42) == 1 > + && check_bf16_float (xmm0b[3], 42) == 1); break; > + case SSE_F_H8: assert (check_bf16_float (xmm0b[0], 42) == 1 > + && check_bf16_float (xmm0b[1], 42) == 1 > + && check_bf16_float (xmm0b[2], 42) == 1 > + && check_bf16_float (xmm0b[3], 42) == 1 > + && check_bf16_float (xmm1b[0], 42) == 1 > + && check_bf16_float (xmm1b[1], 42) == 1 > + && check_bf16_float (xmm1b[2], 42) == 1 > + && check_bf16_float (xmm1b[3], 42) == 1); break; > + case INT_SSE: check_300(); break; > + case SSE_INT: check_400(); break; > + /* Ideally we would like to check that rax == struct_addr. > + Unfortunately the address of the target struct escapes (for setting > + struct_addr), so the return struct is a temporary one whose address > + is given to the f_* functions, otherwise a conforming program > + could notice the struct changing already before the function returns. > + This temporary struct could be anywhere. For GCC it will be on > + stack, but no one is forbidding that it could be a static variable > + if there's no threading or proper locking. Nobody in his right mind > + will not use the stack for that. */ > + case MEM: assert (*(unsigned char*)struct_addr == 42 && rdi == rax); break; > + } > +} > + > +#define D(I) { struct S_ ## I s; current_test = I; struct_addr = (void*)&s; \ > + clear_all(); \ > + s = WRAP_RET(f_ ## I) (); \ > + check_all(class_ ## I, sizeof(s)); \ > +} > + > +static void > +do_test (void) > +{ > + D(120) D(121) D(122) D(123) D(124) D(125) D(126) D(127) D(128) D(129) > + > + D(310) D(311) D(312) D(313) > + > + D(402) > + > + D(540) D(541) > + > + D(601) D(602) > + if (num_failed) > + abort (); > +} > +#undef D > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_varargs-m128.c b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_varargs-m128.c > new file mode 100644 > index 00000000000..4eea7eb7d3c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/test_varargs-m128.c > @@ -0,0 +1,111 @@ > +/* Test variable number of 128-bit vector arguments passed to functions. */ > + > +#include > +#include "bf16-check.h" > +#include "defines.h" > +#include "macros.h" > +#include "args.h" > + > +struct FloatRegisters fregs; > +struct IntegerRegisters iregs; > + > +/* This struct holds values for argument checking. */ > +struct > +{ > + XMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; > +} values; > + > +char *pass; > +int failed = 0; > + > +#undef assert > +#define assert(c) do { \ > + if (!(c)) {failed++; printf ("failed %s\n", pass); } \ > +} while (0) > + > +#define compare(X1,X2,T) do { \ > + assert (memcmp (&X1, &X2, sizeof (T)) == 0); \ > +} while (0) > + > +void > +fun_check_passing_m128bf16_varargs (__m128bf16 i0, __m128bf16 i1, __m128bf16 i2, > + __m128bf16 i3, ...) > +{ > + /* Check argument values. */ > + void **fp = __builtin_frame_address (0); > + void *ra = __builtin_return_address (0); > + __m128bf16 *argp; > + > + compare (values.i0, i0, __m128bf16); > + compare (values.i1, i1, __m128bf16); > + compare (values.i2, i2, __m128bf16); > + compare (values.i3, i3, __m128bf16); > + > + /* Get the pointer to the return address on stack. */ > + while (*fp != ra) > + fp++; > + > + /* Skip the return address stack slot. */ > + argp = (__m128bf16 *) (((char *) fp) + 8); > + > + /* Check __m128bf16 arguments passed on stack. */ > + compare (values.i8, argp[0], __m128bf16); > + compare (values.i9, argp[1], __m128bf16); > + > + /* Check register contents. */ > + compare (fregs.xmm0, xmm_regs[0], __m128bf16); > + compare (fregs.xmm1, xmm_regs[1], __m128bf16); > + compare (fregs.xmm2, xmm_regs[2], __m128bf16); > + compare (fregs.xmm3, xmm_regs[3], __m128bf16); > + compare (fregs.xmm4, xmm_regs[4], __m128bf16); > + compare (fregs.xmm5, xmm_regs[5], __m128bf16); > + compare (fregs.xmm6, xmm_regs[6], __m128bf16); > + compare (fregs.xmm7, xmm_regs[7], __m128bf16); > +} > + > +#define def_check_int_passing_varargs(_i0, _i1, _i2, _i3, _i4, _i5, \ > + _i6, _i7, _i8, _i9, \ > + _func, TYPE) \ > + values.i0.TYPE[0] = _i0; \ > + values.i1.TYPE[0] = _i1; \ > + values.i2.TYPE[0] = _i2; \ > + values.i3.TYPE[0] = _i3; \ > + values.i4.TYPE[0] = _i4; \ > + values.i5.TYPE[0] = _i5; \ > + values.i6.TYPE[0] = _i6; \ > + values.i7.TYPE[0] = _i7; \ > + values.i8.TYPE[0] = _i8; \ > + values.i9.TYPE[0] = _i9; \ > + clear_float_registers; \ > + fregs.F0.TYPE[0] = _i0; \ > + fregs.F1.TYPE[0] = _i1; \ > + fregs.F2.TYPE[0] = _i2; \ > + fregs.F3.TYPE[0] = _i3; \ > + fregs.F4.TYPE[0] = _i4; \ > + fregs.F5.TYPE[0] = _i5; \ > + fregs.F6.TYPE[0] = _i6; \ > + fregs.F7.TYPE[0] = _i7; \ > + WRAP_CALL(_func) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9); > + > +void > +test_m128bf16_varargs (void) > +{ > + __m128bf16 x[10]; > + __bf16 bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8; > + int i; > + for (i = 0; i < 10; i++) > + x[i] = (__m128bf16) { bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8 }; > + pass = "m128bf16-varargs"; > + def_check_int_passing_varargs (x[0], x[1], x[2], x[3], x[4], x[5], > + x[6], x[7], x[8], x[9], > + fun_check_passing_m128bf16_varargs, > + _m128bf16); > +} > + > +static void > +do_test (void) > +{ > + test_m128bf16_varargs (); > + if (failed) > + abort (); > +} > -- > 2.18.1 > -- BR, Hongtao