mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 07:10:27 +08:00
re PR target/39119 (Update classification of aggregates with __m256)
gcc/ 2009-02-10 H.J. Lu <hongjiu.lu@intel.com> PR target/39119 * config/i386/i386.c (x86_64_reg_class): Remove X86_64_AVX_CLASS. (x86_64_reg_class_name): Removed. (classify_argument): Return 0 if bytes > 32. Return 0 if the first one isn't X86_64_SSE_CLASS or any other ones aren't X86_64_SSEUP_CLASS when size > 16bytes. Don't turn X86_64_SSEUP_CLASS into X86_64_SSE_CLASS if the preceded one is X86_64_SSEUP_CLASS. Set AVX modes to 1 X86_64_SSE_CLASS and 3 X86_64_SSEUP_CLASS. (construct_container): Remove X86_64_AVX_CLASS. Handle 4 registers with 1 X86_64_SSE_CLASS and 3 X86_64_SSEUP_CLASS. gcc/testsuite/ 2009-02-10 H.J. Lu <hongjiu.lu@intel.com> PR target/39119 * gcc.target/x86_64/abi/avx/abi-avx.exp: New. * gcc.target/x86_64/abi/avx/args.h: Likewise. * gcc.target/x86_64/abi/avx/asm-support.S: Likewise. * gcc.target/x86_64/abi/avx/avx-check.h: Likewise. * gcc.target/x86_64/abi/avx/test_m256_returning.c: Likewise. * gcc.target/x86_64/abi/avx/test_passing_m256.c: Likewise. * gcc.target/x86_64/abi/avx/test_passing_structs.c: Likewise. * gcc.target/x86_64/abi/avx/test_passing_unions.c: Likewise. From-SVN: r144058
This commit is contained in:
parent
f7459b6c53
commit
a8800687f5
@ -1,3 +1,17 @@
|
||||
2009-02-10 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/39119
|
||||
* config/i386/i386.c (x86_64_reg_class): Remove X86_64_AVX_CLASS.
|
||||
(x86_64_reg_class_name): Removed.
|
||||
(classify_argument): Return 0 if bytes > 32. Return 0 if the
|
||||
first one isn't X86_64_SSE_CLASS or any other ones aren't
|
||||
X86_64_SSEUP_CLASS when size > 16bytes. Don't turn
|
||||
X86_64_SSEUP_CLASS into X86_64_SSE_CLASS if the preceded one
|
||||
is X86_64_SSEUP_CLASS. Set AVX modes to 1 X86_64_SSE_CLASS
|
||||
and 3 X86_64_SSEUP_CLASS.
|
||||
(construct_container): Remove X86_64_AVX_CLASS. Handle 4
|
||||
registers with 1 X86_64_SSE_CLASS and 3 X86_64_SSEUP_CLASS.
|
||||
|
||||
2009-02-10 Ben Elliston <bje@au.ibm.com>
|
||||
|
||||
* config/rs6000/rs6000.md (allocate_stack): Always use an update
|
||||
|
@ -1773,7 +1773,6 @@ enum x86_64_reg_class
|
||||
X86_64_NO_CLASS,
|
||||
X86_64_INTEGER_CLASS,
|
||||
X86_64_INTEGERSI_CLASS,
|
||||
X86_64_AVX_CLASS,
|
||||
X86_64_SSE_CLASS,
|
||||
X86_64_SSESF_CLASS,
|
||||
X86_64_SSEDF_CLASS,
|
||||
@ -1783,11 +1782,6 @@ enum x86_64_reg_class
|
||||
X86_64_COMPLEX_X87_CLASS,
|
||||
X86_64_MEMORY_CLASS
|
||||
};
|
||||
static const char * const x86_64_reg_class_name[] =
|
||||
{
|
||||
"no", "integer", "integerSI", "sse", "sseSF", "sseDF",
|
||||
"sseup", "x87", "x87up", "cplx87", "no"
|
||||
};
|
||||
|
||||
#define MAX_CLASSES 4
|
||||
|
||||
@ -4863,8 +4857,8 @@ classify_argument (enum machine_mode mode, const_tree type,
|
||||
tree field;
|
||||
enum x86_64_reg_class subclasses[MAX_CLASSES];
|
||||
|
||||
/* On x86-64 we pass structures larger than 16 bytes on the stack. */
|
||||
if (bytes > 16)
|
||||
/* On x86-64 we pass structures larger than 32 bytes on the stack. */
|
||||
if (bytes > 32)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < words; i++)
|
||||
@ -4974,6 +4968,20 @@ classify_argument (enum machine_mode mode, const_tree type,
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
if (words > 2)
|
||||
{
|
||||
/* When size > 16 bytes, if the first one isn't
|
||||
X86_64_SSE_CLASS or any other ones aren't
|
||||
X86_64_SSEUP_CLASS, everything should be passed in
|
||||
memory. */
|
||||
if (classes[0] != X86_64_SSE_CLASS)
|
||||
return 0;
|
||||
|
||||
for (i = 1; i < words; i++)
|
||||
if (classes[i] != X86_64_SSEUP_CLASS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Final merger cleanup. */
|
||||
for (i = 0; i < words; i++)
|
||||
{
|
||||
@ -4983,10 +4991,15 @@ classify_argument (enum machine_mode mode, const_tree type,
|
||||
return 0;
|
||||
|
||||
/* The X86_64_SSEUP_CLASS should be always preceded by
|
||||
X86_64_SSE_CLASS. */
|
||||
X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
|
||||
if (classes[i] == X86_64_SSEUP_CLASS
|
||||
&& (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
|
||||
classes[i] = X86_64_SSE_CLASS;
|
||||
&& classes[i - 1] != X86_64_SSE_CLASS
|
||||
&& classes[i - 1] != X86_64_SSEUP_CLASS)
|
||||
{
|
||||
/* The first one should never be X86_64_SSEUP_CLASS. */
|
||||
gcc_assert (i != 0);
|
||||
classes[i] = X86_64_SSE_CLASS;
|
||||
}
|
||||
|
||||
/* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
|
||||
if (classes[i] == X86_64_X87UP_CLASS
|
||||
@ -5107,8 +5120,11 @@ classify_argument (enum machine_mode mode, const_tree type,
|
||||
case V16HImode:
|
||||
case V4DFmode:
|
||||
case V4DImode:
|
||||
classes[0] = X86_64_AVX_CLASS;
|
||||
return 1;
|
||||
classes[0] = X86_64_SSE_CLASS;
|
||||
classes[1] = X86_64_SSEUP_CLASS;
|
||||
classes[2] = X86_64_SSEUP_CLASS;
|
||||
classes[3] = X86_64_SSEUP_CLASS;
|
||||
return 4;
|
||||
case V4SFmode:
|
||||
case V4SImode:
|
||||
case V16QImode:
|
||||
@ -5165,7 +5181,6 @@ examine_argument (enum machine_mode mode, const_tree type, int in_return,
|
||||
case X86_64_INTEGERSI_CLASS:
|
||||
(*int_nregs)++;
|
||||
break;
|
||||
case X86_64_AVX_CLASS:
|
||||
case X86_64_SSE_CLASS:
|
||||
case X86_64_SSESF_CLASS:
|
||||
case X86_64_SSEDF_CLASS:
|
||||
@ -5264,7 +5279,6 @@ construct_container (enum machine_mode mode, enum machine_mode orig_mode,
|
||||
case X86_64_INTEGER_CLASS:
|
||||
case X86_64_INTEGERSI_CLASS:
|
||||
return gen_rtx_REG (mode, intreg[0]);
|
||||
case X86_64_AVX_CLASS:
|
||||
case X86_64_SSE_CLASS:
|
||||
case X86_64_SSESF_CLASS:
|
||||
case X86_64_SSEDF_CLASS:
|
||||
@ -5281,6 +5295,13 @@ construct_container (enum machine_mode mode, enum machine_mode orig_mode,
|
||||
if (n == 2 && regclass[0] == X86_64_SSE_CLASS
|
||||
&& regclass[1] == X86_64_SSEUP_CLASS && mode != BLKmode)
|
||||
return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
|
||||
if (n == 4
|
||||
&& regclass[0] == X86_64_SSE_CLASS
|
||||
&& regclass[1] == X86_64_SSEUP_CLASS
|
||||
&& regclass[2] == X86_64_SSEUP_CLASS
|
||||
&& regclass[3] == X86_64_SSEUP_CLASS
|
||||
&& mode != BLKmode)
|
||||
return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
|
||||
|
||||
if (n == 2
|
||||
&& regclass[0] == X86_64_X87_CLASS && regclass[1] == X86_64_X87UP_CLASS)
|
||||
@ -5331,14 +5352,22 @@ construct_container (enum machine_mode mode, enum machine_mode orig_mode,
|
||||
break;
|
||||
case X86_64_SSE_CLASS:
|
||||
if (i < n - 1 && regclass[i + 1] == X86_64_SSEUP_CLASS)
|
||||
tmpmode = TImode;
|
||||
{
|
||||
if (regclass[i + 2] == X86_64_SSEUP_CLASS
|
||||
|| regclass[i + 3] == X86_64_SSEUP_CLASS)
|
||||
tmpmode = OImode;
|
||||
else
|
||||
tmpmode = TImode;
|
||||
}
|
||||
else
|
||||
tmpmode = DImode;
|
||||
exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_rtx_REG (tmpmode,
|
||||
SSE_REGNO (sse_regno)),
|
||||
GEN_INT (i*8));
|
||||
if (tmpmode == TImode)
|
||||
if (tmpmode == OImode)
|
||||
i += 3;
|
||||
else if (tmpmode == TImode)
|
||||
i++;
|
||||
sse_regno++;
|
||||
break;
|
||||
|
@ -1,3 +1,15 @@
|
||||
2009-02-10 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/39119
|
||||
* gcc.target/x86_64/abi/avx/abi-avx.exp: New.
|
||||
* gcc.target/x86_64/abi/avx/args.h: Likewise.
|
||||
* gcc.target/x86_64/abi/avx/asm-support.S: Likewise.
|
||||
* gcc.target/x86_64/abi/avx/avx-check.h: Likewise.
|
||||
* gcc.target/x86_64/abi/avx/test_m256_returning.c: Likewise.
|
||||
* gcc.target/x86_64/abi/avx/test_passing_m256.c: Likewise.
|
||||
* gcc.target/x86_64/abi/avx/test_passing_structs.c: Likewise.
|
||||
* gcc.target/x86_64/abi/avx/test_passing_unions.c: Likewise.
|
||||
|
||||
2009-02-09 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/39109
|
||||
|
50
gcc/testsuite/gcc.target/x86_64/abi/avx/abi-avx.exp
Normal file
50
gcc/testsuite/gcc.target/x86_64/abi/avx/abi-avx.exp
Normal file
@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2009 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
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# The x86-64 AVX 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
|
||||
|
||||
if { (![istarget x86_64-*-*] && ![istarget i?86-*-*])
|
||||
|| ![is-effective-target lp64]
|
||||
|| ![is-effective-target avx] } then {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
torture-init
|
||||
set-torture-options $C_TORTURE_OPTIONS
|
||||
set additional_flags "-W -Wall -mavx"
|
||||
|
||||
foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] {
|
||||
if {[runtest_file_p $runtests $src]} {
|
||||
if { ([istarget *-*-darwin*]) } then {
|
||||
# FIXME: Darwin isn't tested.
|
||||
c-torture-execute [list $src \
|
||||
$srcdir/$subdir/asm-support-darwin.s] \
|
||||
$additional_flags
|
||||
} else {
|
||||
c-torture-execute [list $src \
|
||||
$srcdir/$subdir/asm-support.S] \
|
||||
$additional_flags
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
torture-finish
|
180
gcc/testsuite/gcc.target/x86_64/abi/avx/args.h
Normal file
180
gcc/testsuite/gcc.target/x86_64/abi/avx/args.h
Normal file
@ -0,0 +1,180 @@
|
||||
#ifndef INCLUDED_ARGS_H
|
||||
#define INCLUDED_ARGS_H
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <string.h>
|
||||
|
||||
/* 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 {
|
||||
float _float[8];
|
||||
double _double[4];
|
||||
long _long[4];
|
||||
int _int[8];
|
||||
unsigned long _ulong[4];
|
||||
__m64 _m64[4];
|
||||
__m128 _m128[2];
|
||||
__m256 _m256[1];
|
||||
} YMM_T;
|
||||
|
||||
typedef union {
|
||||
float _float;
|
||||
double _double;
|
||||
long double _ldouble;
|
||||
unsigned long _ulong[2];
|
||||
} X87_T;
|
||||
extern void (*callthis)(void);
|
||||
extern unsigned 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 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 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;
|
||||
|
||||
#define check_int_arguments do { \
|
||||
assert (num_iregs <= 0 || iregs.I0 == I0); \
|
||||
assert (num_iregs <= 1 || iregs.I1 == I1); \
|
||||
assert (num_iregs <= 2 || iregs.I2 == I2); \
|
||||
assert (num_iregs <= 3 || iregs.I3 == I3); \
|
||||
assert (num_iregs <= 4 || iregs.I4 == I4); \
|
||||
assert (num_iregs <= 5 || iregs.I5 == I5); \
|
||||
} while (0)
|
||||
|
||||
#define check_char_arguments check_int_arguments
|
||||
#define check_short_arguments check_int_arguments
|
||||
#define check_long_arguments check_int_arguments
|
||||
|
||||
/* 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
|
||||
|
||||
/* TODO: Do the checking. */
|
||||
#define check_f_arguments(T) do { \
|
||||
assert (num_fregs <= 0 || fregs.ymm0._ ## T [0] == ymm_regs[0]._ ## T [0]); \
|
||||
assert (num_fregs <= 1 || fregs.ymm1._ ## T [0] == ymm_regs[1]._ ## T [0]); \
|
||||
assert (num_fregs <= 2 || fregs.ymm2._ ## T [0] == ymm_regs[2]._ ## T [0]); \
|
||||
assert (num_fregs <= 3 || fregs.ymm3._ ## T [0] == ymm_regs[3]._ ## T [0]); \
|
||||
assert (num_fregs <= 4 || fregs.ymm4._ ## T [0] == ymm_regs[4]._ ## T [0]); \
|
||||
assert (num_fregs <= 5 || fregs.ymm5._ ## T [0] == ymm_regs[5]._ ## T [0]); \
|
||||
assert (num_fregs <= 6 || fregs.ymm6._ ## T [0] == ymm_regs[6]._ ## T [0]); \
|
||||
assert (num_fregs <= 7 || fregs.ymm7._ ## T [0] == ymm_regs[7]._ ## T [0]); \
|
||||
} while (0)
|
||||
|
||||
#define check_float_arguments check_f_arguments(float)
|
||||
#define check_double_arguments check_f_arguments(double)
|
||||
|
||||
#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_m64_arguments check_vector_arguments(m64, 0)
|
||||
#define check_m128_arguments check_vector_arguments(m128, 0)
|
||||
#define check_m256_arguments check_vector_arguments(m256, 0)
|
||||
|
||||
#endif /* INCLUDED_ARGS_H */
|
80
gcc/testsuite/gcc.target/x86_64/abi/avx/asm-support.S
Normal file
80
gcc/testsuite/gcc.target/x86_64/abi/avx/asm-support.S
Normal file
@ -0,0 +1,80 @@
|
||||
.file "snapshot.S"
|
||||
.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+32*2(%rip)
|
||||
vmovdqu %ymm3, ymm_regs+32*3(%rip)
|
||||
vmovdqu %ymm4, ymm_regs+32*4(%rip)
|
||||
vmovdqu %ymm5, ymm_regs+32*5(%rip)
|
||||
vmovdqu %ymm6, ymm_regs+32*6(%rip)
|
||||
vmovdqu %ymm7, ymm_regs+32*7(%rip)
|
||||
vmovdqu %ymm8, ymm_regs+32*8(%rip)
|
||||
vmovdqu %ymm9, ymm_regs+32*9(%rip)
|
||||
vmovdqu %ymm10, ymm_regs+32*10(%rip)
|
||||
vmovdqu %ymm11, ymm_regs+32*11(%rip)
|
||||
vmovdqu %ymm12, ymm_regs+32*12(%rip)
|
||||
vmovdqu %ymm13, ymm_regs+32*13(%rip)
|
||||
vmovdqu %ymm14, ymm_regs+32*14(%rip)
|
||||
vmovdqu %ymm15, ymm_regs+32*15(%rip)
|
||||
jmp *callthis(%rip)
|
||||
.LFE3:
|
||||
.size snapshot, .-snapshot
|
||||
|
||||
.p2align 4,,15
|
||||
.globl snapshot_ret
|
||||
.type snapshot_ret, @function
|
||||
snapshot_ret:
|
||||
movq %rdi, rdi(%rip)
|
||||
call *callthis(%rip)
|
||||
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
|
28
gcc/testsuite/gcc.target/x86_64/abi/avx/avx-check.h
Normal file
28
gcc/testsuite/gcc.target/x86_64/abi/avx/avx-check.h
Normal file
@ -0,0 +1,28 @@
|
||||
#include <stdlib.h>
|
||||
#include "cpuid.h"
|
||||
|
||||
static void avx_test (void);
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
|
||||
return 0;
|
||||
|
||||
/* Run AVX test only if host has AVX support. */
|
||||
if (ecx & bit_AVX)
|
||||
{
|
||||
avx_test ();
|
||||
#ifdef DEBUG
|
||||
printf ("PASSED\n");
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else
|
||||
printf ("SKIPPED\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
#include "avx-check.h"
|
||||
#include "args.h"
|
||||
|
||||
struct IntegerRegisters iregs;
|
||||
struct FloatRegisters fregs;
|
||||
unsigned int num_iregs, num_fregs;
|
||||
|
||||
__m256
|
||||
fun_test_returning___m256 (void)
|
||||
{
|
||||
volatile_var++;
|
||||
return (__m256){73,0,0,0,0,0,0,0};
|
||||
}
|
||||
|
||||
__m256 test_256;
|
||||
|
||||
static void
|
||||
avx_test (void)
|
||||
{
|
||||
unsigned failed = 0;
|
||||
YMM_T ymmt1, ymmt2;
|
||||
|
||||
clear_struct_registers;
|
||||
test_256 = (__m256){73,0,0,0,0,0,0,0};
|
||||
ymmt1._m256[0] = test_256;
|
||||
ymmt2._m256[0] = WRAP_RET (fun_test_returning___m256)();
|
||||
if (memcmp (&ymmt1, &ymmt2, sizeof (ymmt2)) != 0)
|
||||
printf ("fail m256\n"), failed++;
|
||||
if (failed)
|
||||
abort ();
|
||||
}
|
168
gcc/testsuite/gcc.target/x86_64/abi/avx/test_passing_m256.c
Normal file
168
gcc/testsuite/gcc.target/x86_64/abi/avx/test_passing_m256.c
Normal file
@ -0,0 +1,168 @@
|
||||
#include <stdio.h>
|
||||
#include "avx-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_m256_8_values (__m256 i0 ATTRIBUTE_UNUSED, __m256 i1 ATTRIBUTE_UNUSED, __m256 i2 ATTRIBUTE_UNUSED, __m256 i3 ATTRIBUTE_UNUSED, __m256 i4 ATTRIBUTE_UNUSED, __m256 i5 ATTRIBUTE_UNUSED, __m256 i6 ATTRIBUTE_UNUSED, __m256 i7 ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* Check argument values. */
|
||||
compare (values.i0, i0, __m256);
|
||||
compare (values.i1, i1, __m256);
|
||||
compare (values.i2, i2, __m256);
|
||||
compare (values.i3, i3, __m256);
|
||||
compare (values.i4, i4, __m256);
|
||||
compare (values.i5, i5, __m256);
|
||||
compare (values.i6, i6, __m256);
|
||||
compare (values.i7, i7, __m256);
|
||||
}
|
||||
|
||||
void
|
||||
fun_check_passing_m256_8_regs (__m256 i0 ATTRIBUTE_UNUSED, __m256 i1 ATTRIBUTE_UNUSED, __m256 i2 ATTRIBUTE_UNUSED, __m256 i3 ATTRIBUTE_UNUSED, __m256 i4 ATTRIBUTE_UNUSED, __m256 i5 ATTRIBUTE_UNUSED, __m256 i6 ATTRIBUTE_UNUSED, __m256 i7 ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* Check register contents. */
|
||||
check_m256_arguments;
|
||||
}
|
||||
|
||||
void
|
||||
fun_check_passing_m256_20_values (__m256 i0 ATTRIBUTE_UNUSED, __m256 i1 ATTRIBUTE_UNUSED, __m256 i2 ATTRIBUTE_UNUSED, __m256 i3 ATTRIBUTE_UNUSED, __m256 i4 ATTRIBUTE_UNUSED, __m256 i5 ATTRIBUTE_UNUSED, __m256 i6 ATTRIBUTE_UNUSED, __m256 i7 ATTRIBUTE_UNUSED, __m256 i8 ATTRIBUTE_UNUSED, __m256 i9 ATTRIBUTE_UNUSED, __m256 i10 ATTRIBUTE_UNUSED, __m256 i11 ATTRIBUTE_UNUSED, __m256 i12 ATTRIBUTE_UNUSED, __m256 i13 ATTRIBUTE_UNUSED, __m256 i14 ATTRIBUTE_UNUSED, __m256 i15 ATTRIBUTE_UNUSED, __m256 i16 ATTRIBUTE_UNUSED, __m256 i17 ATTRIBUTE_UNUSED, __m256 i18 ATTRIBUTE_UNUSED, __m256 i19 ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* Check argument values. */
|
||||
compare (values.i0, i0, __m256);
|
||||
compare (values.i1, i1, __m256);
|
||||
compare (values.i2, i2, __m256);
|
||||
compare (values.i3, i3, __m256);
|
||||
compare (values.i4, i4, __m256);
|
||||
compare (values.i5, i5, __m256);
|
||||
compare (values.i6, i6, __m256);
|
||||
compare (values.i7, i7, __m256);
|
||||
compare (values.i8, i8, __m256);
|
||||
compare (values.i9, i9, __m256);
|
||||
compare (values.i10, i10, __m256);
|
||||
compare (values.i11, i11, __m256);
|
||||
compare (values.i12, i12, __m256);
|
||||
compare (values.i13, i13, __m256);
|
||||
compare (values.i14, i14, __m256);
|
||||
compare (values.i15, i15, __m256);
|
||||
compare (values.i16, i16, __m256);
|
||||
compare (values.i17, i17, __m256);
|
||||
compare (values.i18, i18, __m256);
|
||||
compare (values.i19, i19, __m256);
|
||||
}
|
||||
|
||||
void
|
||||
fun_check_passing_m256_20_regs (__m256 i0 ATTRIBUTE_UNUSED, __m256 i1 ATTRIBUTE_UNUSED, __m256 i2 ATTRIBUTE_UNUSED, __m256 i3 ATTRIBUTE_UNUSED, __m256 i4 ATTRIBUTE_UNUSED, __m256 i5 ATTRIBUTE_UNUSED, __m256 i6 ATTRIBUTE_UNUSED, __m256 i7 ATTRIBUTE_UNUSED, __m256 i8 ATTRIBUTE_UNUSED, __m256 i9 ATTRIBUTE_UNUSED, __m256 i10 ATTRIBUTE_UNUSED, __m256 i11 ATTRIBUTE_UNUSED, __m256 i12 ATTRIBUTE_UNUSED, __m256 i13 ATTRIBUTE_UNUSED, __m256 i14 ATTRIBUTE_UNUSED, __m256 i15 ATTRIBUTE_UNUSED, __m256 i16 ATTRIBUTE_UNUSED, __m256 i17 ATTRIBUTE_UNUSED, __m256 i18 ATTRIBUTE_UNUSED, __m256 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);
|
||||
|
||||
void
|
||||
test_m256_on_stack ()
|
||||
{
|
||||
__m256 x[8];
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
x[i] = (__m256){32+i, 0, 0, 0, 0, 0, 0, 0};
|
||||
pass = "m256-8";
|
||||
def_check_passing8(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], fun_check_passing_m256_8_values, fun_check_passing_m256_8_regs, _m256);
|
||||
}
|
||||
|
||||
void
|
||||
test_too_many_m256 ()
|
||||
{
|
||||
__m256 x[20];
|
||||
int i;
|
||||
for (i = 0; i < 20; i++)
|
||||
x[i] = (__m256){32+i, 0, 0, 0, 0, 0, 0, 0};
|
||||
pass = "m256-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_m256_20_values, fun_check_passing_m256_20_regs, _m256);
|
||||
}
|
||||
|
||||
static void
|
||||
avx_test (void)
|
||||
{
|
||||
test_m256_on_stack ();
|
||||
test_too_many_m256 ();
|
||||
if (failed)
|
||||
abort ();
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
#include "avx-check.h"
|
||||
#include "args.h"
|
||||
|
||||
struct IntegerRegisters iregs;
|
||||
struct FloatRegisters fregs;
|
||||
unsigned int num_iregs, num_fregs;
|
||||
|
||||
struct m256_struct
|
||||
{
|
||||
__m256 x;
|
||||
};
|
||||
|
||||
struct m256_2_struct
|
||||
{
|
||||
__m256 x1, x2;
|
||||
};
|
||||
|
||||
/* Check that the struct is passed as the individual members in fregs. */
|
||||
void
|
||||
check_struct_passing1 (struct m256_struct ms1 ATTRIBUTE_UNUSED,
|
||||
struct m256_struct ms2 ATTRIBUTE_UNUSED,
|
||||
struct m256_struct ms3 ATTRIBUTE_UNUSED,
|
||||
struct m256_struct ms4 ATTRIBUTE_UNUSED,
|
||||
struct m256_struct ms5 ATTRIBUTE_UNUSED,
|
||||
struct m256_struct ms6 ATTRIBUTE_UNUSED,
|
||||
struct m256_struct ms7 ATTRIBUTE_UNUSED,
|
||||
struct m256_struct ms8 ATTRIBUTE_UNUSED)
|
||||
{
|
||||
check_m256_arguments;
|
||||
}
|
||||
|
||||
void
|
||||
check_struct_passing2 (struct m256_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);
|
||||
}
|
||||
|
||||
static void
|
||||
avx_test (void)
|
||||
{
|
||||
struct m256_struct m256s [8];
|
||||
struct m256_2_struct m256_2s = {
|
||||
{ 48.394, 39.3, -397.9, 3484.9, -8.394, -93.3, 7.9, 84.94 },
|
||||
{ -8.394, -3.3, -39.9, 34.9, 7.9, 84.94, -48.394, 39.3 }
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
m256s[i].x = (__m256){32+i, 0, i, 0, -i, 0, i - 12, i + 8};
|
||||
|
||||
clear_struct_registers;
|
||||
for (i = 0; i < 8; i++)
|
||||
fregs.ymm0._m256[i] = m256s[i].x;
|
||||
num_fregs = 8;
|
||||
WRAP_CALL (check_struct_passing1)(m256s[0], m256s[1], m256s[2], m256s[3],
|
||||
m256s[4], m256s[5], m256s[6], m256s[7]);
|
||||
WRAP_CALL (check_struct_passing2)(m256_2s);
|
||||
}
|
143
gcc/testsuite/gcc.target/x86_64/abi/avx/test_passing_unions.c
Normal file
143
gcc/testsuite/gcc.target/x86_64/abi/avx/test_passing_unions.c
Normal file
@ -0,0 +1,143 @@
|
||||
#include "avx-check.h"
|
||||
#include "args.h"
|
||||
|
||||
struct IntegerRegisters iregs;
|
||||
struct FloatRegisters fregs;
|
||||
unsigned int num_iregs, num_fregs;
|
||||
|
||||
union un1
|
||||
{
|
||||
__m256 x;
|
||||
float f;
|
||||
};
|
||||
|
||||
union un2
|
||||
{
|
||||
__m256 x;
|
||||
double d;
|
||||
};
|
||||
|
||||
union un3
|
||||
{
|
||||
__m256 x;
|
||||
__m128 v;
|
||||
};
|
||||
|
||||
union un4
|
||||
{
|
||||
__m256 x;
|
||||
long double ld;
|
||||
};
|
||||
|
||||
union un5
|
||||
{
|
||||
__m256 x;
|
||||
int i;
|
||||
};
|
||||
|
||||
void
|
||||
check_union_passing1(union un1 u1 ATTRIBUTE_UNUSED,
|
||||
union un1 u2 ATTRIBUTE_UNUSED,
|
||||
union un1 u3 ATTRIBUTE_UNUSED,
|
||||
union un1 u4 ATTRIBUTE_UNUSED,
|
||||
union un1 u5 ATTRIBUTE_UNUSED,
|
||||
union un1 u6 ATTRIBUTE_UNUSED,
|
||||
union un1 u7 ATTRIBUTE_UNUSED,
|
||||
union un1 u8 ATTRIBUTE_UNUSED)
|
||||
{
|
||||
check_m256_arguments;
|
||||
}
|
||||
|
||||
void
|
||||
check_union_passing2(union un2 u1 ATTRIBUTE_UNUSED,
|
||||
union un2 u2 ATTRIBUTE_UNUSED,
|
||||
union un2 u3 ATTRIBUTE_UNUSED,
|
||||
union un2 u4 ATTRIBUTE_UNUSED,
|
||||
union un2 u5 ATTRIBUTE_UNUSED,
|
||||
union un2 u6 ATTRIBUTE_UNUSED,
|
||||
union un2 u7 ATTRIBUTE_UNUSED,
|
||||
union un2 u8 ATTRIBUTE_UNUSED)
|
||||
{
|
||||
check_m256_arguments;
|
||||
}
|
||||
|
||||
void
|
||||
check_union_passing3(union un3 u1 ATTRIBUTE_UNUSED,
|
||||
union un3 u2 ATTRIBUTE_UNUSED,
|
||||
union un3 u3 ATTRIBUTE_UNUSED,
|
||||
union un3 u4 ATTRIBUTE_UNUSED,
|
||||
union un3 u5 ATTRIBUTE_UNUSED,
|
||||
union un3 u6 ATTRIBUTE_UNUSED,
|
||||
union un3 u7 ATTRIBUTE_UNUSED,
|
||||
union un3 u8 ATTRIBUTE_UNUSED)
|
||||
{
|
||||
check_m256_arguments;
|
||||
}
|
||||
|
||||
void
|
||||
check_union_passing4(union un4 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_passing5(union un5 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_passing1 WRAP_CALL(check_union_passing1)
|
||||
#define check_union_passing2 WRAP_CALL(check_union_passing2)
|
||||
#define check_union_passing3 WRAP_CALL(check_union_passing3)
|
||||
#define check_union_passing4 WRAP_CALL(check_union_passing4)
|
||||
#define check_union_passing5 WRAP_CALL(check_union_passing5)
|
||||
|
||||
static void
|
||||
avx_test (void)
|
||||
{
|
||||
union un1 u1[8];
|
||||
union un2 u2[8];
|
||||
union un3 u3[8];
|
||||
union un4 u4;
|
||||
union un5 u5;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
u1[i].x = (__m256){32+i, 0, i, 0, -i, 0, i - 12, i + 8};
|
||||
|
||||
clear_struct_registers;
|
||||
for (i = 0; i < 8; i++)
|
||||
fregs.ymm0._m256[i] = u1[i].x;
|
||||
num_fregs = 8;
|
||||
check_union_passing1(u1[0], u1[1], u1[2], u1[3],
|
||||
u1[4], u1[5], u1[6], u1[7]);
|
||||
|
||||
clear_struct_registers;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
u2[i].x = u1[i].x;
|
||||
fregs.ymm0._m256[i] = u2[i].x;
|
||||
}
|
||||
num_fregs = 8;
|
||||
check_union_passing2(u2[0], u2[1], u2[2], u2[3],
|
||||
u2[4], u2[5], u2[6], u2[7]);
|
||||
|
||||
clear_struct_registers;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
u3[i].x = u1[i].x;
|
||||
fregs.ymm0._m256[i] = u3[i].x;
|
||||
}
|
||||
num_fregs = 8;
|
||||
check_union_passing3(u3[0], u3[1], u3[2], u3[3],
|
||||
u3[4], u3[5], u3[6], u3[7]);
|
||||
|
||||
check_union_passing4(u4);
|
||||
check_union_passing5(u5);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user