Commit 77c4ae24 by Ian Bolton Committed by Marcus Shawcroft

AArch64 [5/10]

2012-10-23  Ian Bolton  <ian.bolton@arm.com>
	    Jim MacArthur  <jim.macarthur@arm.com>
	    Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
	    Marcus Shawcroft  <marcus.shawcroft@arm.com>
	    Nigel Stephens  <nigel.stephens@arm.com>
	    Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
	    Richard Earnshaw  <rearnsha@arm.com>
	    Sofiane Naci  <sofiane.naci@arm.com>
	    Stephen Thomas  <stephen.thomas@arm.com>
	    Tejas Belagod  <tejas.belagod@arm.com>
	    Yufeng Zhang  <yufeng.zhang@arm.com>

	* gcc.target/aarch64/aapcs/aapcs64.exp: New file.
	* gcc.target/aarch64/aapcs/abitest-2.h: New file.
	* gcc.target/aarch64/aapcs/abitest-common.h: New file.
	* gcc.target/aarch64/aapcs/abitest.S: New file.
	* gcc.target/aarch64/aapcs/abitest.h: New file.
	* gcc.target/aarch64/aapcs/func-ret-1.c: New file.
	* gcc.target/aarch64/aapcs/func-ret-2.c: New file.
	* gcc.target/aarch64/aapcs/func-ret-3.c: New file.
	* gcc.target/aarch64/aapcs/func-ret-3.x: New file.
	* gcc.target/aarch64/aapcs/func-ret-4.c: New file.
	* gcc.target/aarch64/aapcs/func-ret-4.x: New file.
	* gcc.target/aarch64/aapcs/ice_1.c: New file.
	* gcc.target/aarch64/aapcs/ice_2.c: New file.
	* gcc.target/aarch64/aapcs/ice_3.c: New file.
	* gcc.target/aarch64/aapcs/ice_4.c: New file.
	* gcc.target/aarch64/aapcs/ice_5.c: New file.
	* gcc.target/aarch64/aapcs/macro-def.h: New file.
	* gcc.target/aarch64/aapcs/test_1.c: New file.
	* gcc.target/aarch64/aapcs/test_10.c: New file.
	* gcc.target/aarch64/aapcs/test_11.c: New file.
	* gcc.target/aarch64/aapcs/test_12.c: New file.
	* gcc.target/aarch64/aapcs/test_13.c: New file.
	* gcc.target/aarch64/aapcs/test_14.c: New file.
	* gcc.target/aarch64/aapcs/test_15.c: New file.
	* gcc.target/aarch64/aapcs/test_16.c: New file.
	* gcc.target/aarch64/aapcs/test_17.c: New file.
	* gcc.target/aarch64/aapcs/test_18.c: New file.
	* gcc.target/aarch64/aapcs/test_19.c: New file.
	* gcc.target/aarch64/aapcs/test_2.c: New file.
	* gcc.target/aarch64/aapcs/test_20.c: New file.
	* gcc.target/aarch64/aapcs/test_21.c: New file.
	* gcc.target/aarch64/aapcs/test_22.c: New file.
	* gcc.target/aarch64/aapcs/test_23.c: New file.
	* gcc.target/aarch64/aapcs/test_24.c: New file.
	* gcc.target/aarch64/aapcs/test_25.c: New file.
	* gcc.target/aarch64/aapcs/test_26.c: New file.
	* gcc.target/aarch64/aapcs/test_3.c: New file.
	* gcc.target/aarch64/aapcs/test_4.c: New file.
	* gcc.target/aarch64/aapcs/test_5.c: New file.
	* gcc.target/aarch64/aapcs/test_6.c: New file.
	* gcc.target/aarch64/aapcs/test_7.c: New file.
	* gcc.target/aarch64/aapcs/test_8.c: New file.
	* gcc.target/aarch64/aapcs/test_9.c: New file.
	* gcc.target/aarch64/aapcs/test_align-1.c: New file.
	* gcc.target/aarch64/aapcs/test_align-2.c: New file.
	* gcc.target/aarch64/aapcs/test_align-3.c: New file.
	* gcc.target/aarch64/aapcs/test_align-4.c: New file.
	* gcc.target/aarch64/aapcs/test_complex.c: New file.
	* gcc.target/aarch64/aapcs/test_int128.c: New file.
	* gcc.target/aarch64/aapcs/test_quad_double.c: New file.
	* gcc.target/aarch64/aapcs/type-def.h: New file.
	* gcc.target/aarch64/aapcs/va_arg-1.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-10.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-11.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-12.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-2.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-3.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-4.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-5.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-6.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-7.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-8.c: New file.
	* gcc.target/aarch64/aapcs/va_arg-9.c: New file.
	* gcc.target/aarch64/aapcs/validate_memory.h: New file.
	* gcc.target/aarch64/aarch64.exp: New file.
	* gcc.target/aarch64/adc-1.c: New file.
	* gcc.target/aarch64/adc-2.c: New file.
	* gcc.target/aarch64/asm-1.c: New file.
	* gcc.target/aarch64/clrsb.c: New file.
	* gcc.target/aarch64/clz.c: New file.
	* gcc.target/aarch64/ctz.c: New file.
	* gcc.target/aarch64/csinc-1.c: New file.
	* gcc.target/aarch64/csinv-1.c: New file.
	* gcc.target/aarch64/csneg-1.c: New file.
	* gcc.target/aarch64/extend.c: New file.
	* gcc.target/aarch64/fcvt.x: New file.
	* gcc.target/aarch64/fcvt_double_int.c: New file.
	* gcc.target/aarch64/fcvt_double_long.c: New file.
	* gcc.target/aarch64/fcvt_double_uint.c: New file.
	* gcc.target/aarch64/fcvt_double_ulong.c: New file.
	* gcc.target/aarch64/fcvt_float_int.c: New file.
	* gcc.target/aarch64/fcvt_float_long.c: New file.
	* gcc.target/aarch64/fcvt_float_uint.c: New file.
	* gcc.target/aarch64/fcvt_float_ulong.c: New file.
	* gcc.target/aarch64/ffs.c: New file.
	* gcc.target/aarch64/fmadd.c: New file.
	* gcc.target/aarch64/fnmadd-fastmath.c: New file.
	* gcc.target/aarch64/frint.x: New file.
	* gcc.target/aarch64/frint_double.c: New file.
	* gcc.target/aarch64/frint_float.c: New file.
	* gcc.target/aarch64/index.c: New file.
	* gcc.target/aarch64/mneg-1.c: New file.
	* gcc.target/aarch64/mneg-2.c: New file.
	* gcc.target/aarch64/mneg-3.c: New file.
	* gcc.target/aarch64/mnegl-1.c: New file.
	* gcc.target/aarch64/mnegl-2.c: New file.
	* gcc.target/aarch64/narrow_high-intrinsics.c: New file.
	* gcc.target/aarch64/pic-constantpool1.c: New file.
	* gcc.target/aarch64/pic-symrefplus.c: New file.
	* gcc.target/aarch64/predefine_large.c: New file.
	* gcc.target/aarch64/predefine_small.c: New file.
	* gcc.target/aarch64/predefine_tiny.c: New file.
	* gcc.target/aarch64/reload-valid-spoff.c: New file.
	* gcc.target/aarch64/scalar_intrinsics.c: New file.
	* gcc.target/aarch64/table-intrinsics.c: New file.
	* gcc.target/aarch64/tst-1.c: New file.
	* gcc.target/aarch64/vect-abs-compile.c: New file.
	* gcc.target/aarch64/vect-abs.c: New file.
	* gcc.target/aarch64/vect-abs.x: New file.
	* gcc.target/aarch64/vect-compile.c: New file.
	* gcc.target/aarch64/vect-faddv-compile.c: New file.
	* gcc.target/aarch64/vect-faddv.c: New file.
	* gcc.target/aarch64/vect-faddv.x: New file.
	* gcc.target/aarch64/vect-fmax-fmin-compile.c: New file.
	* gcc.target/aarch64/vect-fmax-fmin.c: New file.
	* gcc.target/aarch64/vect-fmax-fmin.x: New file.
	* gcc.target/aarch64/vect-fmaxv-fminv-compile.c: New file.
	* gcc.target/aarch64/vect-fmaxv-fminv.x: New file.
	* gcc.target/aarch64/vect-fp-compile.c: New file.
	* gcc.target/aarch64/vect-fp.c: New file.
	* gcc.target/aarch64/vect-fp.x: New file.
	* gcc.target/aarch64/vect-mull-compile.c: New file.
	* gcc.target/aarch64/vect-mull.c: New file.
	* gcc.target/aarch64/vect-mull.x: New file.
	* gcc.target/aarch64/vect.c: New file.
	* gcc.target/aarch64/vect.x: New file.
	* gcc.target/aarch64/vector_intrinsics.c: New file.
	* gcc.target/aarch64/vfp-1.c: New file.
	* gcc.target/aarch64/volatile-bitfields-1.c: New file.
	* gcc.target/aarch64/volatile-bitfields-2.c: New file.
	* gcc.target/aarch64/volatile-bitfields-3.c: New file.
	* g++.dg/abi/aarch64_guard1.C: New file.


Co-Authored-By: Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Co-Authored-By: Jim MacArthur <jim.macarthur@arm.com>
Co-Authored-By: Marcus Shawcroft <marcus.shawcroft@arm.com>
Co-Authored-By: Nigel Stephens <nigel.stephens@arm.com>
Co-Authored-By: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
Co-Authored-By: Richard Earnshaw <rearnsha@arm.com>
Co-Authored-By: Sofiane Naci <sofiane.naci@arm.com>
Co-Authored-By: Stephen Thomas <stephen.thomas@arm.com>
Co-Authored-By: Tejas Belagod <tejas.belagod@arm.com>
Co-Authored-By: Yufeng Zhang <yufeng.zhang@arm.com>

From-SVN: r192725
parent 5c0da018
2012-10-23 Ian Bolton <ian.bolton@arm.com>
Jim MacArthur <jim.macarthur@arm.com>
Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Marcus Shawcroft <marcus.shawcroft@arm.com>
Nigel Stephens <nigel.stephens@arm.com>
Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
Richard Earnshaw <rearnsha@arm.com>
Sofiane Naci <sofiane.naci@arm.com>
Stephen Thomas <stephen.thomas@arm.com>
Tejas Belagod <tejas.belagod@arm.com>
Yufeng Zhang <yufeng.zhang@arm.com>
* gcc.target/aarch64/aapcs/aapcs64.exp: New file.
* gcc.target/aarch64/aapcs/abitest-2.h: New file.
* gcc.target/aarch64/aapcs/abitest-common.h: New file.
* gcc.target/aarch64/aapcs/abitest.S: New file.
* gcc.target/aarch64/aapcs/abitest.h: New file.
* gcc.target/aarch64/aapcs/func-ret-1.c: New file.
* gcc.target/aarch64/aapcs/func-ret-2.c: New file.
* gcc.target/aarch64/aapcs/func-ret-3.c: New file.
* gcc.target/aarch64/aapcs/func-ret-3.x: New file.
* gcc.target/aarch64/aapcs/func-ret-4.c: New file.
* gcc.target/aarch64/aapcs/func-ret-4.x: New file.
* gcc.target/aarch64/aapcs/ice_1.c: New file.
* gcc.target/aarch64/aapcs/ice_2.c: New file.
* gcc.target/aarch64/aapcs/ice_3.c: New file.
* gcc.target/aarch64/aapcs/ice_4.c: New file.
* gcc.target/aarch64/aapcs/ice_5.c: New file.
* gcc.target/aarch64/aapcs/macro-def.h: New file.
* gcc.target/aarch64/aapcs/test_1.c: New file.
* gcc.target/aarch64/aapcs/test_10.c: New file.
* gcc.target/aarch64/aapcs/test_11.c: New file.
* gcc.target/aarch64/aapcs/test_12.c: New file.
* gcc.target/aarch64/aapcs/test_13.c: New file.
* gcc.target/aarch64/aapcs/test_14.c: New file.
* gcc.target/aarch64/aapcs/test_15.c: New file.
* gcc.target/aarch64/aapcs/test_16.c: New file.
* gcc.target/aarch64/aapcs/test_17.c: New file.
* gcc.target/aarch64/aapcs/test_18.c: New file.
* gcc.target/aarch64/aapcs/test_19.c: New file.
* gcc.target/aarch64/aapcs/test_2.c: New file.
* gcc.target/aarch64/aapcs/test_20.c: New file.
* gcc.target/aarch64/aapcs/test_21.c: New file.
* gcc.target/aarch64/aapcs/test_22.c: New file.
* gcc.target/aarch64/aapcs/test_23.c: New file.
* gcc.target/aarch64/aapcs/test_24.c: New file.
* gcc.target/aarch64/aapcs/test_25.c: New file.
* gcc.target/aarch64/aapcs/test_26.c: New file.
* gcc.target/aarch64/aapcs/test_3.c: New file.
* gcc.target/aarch64/aapcs/test_4.c: New file.
* gcc.target/aarch64/aapcs/test_5.c: New file.
* gcc.target/aarch64/aapcs/test_6.c: New file.
* gcc.target/aarch64/aapcs/test_7.c: New file.
* gcc.target/aarch64/aapcs/test_8.c: New file.
* gcc.target/aarch64/aapcs/test_9.c: New file.
* gcc.target/aarch64/aapcs/test_align-1.c: New file.
* gcc.target/aarch64/aapcs/test_align-2.c: New file.
* gcc.target/aarch64/aapcs/test_align-3.c: New file.
* gcc.target/aarch64/aapcs/test_align-4.c: New file.
* gcc.target/aarch64/aapcs/test_complex.c: New file.
* gcc.target/aarch64/aapcs/test_int128.c: New file.
* gcc.target/aarch64/aapcs/test_quad_double.c: New file.
* gcc.target/aarch64/aapcs/type-def.h: New file.
* gcc.target/aarch64/aapcs/va_arg-1.c: New file.
* gcc.target/aarch64/aapcs/va_arg-10.c: New file.
* gcc.target/aarch64/aapcs/va_arg-11.c: New file.
* gcc.target/aarch64/aapcs/va_arg-12.c: New file.
* gcc.target/aarch64/aapcs/va_arg-2.c: New file.
* gcc.target/aarch64/aapcs/va_arg-3.c: New file.
* gcc.target/aarch64/aapcs/va_arg-4.c: New file.
* gcc.target/aarch64/aapcs/va_arg-5.c: New file.
* gcc.target/aarch64/aapcs/va_arg-6.c: New file.
* gcc.target/aarch64/aapcs/va_arg-7.c: New file.
* gcc.target/aarch64/aapcs/va_arg-8.c: New file.
* gcc.target/aarch64/aapcs/va_arg-9.c: New file.
* gcc.target/aarch64/aapcs/validate_memory.h: New file.
* gcc.target/aarch64/aarch64.exp: New file.
* gcc.target/aarch64/adc-1.c: New file.
* gcc.target/aarch64/adc-2.c: New file.
* gcc.target/aarch64/asm-1.c: New file.
* gcc.target/aarch64/clrsb.c: New file.
* gcc.target/aarch64/clz.c: New file.
* gcc.target/aarch64/ctz.c: New file.
* gcc.target/aarch64/csinc-1.c: New file.
* gcc.target/aarch64/csinv-1.c: New file.
* gcc.target/aarch64/csneg-1.c: New file.
* gcc.target/aarch64/extend.c: New file.
* gcc.target/aarch64/fcvt.x: New file.
* gcc.target/aarch64/fcvt_double_int.c: New file.
* gcc.target/aarch64/fcvt_double_long.c: New file.
* gcc.target/aarch64/fcvt_double_uint.c: New file.
* gcc.target/aarch64/fcvt_double_ulong.c: New file.
* gcc.target/aarch64/fcvt_float_int.c: New file.
* gcc.target/aarch64/fcvt_float_long.c: New file.
* gcc.target/aarch64/fcvt_float_uint.c: New file.
* gcc.target/aarch64/fcvt_float_ulong.c: New file.
* gcc.target/aarch64/ffs.c: New file.
* gcc.target/aarch64/fmadd.c: New file.
* gcc.target/aarch64/fnmadd-fastmath.c: New file.
* gcc.target/aarch64/frint.x: New file.
* gcc.target/aarch64/frint_double.c: New file.
* gcc.target/aarch64/frint_float.c: New file.
* gcc.target/aarch64/index.c: New file.
* gcc.target/aarch64/mneg-1.c: New file.
* gcc.target/aarch64/mneg-2.c: New file.
* gcc.target/aarch64/mneg-3.c: New file.
* gcc.target/aarch64/mnegl-1.c: New file.
* gcc.target/aarch64/mnegl-2.c: New file.
* gcc.target/aarch64/narrow_high-intrinsics.c: New file.
* gcc.target/aarch64/pic-constantpool1.c: New file.
* gcc.target/aarch64/pic-symrefplus.c: New file.
* gcc.target/aarch64/predefine_large.c: New file.
* gcc.target/aarch64/predefine_small.c: New file.
* gcc.target/aarch64/predefine_tiny.c: New file.
* gcc.target/aarch64/reload-valid-spoff.c: New file.
* gcc.target/aarch64/scalar_intrinsics.c: New file.
* gcc.target/aarch64/table-intrinsics.c: New file.
* gcc.target/aarch64/tst-1.c: New file.
* gcc.target/aarch64/vect-abs-compile.c: New file.
* gcc.target/aarch64/vect-abs.c: New file.
* gcc.target/aarch64/vect-abs.x: New file.
* gcc.target/aarch64/vect-compile.c: New file.
* gcc.target/aarch64/vect-faddv-compile.c: New file.
* gcc.target/aarch64/vect-faddv.c: New file.
* gcc.target/aarch64/vect-faddv.x: New file.
* gcc.target/aarch64/vect-fmax-fmin-compile.c: New file.
* gcc.target/aarch64/vect-fmax-fmin.c: New file.
* gcc.target/aarch64/vect-fmax-fmin.x: New file.
* gcc.target/aarch64/vect-fmaxv-fminv-compile.c: New file.
* gcc.target/aarch64/vect-fmaxv-fminv.x: New file.
* gcc.target/aarch64/vect-fp-compile.c: New file.
* gcc.target/aarch64/vect-fp.c: New file.
* gcc.target/aarch64/vect-fp.x: New file.
* gcc.target/aarch64/vect-mull-compile.c: New file.
* gcc.target/aarch64/vect-mull.c: New file.
* gcc.target/aarch64/vect-mull.x: New file.
* gcc.target/aarch64/vect.c: New file.
* gcc.target/aarch64/vect.x: New file.
* gcc.target/aarch64/vector_intrinsics.c: New file.
* gcc.target/aarch64/vfp-1.c: New file.
* gcc.target/aarch64/volatile-bitfields-1.c: New file.
* gcc.target/aarch64/volatile-bitfields-2.c: New file.
* gcc.target/aarch64/volatile-bitfields-3.c: New file.
* g++.dg/abi/aarch64_guard1.C: New file.
2012-10-23 Jakub Jelinek <jakub@redhat.com> 2012-10-23 Jakub Jelinek <jakub@redhat.com>
PR c++/54988 PR c++/54988
......
# Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# Contributed by ARM Ltd.
#
# This file is part of GCC.
#
# GCC 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, or (at your option)
# any later version.
#
# GCC 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/>. */
load_lib c-torture.exp
load_lib target-supports.exp
load_lib torture-options.exp
if { ![istarget aarch64*-*-*] } then {
return
}
torture-init
set-torture-options $C_TORTURE_OPTIONS
set additional_flags "-W -Wall -Wno-abi"
# Test parameter passing.
foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] {
if {[runtest_file_p $runtests $src]} {
c-torture-execute [list $src \
$srcdir/$subdir/abitest.S] \
$additional_flags
}
}
# Test unnamed argument retrieval via the va_arg macro.
foreach src [lsort [glob -nocomplain $srcdir/$subdir/va_arg-*.c]] {
if {[runtest_file_p $runtests $src]} {
c-torture-execute [list $src \
$srcdir/$subdir/abitest.S] \
$additional_flags
}
}
# Test function return value.
foreach src [lsort [glob -nocomplain $srcdir/$subdir/func-ret-*.c]] {
if {[runtest_file_p $runtests $src]} {
c-torture-execute [list $src \
$srcdir/$subdir/abitest.S] \
$additional_flags
}
}
# Test no internal compiler errors.
foreach src [lsort [glob -nocomplain $srcdir/$subdir/ice_*.c]] {
if {[runtest_file_p $runtests $src]} {
c-torture [list $src] \
$additional_flags
}
}
torture-finish
/* This header file should be included for the purpose of function return
value testing. */
#include "abitest-common.h"
#include "validate_memory.h"
void (*testfunc_ptr)(char* stack);
/* Helper macros to generate function name. Example of the function name:
func_return_val_1. */
#define FUNC_BASE_NAME func_return_val_
#define FUNC_NAME_COMBINE(base,suffix) base ## suffix
#define FUNC_NAME_1(base,suffix) FUNC_NAME_COMBINE(base,suffix)
#define FUNC_NAME(suffix) FUNC_NAME_1(FUNC_BASE_NAME,suffix)
#define TEST_FUNC_BASE_NAME testfunc_
#define TEST_FUNC_NAME(suffix) FUNC_NAME_1(TEST_FUNC_BASE_NAME,suffix)
#undef DUMP_STATUS
#ifdef DUMP_ENABLED
#define DUMP_STATUS(type,val) printf ("### Checking "#type" "#val"\n");
#else
#define DUMP_STATUS(type,val)
#endif
/* Generate code to do memcmp to check if the returned value is in the
correct location and has the expected value.
Note that for value that is returned in the caller-allocated memory
block, we get the address from the saved x8 register. x8 is saved
just after the callee is returned; we assume that x8 has not been
clobbered at then, although there is no requirement for the callee
preserve the value stored in x8. Luckily, all test cases here are
simple enough that x8 doesn't normally get clobbered (although not
guaranteed). */
#undef FUNC_VAL_CHECK
#define FUNC_VAL_CHECK(id, type, val, offset, layout) \
void TEST_FUNC_NAME(id)(char* stack) \
{ \
type __x = val; \
char* addr; \
DUMP_STATUS(type,val) \
if (offset != X8) \
addr = stack + offset; \
else \
addr = *(char **)(stack + X8); \
if (validate_memory (&__x, addr, sizeof (type), layout) != 0) \
abort(); \
}
/* Composite larger than 16 bytes is replaced by a pointer to a copy prepared
by the caller, so here we extrat the pointer, deref it and compare the
content with that of the original one. */
#define PTR(type, val, offset, ...) { \
type * ptr; \
DUMP_ARG(type,val) \
ptr = *(type **)(stack + offset); \
if (memcmp (ptr, &val, sizeof (type)) != 0) abort (); \
}
#include TESTFILE
MYFUNCTYPE myfunc () PCSATTR;
/* Define the function to return VAL of type TYPE. I and D in the
parameter list are two dummy parameters to help improve the detection
of bugs like a short vector being returned in X0 after copied from V0. */
#undef FUNC_VAL_CHECK
#define FUNC_VAL_CHECK(id, type, var, offset, layout) \
__attribute__ ((noinline)) type FUNC_NAME (id) (int i, double d, type t) \
{ \
asm (""::"r" (i),"r" (d)); /* asm prevents function from getting \
optimized away. Using i and d prevents \
warnings about unused parameters. \
*/ \
return t; \
}
#include TESTFILE
/* Call the function to return value and call the checking function
to validate. See the comment above for the reason of having 0 and 0.0
in the function argument list. */
#undef FUNC_VAL_CHECK
#define FUNC_VAL_CHECK(id, type, var, offset, layout) \
{ \
testfunc_ptr = TEST_FUNC_NAME(id); \
FUNC_NAME(id) (0, 0.0, var); \
myfunc (); \
}
int main()
{
which_kind_of_test = TK_RETURN;
#ifdef HAS_DATA_INIT_FUNC
init_data ();
#endif
#include TESTFILE
return 0;
}
#undef __AAPCS64_BIG_ENDIAN__
#ifdef __GNUC__
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define __AAPCS64_BIG_ENDIAN__
#endif
#else
#error unknown compiler
#endif
#define IN_FRAMEWORK
#define D0 0
#define D1 8
#define D2 16
#define D3 24
#define D4 32
#define D5 40
#define D6 48
#define D7 56
#define S0 64
#define S1 68
#define S2 72
#define S3 76
#define S4 80
#define S5 84
#define S6 88
#define S7 92
#define W0 96
#define W1 100
#define W2 104
#define W3 108
#define W4 112
#define W5 116
#define W6 120
#define W7 124
#define X0 128
#define X1 136
#define X2 144
#define X3 152
#define X4 160
#define X5 168
#define X6 176
#define X7 184
#define Q0 192
#define Q1 208
#define Q2 224
#define Q3 240
#define Q4 256
#define Q5 272
#define Q6 288
#define Q7 304
#define X8 320
#define X9 328
#define STACK 336
/* The type of test. 'myfunc' in abitest.S needs to know which kind of
test it is running to decide what to do at the runtime. Keep the
related code in abitest.S synchronized if anything is changed here. */
enum aapcs64_test_kind
{
TK_PARAM = 0, /* Test parameter passing. */
TK_VA_ARG, /* Test va_arg code generation. */
TK_RETURN /* Test function return value. */
};
int which_kind_of_test;
extern int printf (const char*, ...);
extern void abort (void);
extern void dumpregs () __asm("myfunc");
#ifndef MYFUNCTYPE
#define MYFUNCTYPE void
#endif
#ifndef PCSATTR
#define PCSATTR
#endif
#ifdef RUNTIME_ENDIANNESS_CHECK
#ifndef RUNTIME_ENDIANNESS_CHECK_FUNCTION_DEFINED
/* This helper funtion defined to detect whether there is any incompatibility
issue on endianness between compilation time and run-time environments.
TODO: review the implementation when the work of big-endian support in A64
GCC starts.
*/
static void rt_endian_check ()
{
const char* msg_endian[2] = {"little-endian", "big-endian"};
const char* msg_env[2] = {"compile-time", "run-time"};
union
{
unsigned int ui;
unsigned char ch[4];
} u;
int flag = -1;
u.ui = 0xCAFEBABE;
printf ("u.ui=0x%X, u.ch[0]=0x%X\n", u.ui, u.ch[0]);
if (u.ch[0] == 0xBE)
{
/* Little-Endian at run-time */
#ifdef __AAPCS64_BIG_ENDIAN__
/* Big-Endian at compile-time */
flag = 1;
#endif
}
else
{
/* Big-Endian at run-time */
#ifndef __AAPCS64_BIG_ENDIAN__
/* Little-Endian at compile-time */
flag = 0;
#endif
}
if (flag != -1)
{
/* Endianness conflict exists */
printf ("Error: endianness conflicts between %s and %s:\n\
\t%s: %s\n\t%s: %s\n", msg_env[0], msg_env[1], msg_env[0], msg_endian[flag],
msg_env[1], msg_endian[1-flag]);
abort ();
}
return;
}
#endif
#define RUNTIME_ENDIANNESS_CHECK_FUNCTION_DEFINED
#endif
.global dumpregs
.global myfunc
.type dumpregs,%function
.type myfunc,%function
dumpregs:
myfunc:
mov x16, sp
mov x17, sp
sub sp, sp, 352 // 336 for registers and 16 for old sp and lr
stp x8, x9, [x17, #-16]! //320
stp q6, q7, [x17, #-32]! //288
stp q4, q5, [x17, #-32]! //256
stp q2, q3, [x17, #-32]! //224
stp q0, q1, [x17, #-32]! //192
stp x6, x7, [x17, #-16]! //176
stp x4, x5, [x17, #-16]! //160
stp x2, x3, [x17, #-16]! //144
stp x0, x1, [x17, #-16]! //128
stp w6, w7, [x17, #-8]! //120
stp w4, w5, [x17, #-8]! //112
stp w2, w3, [x17, #-8]! //104
stp w0, w1, [x17, #-8]! // 96
stp s6, s7, [x17, #-8]! // 88
stp s4, s5, [x17, #-8]! // 80
stp s2, s3, [x17, #-8]! // 72
stp s0, s1, [x17, #-8]! // 64
stp d6, d7, [x17, #-16]! // 48
stp d4, d5, [x17, #-16]! // 32
stp d2, d3, [x17, #-16]! // 16
stp d0, d1, [x17, #-16]! // 0
add x0, sp, #16
stp x16, x30, [x17, #-16]!
adrp x9, which_kind_of_test // determine the type of test
add x9, x9, :lo12:which_kind_of_test
ldr w9, [x9, #0]
cmp w9, #1
bgt LABEL_TEST_FUNC_RETURN
bl testfunc // parameter passing test or va_arg code gen test
b LABEL_RET
LABEL_TEST_FUNC_RETURN:
adrp x9, testfunc_ptr
add x9, x9, :lo12:testfunc_ptr
ldr x9, [x9, #0]
blr x9 // function return value test
LABEL_RET:
ldp x0, x30, [sp]
mov sp, x0
ret
.weak testfunc
.weak testfunc_ptr
/* This header file should be included for the purpose of parameter passing
testing and va_arg code gen testing.
To test va_arg code gen, #define AAPCS64_TEST_STDARG in the test case.
The parameter passing test is done by passing variables/constants to
'myfunc', which pushes its incoming arguments to a memory block on the
stack and then passes the memory block address to 'testfunc'. It is inside
'testfunc' that the real parameter passing check is carried out.
The function body of 'myfunc' is in abitest.S. The declaration of 'myfunc'
is constructed during the pre-processing stage.
The va_arg code gen test has a similar workflow, apart from an extra set-up
step before calling 'myfunc'. All arguments are passed to 'stdarg_func'
first, which assigned these arguments to its local variables via either
direct assignment or va_arg macro, depending on whether an argument is named
or not. Afterwards, 'stdarg_func' calls 'myfunc' with the aforementioned
local variables as the arguments to finish the remaining steps. */
#include "abitest-common.h"
#include "validate_memory.h"
#ifdef AAPCS64_TEST_STDARG
/* Generate va_start (ap, last_named_arg). Note that this requires
LAST_NAMED_ARG_ID to be defined/used correctly in the test file. */
#ifndef LAST_NAMED_ARG_ID
#define LAST_NAMED_ARG_ID 65535
#endif
#ifndef VA_START
#undef VA_START_1
#define VA_START_1(ap, id) va_start (ap, _f##id);
#define VA_START(ap, id) VA_START_1 (ap, id);
#endif
#endif /* AAPCS64_TEST_STDARG */
/* Some debugging facility. */
#undef DUMP_ARG
#ifdef DUMP_ENABLED
#define DUMP_ARG(type,val) printf ("### Checking ARG "#type" "#val"\n")
#else
#define DUMP_ARG(type,val)
#endif
/* Function called from myfunc (defined in abitest.S) to check the arguments
passed to myfunc. myfunc has pushed all the arguments into the memory
block pointed by STACK. */
void testfunc(char* stack)
{
#define AARCH64_MACRO_DEF_CHECK_INCOMING_ARGS
#include "macro-def.h"
#include TESTFILE
#undef AARCH64_MACRO_DEF_CHECK_INCOMING_ARGS
return;
}
#ifndef AAPCS64_TEST_STDARG
/* Test parameter passing. */
/* Function declaration of myfunc. */
MYFUNCTYPE myfunc(
#define AARCH64_MACRO_DEF_GEN_PARAM_TYPE_LIST
#include "macro-def.h"
#include TESTFILE
#undef AARCH64_MACRO_DEF_GEN_PARAM_TYPE_LIST
) PCSATTR;
#else /* AAPCS64_TEST_STDARG */
/* Test stdarg macros, e.g. va_arg. */
#include <stdarg.h>
/* Dummy function to help reset parameter passing registers, i.e. X0-X7
and V0-V7 (by being passed 0 in W0-W7 and 0.f in S0-S7). */
__attribute__ ((noinline)) void
dummy_func (int w0, int w1, int w2, int w3, int w4, int w5, int w6, int w7,
float s0, float s1, float s2, float s3, float s4, float s5,
float s6, float s7)
{
asm (""); /* Prevent function from getting optimized away */
return;
}
/* Function declaration of myfunc. */
MYFUNCTYPE myfunc(
#define AARCH64_VARIADIC_MACRO_DEF_GEN_PARAM_TYPE_LIST
#include "macro-def.h"
#include TESTFILE
#undef AARCH64_VARIADIC_MACRO_DEF_GEN_PARAM_TYPE_LIST
) PCSATTR;
/* Function definition of stdarg_func.
stdarg_func is a variadic function; it retrieves all of its arguments,
both named and unnamed, and passes them to myfunc in the identical
order. myfunc will carry out the check on the passed values. Remember
that myfunc is not a variadic function. */
MYFUNCTYPE stdarg_func(
#define AARCH64_VARIADIC_MACRO_DEF_GEN_PARAM_TYPE_LIST_WITH_IDENT
#include "macro-def.h"
#include TESTFILE
#undef AARCH64_VARIADIC_MACRO_DEF_GEN_PARAM_TYPE_LIST_WITH_IDENT
) PCSATTR
{
/* Start of the function body of stdarg_func. */
va_list ap;
VA_START (ap, LAST_NAMED_ARG_ID)
/* Zeroize the content of X0-X7 and V0-V7 to make sure that any va_arg
failure will not be hidden by the old data being in these registers. */
dummy_func (0, 0, 0, 0, 0, 0, 0, 0, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
/* A full memory barrier to ensure that compiler won't optimize away
va_arg code gen. */
__sync_synchronize ();
{
/* Assign all the function incoming arguments to local variables. */
#define AARCH64_VARIADIC_MACRO_DEF_ASSIGN_LOCAL_VARS_WITH_ARGS
#include "macro-def.h"
#include TESTFILE
#undef AARCH64_VARIADIC_MACRO_DEF_ASSIGN_LOCAL_VARS_WITH_ARGS
/* Call myfunc and pass in the local variables prepared above. */
myfunc (
#define AARCH64_VARIADIC_MACRO_DEF_GEN_ARGUMENT_LIST
#include "macro-def.h"
#include TESTFILE
#undef AARCH64_VARIADIC_MACRO_DEF_GEN_ARGUMENT_LIST
);
}
va_end (ap);
}
#endif /* AAPCS64_TEST_STDARG */
int main()
{
#ifdef RUNTIME_ENDIANNESS_CHECK
rt_endian_check();
#endif
#ifdef HAS_DATA_INIT_FUNC
init_data ();
#endif
#ifndef AAPCS64_TEST_STDARG
which_kind_of_test = TK_PARAM;
myfunc(
#else
which_kind_of_test = TK_VA_ARG;
stdarg_func(
#endif
#define AARCH64_MACRO_DEF_GEN_ARGUMENT_LIST
#include "macro-def.h"
#include TESTFILE
#undef AARCH64_MACRO_DEF_GEN_ARGUMENT_LIST
);
return 0;
}
/* Test AAPCS64 function result return.
This test covers most fundamental data types as specified in
AAPCS64 \S 4.1. */
/* { dg-do run { target aarch64*-*-* } } */
/* { dg-additional-sources "abitest.S" } */
#ifndef IN_FRAMEWORK
#define TESTFILE "func-ret-1.c"
#include "type-def.h"
vf2_t vf2 = (vf2_t){ 17.f, 18.f };
vi4_t vi4 = (vi4_t){ 0xdeadbabe, 0xbabecafe, 0xcafebeef, 0xbeefdead };
union int128_t qword;
int *int_ptr = (int *)0xabcdef0123456789ULL;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
/* Init signed quad-word integer. */
qword.l64 = 0xfdb9753102468aceLL;
qword.h64 = 0xeca8642013579bdfLL;
}
#include "abitest-2.h"
#else
FUNC_VAL_CHECK (0, unsigned char , 0xfe , X0, i8in64)
FUNC_VAL_CHECK (1, signed char , 0xed , X0, i8in64)
FUNC_VAL_CHECK (2, unsigned short, 0xdcba , X0, i16in64)
FUNC_VAL_CHECK (3, signed short, 0xcba9 , X0, i16in64)
FUNC_VAL_CHECK (4, unsigned int , 0xdeadbeef, X0, i32in64)
FUNC_VAL_CHECK (5, signed int , 0xcafebabe, X0, i32in64)
FUNC_VAL_CHECK (6, unsigned long long, 0xba98765432101234ULL, X0, flat)
FUNC_VAL_CHECK (7, signed long long, 0xa987654321012345LL, X0, flat)
FUNC_VAL_CHECK (8, __int128, qword.i, X0, flat)
FUNC_VAL_CHECK (9, float, 65432.12345f, S0, flat)
FUNC_VAL_CHECK (10, double, 9876543.212345, D0, flat)
FUNC_VAL_CHECK (11, long double, 98765432123456789.987654321L, Q0, flat)
FUNC_VAL_CHECK (12, vf2_t, vf2, D0, f32in64)
FUNC_VAL_CHECK (13, vi4_t, vi4, Q0, i32in128)
FUNC_VAL_CHECK (14, int *, int_ptr, X0, flat)
#endif
/* Test AAPCS64 function result return.
This test covers most composite types as described in AAPCS64 \S 4.3.
Homogeneous floating-point aggregate types are covered in func-ret-3.c. */
/* { dg-do run { target aarch64*-*-* } } */
/* { dg-additional-sources "abitest.S" } */
#ifndef IN_FRAMEWORK
#define TESTFILE "func-ret-2.c"
struct x0
{
char ch;
int i;
} ys0 = { 'a', 12345 };
struct x1
{
int a;
unsigned int b;
unsigned int c;
unsigned int d;
} ys1 = { 0xdeadbeef, 0xcafebabe, 0x87654321, 0xbcedf975 };
struct x2
{
long long a;
long long b;
char ch;
} y2 = { 0x12, 0x34, 0x56 };
union x3
{
char ch;
int i;
long long ll;
} y3;
union x4
{
int i;
struct x2 y2;
} y4;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
/* Init small union. */
y3.ll = 0xfedcba98LL;
/* Init big union. */
y4.y2.a = 0x78;
y4.y2.b = 0x89;
y4.y2.ch= 0x9a;
}
#include "abitest-2.h"
#else
/* Composite smaller than or equal to 16 bytes returned in X0 and X1. */
FUNC_VAL_CHECK ( 0, struct x0, ys0, X0, flat)
FUNC_VAL_CHECK ( 1, struct x1, ys1, X0, flat)
FUNC_VAL_CHECK ( 2, union x3, y3, X0, flat)
/* Composite larger than 16 bytes returned in the caller-reserved memory
block of which the address is passed as an additional argument to the
function in X8. */
FUNC_VAL_CHECK (10, struct x2, y2, X8, flat)
FUNC_VAL_CHECK (11, union x4, y4, X8, flat)
#endif
/* Test AAPCS64 function result return.
This test covers homogeneous floating-point aggregate types as described
in AAPCS64 \S 4.3.5. */
/* { dg-do run { target aarch64-*-* } } */
/* { dg-additional-sources "abitest.S" } */
/* { dg-require-effective-target aarch64_big_endian } */
#ifndef IN_FRAMEWORK
#define TESTFILE "func-ret-3.c"
#include "type-def.h"
struct hfa_fx1_t hfa_fx1 = {12.345f};
struct hfa_fx2_t hfa_fx2 = {123.456f, 234.456f};
struct hfa_dx2_t hfa_dx2 = {234.567, 345.678};
struct hfa_dx4_t hfa_dx4 = {1234.123, 2345.234, 3456.345, 4567.456};
struct hfa_ldx3_t hfa_ldx3 = {123456.7890, 234567.8901, 345678.9012};
struct non_hfa_fx5_t non_hfa_fx5 = {456.789f, 567.890f, 678.901f, 789.012f, 890.123f};
struct hfa_ffs_t hfa_ffs;
struct non_hfa_ffs_t non_hfa_ffs;
struct non_hfa_ffs_2_t non_hfa_ffs_2;
struct hva_vf2x1_t hva_vf2x1;
struct hva_vi4x1_t hva_vi4x1;
struct non_hfa_ffd_t non_hfa_ffd = {23.f, 24.f, 25.0};
struct non_hfa_ii_t non_hfa_ii = {26, 27};
struct non_hfa_c_t non_hfa_c = {28};
struct non_hfa_ffvf2_t non_hfa_ffvf2;
struct non_hfa_fffd_t non_hfa_fffd = {33.f, 34.f, 35.f, 36.0};
union hfa_union_t hfa_union;
union non_hfa_union_t non_hfa_union;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
hva_vf2x1.a = (vf2_t){17.f, 18.f};
hva_vi4x1.a = (vi4_t){19, 20, 21, 22};
non_hfa_ffvf2.a = 29.f;
non_hfa_ffvf2.b = 30.f;
non_hfa_ffvf2.c = (vf2_t){31.f, 32.f};
hfa_union.s.a = 37.f;
hfa_union.s.b = 38.f;
hfa_union.c = 39.f;
non_hfa_union.a = 40.0;
non_hfa_union.b = 41.f;
hfa_ffs.a = 42.f;
hfa_ffs.b = 43.f;
hfa_ffs.c.a = 44.f;
hfa_ffs.c.b = 45.f;
non_hfa_ffs.a = 46.f;
non_hfa_ffs.b = 47.f;
non_hfa_ffs.c.a = 48.0;
non_hfa_ffs.c.b = 49.0;
non_hfa_ffs_2.s.a = 50;
non_hfa_ffs_2.s.b = 51;
non_hfa_ffs_2.c = 52.f;
non_hfa_ffs_2.d = 53.f;
}
#include "abitest-2.h"
#else
/* HFA returned in fp/simd registers. */
FUNC_VAL_CHECK ( 0, struct hfa_fx1_t , hfa_fx1 , S0, flat)
FUNC_VAL_CHECK ( 1, struct hfa_fx2_t , hfa_fx2 , S0, flat)
FUNC_VAL_CHECK ( 2, struct hfa_dx2_t , hfa_dx2 , D0, flat)
FUNC_VAL_CHECK ( 3, struct hfa_dx4_t , hfa_dx4 , D0, flat)
FUNC_VAL_CHECK ( 4, struct hfa_ldx3_t, hfa_ldx3 , Q0, flat)
FUNC_VAL_CHECK ( 5, struct hfa_ffs_t , hfa_ffs , S0, flat)
FUNC_VAL_CHECK ( 6, union hfa_union_t, hfa_union, S0, flat)
FUNC_VAL_CHECK ( 7, struct hva_vf2x1_t, hva_vf2x1, D0, flat)
FUNC_VAL_CHECK ( 8, struct hva_vi4x1_t, hva_vi4x1, Q0, flat)
/* Non-HFA returned in general registers or via a pointer in X8. */
FUNC_VAL_CHECK (10, struct non_hfa_fx5_t , non_hfa_fx5 , X8, flat)
FUNC_VAL_CHECK (13, struct non_hfa_ffd_t , non_hfa_ffd , X0, flat)
FUNC_VAL_CHECK (14, struct non_hfa_ii_t , non_hfa_ii , X0, flat)
FUNC_VAL_CHECK (15, struct non_hfa_c_t , non_hfa_c , X0, flat)
FUNC_VAL_CHECK (16, struct non_hfa_ffvf2_t, non_hfa_ffvf2, X0, flat)
FUNC_VAL_CHECK (17, struct non_hfa_fffd_t , non_hfa_fffd , X8, flat)
FUNC_VAL_CHECK (18, struct non_hfa_ffs_t , non_hfa_ffs , X8, flat)
FUNC_VAL_CHECK (19, struct non_hfa_ffs_2_t, non_hfa_ffs_2, X0, flat)
FUNC_VAL_CHECK (20, union non_hfa_union_t, non_hfa_union, X0, flat)
#endif
/* Test AAPCS64 function result return.
This test covers complex types. Complex floating-point types are treated
as homogeneous floating-point aggregates, while complex integral types
are treated as general composite types. */
/* { dg-do run { target aarch64*-*-* } } */
/* { dg-additional-sources "abitest.S" } */
/* { dg-require-effective-target aarch64_big_endian } */
#ifndef IN_FRAMEWORK
#define TESTFILE "func-ret-4.c"
#include "abitest-2.h"
#else
/* Complex floating-point types are passed in fp/simd registers. */
FUNC_VAL_CHECK ( 0, _Complex float , 12.3f + 23.4fi, S0, flat)
FUNC_VAL_CHECK ( 1, _Complex double, 34.56 + 45.67i, D0, flat)
FUNC_VAL_CHECK ( 2, _Complex long double, 56789.01234 + 67890.12345i, Q0, flat)
/* Complex integral types are passed in general registers or via a pointer in
X8. */
FUNC_VAL_CHECK (10, _Complex short , 12345 + 23456i, X0, flat)
FUNC_VAL_CHECK (11, _Complex int , 34567 + 45678i, X0, flat)
FUNC_VAL_CHECK (12, _Complex __int128, 567890 + 678901i, X8, flat)
#endif
/* Test AAPCS layout
Empty, i.e. zero-sized, small struct passing used to cause Internal Compiler
Error. */
/* { dg-do compile { target aarch64*-*-* } } */
struct AAAA
{
} aaaa;
void named (int, struct AAAA);
void unnamed (int, ...);
void foo ()
{
name (0, aaaa);
unnamed (0, aaaa);
}
/* Test AAPCS layout
Larger than machine-supported vector size. The behaviour is unspecified by
the AAPCS64 document; the implementation opts for pass by reference. */
/* { dg-do compile { target aarch64*-*-* } } */
typedef char A __attribute__ ((vector_size (64)));
void
foo (A a)
{
}
/* Test AAPCS layout
/* { dg-do compile { target aarch64*-*-* } } */
#define vector __attribute__((vector_size(16)))
void
foo(int a, ...);
int
main(void)
{
foo (1, (vector unsigned int){10,11,12,13},
2, (vector unsigned int){20,21,22,23});
return 0;
}
/* Test AAPCS layout
/* { dg-do compile { target aarch64*-*-* } } */
__complex__ long int
ctest_long_int(__complex__ long int x)
{
return x;
}
/* { dg-do compile { target aarch64*-*-* } } */
struct S
{
union
{
long double b;
} a;
};
struct S s;
extern struct S a[5];
extern struct S check (struct S, struct S *, struct S);
extern void checkx (struct S);
void test (void)
{
checkx (check (s, &a[1], a[2]));
}
/* Test AAPCS64 layout */
/* C.7 If the argument is an Integral Type, the size of the argument is
less than or equal to 8 bytes and the NGRN is less than 8, the
argument is copied to the least significant bits in x[NGRN]. The
NGRN is incremented by one. The argument has now been allocated. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_1.c"
/* TODO: review if we need this */
#define RUNTIME_ENDIANNESS_CHECK
#include "abitest.h"
#else
ARG(int, 4, W0)
ARG(double, 4.0, D0)
ARG(int, 3, W1)
/* TODO: review the way of memcpy char, short, etc. */
#ifndef __AAPCS64_BIG_ENDIAN__
ARG(char, 0xEF, X2)
ARG(short, 0xBEEF, X3)
ARG(int, 0xDEADBEEF, X4)
#else
/* TODO: need the model/qemu to be big-endian as well */
ARG(char, 0xEF, X2+7)
ARG(short, 0xBEEF, X3+6)
ARG(int, 0xDEADBEEF, X4+4)
#endif
LAST_ARG(long long, 0xDEADBEEFCAFEBABELL, X5)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_10.c"
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(int, 7, W0)
DOTS
ANON(struct z, a, D0)
ANON(struct z, b, D4)
ANON(double, 0.5, STACK)
LAST_ANON(double, 1.5, STACK+8)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_11.c"
__complex__ x = 1.0+2.0i;
struct y
{
int p;
int q;
int r;
int s;
} v = { 1, 2, 3, 4 };
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(double, 11.0, D0)
DOTS
ANON(struct z, a, D1)
ANON(struct z, b, STACK)
LAST_ANON(double, 0.5, STACK+32)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_12.c"
struct y
{
long p;
long q;
long r;
long s;
} v = { 1, 2, 3, 4 };
struct y1
{
int p;
int q;
int r;
int s;
} v1 = { 1, 2, 3, 4 };
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#define MYFUNCTYPE struct y
#include "abitest.h"
#else
ARG(int, 7, W0)
ARG(struct y1, v1, X1)
ARG(struct z, a, D0)
ARG(struct z, b, D4)
LAST_ARG(double, 0.5, STACK)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_13.c"
struct y
{
int p;
int q;
int r;
int s;
} v = { 1, 2, 3, 4 };
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(int, 7, W0)
ARG(struct y, v, X1)
ARG(struct z, a, D0)
ARG(double, 1.0, D4)
ARG(struct z, b, STACK)
LAST_ARG(double, 0.5, STACK+32)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_14.c"
struct y
{
int p;
int q;
int r;
int s;
} v = { 1, 2, 3, 4 };
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(int, 7, W0)
ARG(int, 9, W1)
ARG(struct z, a, D0)
ARG(double, 1.0, D4)
ARG(struct z, b, STACK)
ARG(int, 4, W2)
LAST_ARG(double, 0.5, STACK+32)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_15.c"
#include "abitest.h"
#else
ARG(double, 1.0, D0)
ARG(double, 2.0, D1)
ARG(double, 3.0, D2)
ARG(double, 4.0, D3)
ARG(double, 5.0, D4)
ARG(double, 6.0, D5)
ARG(double, 7.0, D6)
ARG(double, 8.0, D7)
ARG(double, 9.0, STACK)
LAST_ARG(double, 10.0, STACK+8)
#endif
/* Test AAPCS layout */
/* C.5 If the argument is a Half- or Single- precision Floating-point type,
then the size of the argument is set to 8 bytes. The effect is as if
the argument had been copied to the least significant bits of a 64-bit
register and the remaining bits filled with unspecified values. */
/* TODO: add the check of half-precision floating-point when it is supported
by the A64 GCC. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_16.c"
#include "abitest.h"
#else
ARG(float, 1.0, S0)
ARG(float, 2.0, S1)
ARG(float, 3.0, S2)
ARG(float, 4.0, S3)
ARG(float, 5.0, S4)
ARG(float, 6.0, S5)
ARG(float, 7.0, S6)
ARG(float, 8.0, S7)
#ifndef __AAPCS64_BIG_ENDIAN__
ARG(float, 9.0, STACK)
LAST_ARG(float, 10.0, STACK+8)
#else
ARG(float, 9.0, STACK+4)
LAST_ARG(float, 10.0, STACK+12)
#endif
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_17.c"
__complex__ x = 1.0+2.0i;
struct y
{
int p;
int q;
int r;
int s;
} v = { 1, 2, 3, 4 };
struct z
{
double x[4];
};
float f1 = 25.0;
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(double, 11.0, D0)
DOTS
ANON(struct z, a, D1)
ANON(struct z, b, STACK)
ANON(int , 5, W0)
ANON(double, f1, STACK+32)
LAST_ANON(double, 0.5, STACK+40)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_18.c"
struct y
{
long p;
long q;
long r;
long s;
} v = { 1, 2, 3, 4 };
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(int, 7, W0)
PTR(struct y, v, X1)
ARG(struct z, a, D0)
ARG(double, 1.0, D4)
ARG(struct z, b, STACK)
LAST_ARG(double, 0.5, STACK+32)
#endif
/* Test AAPCS64 layout. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_19.c"
struct y
{
int p1;
int p2;
float q;
int r1;
int r2;
char x;
} v = { -1, 1, 2.0f, 3, 18, 19, 20};
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(int, 7, W0)
DOTS
ANON(double, 4.0, D0)
ANON(struct z, a, D1)
ANON(struct z, b, STACK)
PTR_ANON(struct y, v, X1)
LAST_ANON(int, 10, W2)
#endif
/* Test AAPCS64 layout */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_2.c"
#include "abitest.h"
#else
ARG(float, 1.0f, S0)
ARG(double, 4.0, D1)
ARG(float, 2.0f, S2)
ARG(double, 5.0, D3)
LAST_ARG(int, 3, W0)
#endif
/* Test AAPCS64 layout */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_20.c"
#include "abitest.h"
#else
ARG(int, 8, W0)
ARG(double, 1.0, D0)
ARG(double, 2.0, D1)
ARG(double, 3.0, D2)
ARG(double, 4.0, D3)
ARG(double, 5.0, D4)
ARG(double, 6.0, D5)
ARG(double, 7.0, D6)
DOTS
ANON(_Complex double, 1234.0 + 567.0i, STACK)
LAST_ANON(double, -987.0, STACK+16)
#endif
/* Test AAPCS64 layout */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_21.c"
#include "abitest.h"
#else
ARG(int, 8, W0)
ARG(double, 1.0, D0)
ARG(double, 2.0, D1)
ARG(double, 3.0, D2)
ARG(double, 4.0, D3)
ARG(double, 5.0, D4)
ARG(double, 6.0, D5)
ARG(double, 7.0, D6)
ARG(_Complex double, 1234.0 + 567.0i, STACK)
LAST_ARG(double, -987.0, STACK+16)
#endif
/* Test AAPCS64 layout */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_22.c"
struct y
{
float p;
float q;
} v = { 345.0f, 678.0f };
#include "abitest.h"
#else
ARG(float, 123.0f, S0)
ARG(struct y, v, S1)
LAST_ARG(float, 901.0f, S3)
#endif
/* Test AAPCS64 layout.
Larger than machine-supported vector size. The behaviour is unspecified by
the AAPCS64 document; the implementation opts for pass by reference. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_23.c"
typedef char A __attribute__ ((vector_size (64)));
struct y
{
double df[8];
};
union u
{
struct y x;
A a;
} u;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
u.x.df[0] = 1.0;
u.x.df[1] = 2.0;
u.x.df[2] = 3.0;
u.x.df[3] = 4.0;
u.x.df[4] = 5.0;
u.x.df[5] = 6.0;
u.x.df[6] = 7.0;
u.x.df[7] = 8.0;
}
#include "abitest.h"
#else
ARG (float, 123.0f, S0)
PTR (A, u.a, X0)
LAST_ARG_NONFLAT (int, 0xdeadbeef, X1, i32in64)
#endif
/* Test AAPCS64 layout. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_24.c"
typedef long double TFtype;
#include "abitest.h"
#else
ARG(TFtype, 1.0, Q0)
ARG(TFtype, 2.0, Q1)
ARG(TFtype, 3.0, Q2)
ARG(TFtype, 4.0, Q3)
ARG(TFtype, 5.0, Q4)
ARG(TFtype, 6.0, Q5)
ARG(TFtype, 7.0, Q6)
ARG(TFtype, 8.0, Q7)
ARG(double, 9.0, STACK)
LAST_ARG(TFtype, 10.0, STACK+16)
#endif
/* Test AAPCS64 layout
Test homogeneous floating-point aggregates and homogeneous short-vector
aggregates, which should be passed in SIMD/FP registers or via the
stack. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_25.c"
typedef float vf2_t __attribute__((vector_size (8)));
struct x0
{
vf2_t v;
} s0;
struct x3
{
vf2_t v[2];
} s3;
struct x4
{
vf2_t v[3];
} s4;
typedef float vf4_t __attribute__((vector_size(16)));
struct x1
{
vf4_t v;
} s1;
struct x2
{
double df[3];
} s2;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
s0.v = (vf2_t){ 17.f, 18.f };
s1.v = (vf4_t){ 567.890f, 678.901f, 789.012f, 890.123f };
s2.df[0] = 123.456;
s2.df[1] = 234.567;
s2.df[2] = 345.678;
s3.v[0] = (vf2_t){ 19.f, 20.f, 21.f, 22.f };
s3.v[1] = (vf2_t){ 23.f, 24.f, 25.f, 26.f };
s4.v[0] = (vf2_t){ 27.f, 28.f, 29.f, 30.f };
s4.v[1] = (vf2_t){ 31.f, 32.f, 33.f, 34.f };
s4.v[2] = (vf2_t){ 35.f, 36.f, 37.f, 38.f };
}
#include "abitest.h"
#else
ARG_NONFLAT (struct x0, s0, Q0, f32in64)
ARG (struct x2, s2, D1)
ARG (struct x1, s1, Q4)
ARG (struct x3, s3, D5)
ARG (struct x4, s4, STACK)
ARG_NONFLAT (int, 0xdeadbeef, X0, i32in64)
LAST_ARG (double, 456.789, STACK+24)
#endif
/* Test AAPCS64 layout.
Test some small structures that should be passed in GPRs. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_26.c"
struct y0
{
char ch;
} c0 = { 'A' };
struct y2
{
long long ll[2];
} c2 = { 0xDEADBEEF, 0xCAFEBABE };
struct y3
{
int i[3];
} c3 = { 56789, 67890, 78901 };
typedef float vf2_t __attribute__((vector_size (8)));
struct x0
{
vf2_t v;
} s0;
typedef short vh4_t __attribute__((vector_size (8)));
struct x1
{
vh4_t v[2];
} s1;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
s0.v = (vf2_t){ 17.f, 18.f };
s1.v[0] = (vh4_t){ 345, 456, 567, 678 };
s1.v[1] = (vh4_t){ 789, 890, 901, 123 };
}
#include "abitest.h"
#else
ARG (struct y0, c0, X0)
ARG (struct y2, c2, X1)
ARG (struct y3, c3, X3)
ARG_NONFLAT (struct x0, s0, D0, f32in64)
ARG (struct x1, s1, D1)
LAST_ARG_NONFLAT (int, 89012, X5, i32in64)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_3.c"
__complex__ x = 1.0+2.0i;
#include "abitest.h"
#else
ARG (float, 1.0f, S0)
ARG (__complex__ double, x, D1)
ARG (float, 2.0f, S3)
ARG (double, 5.0, D4)
LAST_ARG_NONFLAT (int, 3, X0, i32in64)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target arm*-*-eabi* } } */
/* { dg-require-effective-target arm_hard_vfp_ok } */
/* { dg-require-effective-target arm32 } */
/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_4.c"
__complex__ float x = 1.0f + 2.0fi;
#include "abitest.h"
#else
ARG (float, 1.0f, S0)
ARG (__complex__ float, x, S1)
ARG (float, 2.0f, S3)
ARG (double, 5.0, D4)
LAST_ARG_NONFLAT (int, 3, X0, i32in64)
#endif
/* Test AAPCS64 layout */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_5.c"
__complex__ float x = 1.0+2.0i;
struct y
{
long p;
long q;
} v = { 1, 2};
#include "abitest.h"
#else
ARG(float, 1.0f, S0)
ARG(__complex__ float, x, S1)
ARG(float, 2.0f, S3)
ARG(double, 5.0, D4)
LAST_ARG(struct y, v, X0)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_6.c"
__complex__ double x = 1.0+2.0i;
struct y
{
int p;
int q;
int r;
int s;
} v = { 1, 2, 3, 4 };
#include "abitest.h"
#else
ARG(struct y, v, X0)
ARG(float, 1.0f, S0)
ARG(__complex__ double, x, D1)
ARG(float, 2.0f, S3)
ARG(double, 5.0, D4)
LAST_ARG(int, 3, W2)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_7.c"
__complex__ float x = 1.0f + 2.0i;
struct y
{
int p;
int q;
int r;
int s;
} v = { 1, 2, 3, 4 }, v1 = {5, 6, 7, 8}, v2 = {9, 10, 11, 12};
#include "abitest.h"
#else
ARG (struct y, v, X0)
ARG (struct y, v1, X2)
ARG (struct y, v2, X4)
ARG (int, 4, W6)
ARG (float, 1.0f, S0)
ARG (__complex__ float, x, S1)
ARG (float, 2.0f, S3)
ARG (double, 5.0, D4)
ARG (int, 3, W7)
LAST_ARG_NONFLAT (int, 5, STACK, i32in64)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_8.c"
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(struct z, a, D0)
ARG(struct z, b, D4)
ARG(double, 0.5, STACK)
ARG(int, 7, W0)
LAST_ARG(int, 8, W1)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define VFP
#define TESTFILE "test_9.c"
struct y
{
int p;
int q;
int r;
int s;
} v = { 1, 2, 3, 4 };
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(int, 7, W0)
ARG(struct y, v, X1)
ARG(struct z, a, D0)
ARG(struct z, b, D4)
LAST_ARG(double, 0.5, STACK)
#endif
/* Test AAPCS64 layout.
Test the comformance to the alignment and padding requirements.
B.4 If the argument type is a Composite Type then the size of the
argument is rounded up to the nearest multiple of 8 bytes.
C.4 If the argument is an HFA, a Quad-precision Floating-point or Short
Vector Type then the NSAA is rounded up to the larger of 8 or the
Natural Alignment of the argument's type.
C.12 The NSAA is rounded up to the larger of 8 or the Natural Alignment
of the argument's type.
C.14 If the size of the argument is less than 8 bytes then the size of
the argument is set ot 8 bytes. The effect is as if the argument
was copied to the least significant bits of a 64-bit register and
the remaining bits filled with unspecified values. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_align-1.c"
#include "type-def.h"
struct y
{
int p;
int q;
int r;
int s;
};
struct y v1 = { 1, 2, 3, 4 };
struct y v2 = { 5, 6, 7, 8 };
struct y v3 = { 9, 10, 11, 12 };
struct y v4 = { 13, 14, 15, 16 };
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
vf4_t c = { 13.f, 14.f, 15.f, 16.f };
struct x
{
vf4_t v;
} w;
char ch='a';
short sh=13;
int i=14;
long long ll=15;
struct s1
{
short sh[3];
} s1;
struct s2
{
int i[2];
char c;
} s2;
struct ldx2_t
{
long double ld[2];
} ldx2 = { 12345.67890L, 23456.78901L };
union u_t
{
long double ld;
double d[2];
} u;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
w.v = (vf4_t){ 17.f, 18.f, 19.f, 20.f };
s1.sh[0] = 16;
s1.sh[1] = 17;
s1.sh[2] = 18;
s2.i[0] = 19;
s2.i[1] = 20;
s2.c = 21;
u.ld = 34567.89012L;
}
#include "abitest.h"
#else
ARG(struct y, v1, X0)
ARG(struct y, v2, X2)
ARG(struct y, v3, X4)
ARG(struct y, v4, X6)
ARG(struct z, a, D0)
ARG(struct z, b, D4)
ARG(double, 12.5, STACK)
ARG(vf4_t, c, STACK+16) /* [C.4] 16-byte aligned short vector */
ARG(double, 17.0, STACK+32)
ARG(struct x, w, STACK+48) /* [C.12] 16-byte aligned small struct */
#ifndef __AAPCS64_BIG_ENDIAN__
ARG(char, ch, STACK+64) /* [C.14] char padded to the size of 8 bytes */
ARG(short, sh, STACK+72) /* [C.14] short padded to the size of 8 bytes */
ARG(int, i, STACK+80) /* [C.14] int padded to the size of 8 bytes */
#else
ARG(char, ch, STACK+71)
ARG(short, sh, STACK+78)
ARG(int, i, STACK+84)
#endif
ARG(long long, ll, STACK+88)
ARG(struct s1, s1, STACK+96) /* [B.4] small struct padded to the size of 8 bytes */
ARG(double, 18.0, STACK+104)
ARG(struct s2, s2, STACK+112) /* [B.4] small struct padded to the size of 16 bytes */
ARG(double, 19.0, STACK+128)
ARG(long double, 30.0L, STACK+144) /* [C.4] 16-byte aligned quad-precision */
ARG(double, 31.0, STACK+160)
ARG(struct ldx2_t, ldx2, STACK+176) /* [C.4] 16-byte aligned HFA */
ARG(double, 32.0, STACK+208)
ARG(__int128, 33, STACK+224) /* [C.12] 16-byte aligned 128-bit integer */
ARG(double, 34.0, STACK+240)
ARG(union u_t, u, STACK+256) /* [C.12] 16-byte aligned small composite (union in this case) */
LAST_ARG_NONFLAT (int, 35.0, STACK+272, i32in64)
#endif
/* Test AAPCS64 layout.
C.8 If the argument has an alignment of 16 then the NGRN is rounded up
the next even number.
The case of a small struture containing only one 16-byte aligned
quad-word integer is covered in this test. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_align-2.c"
#include "type-def.h"
struct y
{
union int128_t v;
} w;
struct x
{
long long p;
int q;
} s = {0xDEADBEEFCAFEBABELL, 0xFEEBDAED};
#define HAS_DATA_INIT_FUNC
void init_data ()
{
/* Init signed quad-word integer. */
w.v.l64 = 0xfdb9753102468aceLL;
w.v.h64 = 0xeca8642013579bdfLL;
}
#include "abitest.h"
#else
ARG(int, 0xAB, W0)
ARG(struct y, w, X2)
ARG(int, 0xCD, W4)
ARG(struct x, s, X5)
LAST_ARG(int, 0xFF00FF00, W7)
#endif
/* Test AAPCS64 layout.
C.8 If the argument has an alignment of 16 then the NGRN is rounded up
the next even number.
C.9 If the argument is an Integral Type, the size of the argument is
equal to 16 and the NGRN is less than 7, the argument is copied
to x[NGRN] and x[NGRN+1]. x[NGRN] shall contain the lower addressed
double-word of the memory representation of the argument. The
NGRN is incremented by two. The argument has now been allocated.
The case of passing a 128-bit integer in two general registers is covered
in this test. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_align-3.c"
#include "type-def.h"
union int128_t qword;
int gInt[4];
#define HAS_DATA_INIT_FUNC
void init_data ()
{
/* Initialize the quadword integer via the union. */
qword.l64 = 0xDEADBEEFCAFEBABELL;
qword.h64 = 0x123456789ABCDEF0LL;
gInt[0] = 12345;
gInt[1] = 23456;
gInt[2] = 34567;
gInt[3] = 45678;
}
#include "abitest.h"
#else
ARG(int, gInt[0], W0)
ARG(int, gInt[1], W1)
ARG(int, gInt[2], W2)
ARG(__int128, qword.i, X4)
LAST_ARG(int, gInt[3], W6)
#endif
/* Test AAPCS64 layout.
C.3 If the argument is an HFA then the NSRN is set to 8 and the size
of the argument is rounded up to the nearest multiple of 8 bytes.
TODO: add the check of an HFA containing half-precision floating-point
when __f16 is supported in A64 GCC. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_align-4.c"
struct z1
{
double x[4];
};
struct z1 a = { 5.0, 6.0, 7.0, 8.0 };
struct z2
{
float x[3];
};
struct z2 b = { 13.f, 14.f, 15.f };
struct z2 c = { 16.f, 17.f, 18.f };
#include "abitest.h"
#else
ARG(struct z1, a, D0)
ARG(double, 9.0, D4)
ARG(double, 10.0, D5)
ARG(struct z2, b, STACK) /* [C.3] on stack and size padded to 16 bytes */
#ifndef __AAPCS64_BIG_ENDIAN__
ARG(float, 15.5f, STACK+16) /* [C.3] NSRN has been set to 8 */
#else
ARG(float, 15.5f, STACK+20)
#endif
LAST_ARG(struct z2, c, STACK+24)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_complex.c"
__complex__ float x = 1.0+2.0i;
__complex__ int y = 5 + 6i;
__complex__ double z = 2.0 + 3.0i;
#include "abitest.h"
#else
ARG(__complex__ float, x, S0)
ARG(__complex__ int, y, X0)
ARG(__complex__ double, z, D2)
LAST_ARG (int, 5, W1)
#endif
/* Test AAPCS layout (VFP variant) */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_int128.c"
typedef int TItype __attribute__ ((mode (TI)));
TItype x = 0xcafecafecafecfeacfeacfea;
TItype y = 0xcfeacfeacfeacafecafecafe;
#include "abitest.h"
#else
ARG (TItype, x, X0)
LAST_ARG (TItype, y, X2)
#endif
/* Test AAPCS64 layout.
Test parameter passing of floating-point quad precision types. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define TESTFILE "test_quad_double.c"
typedef long double TFtype;
typedef _Complex long double CTFtype;
TFtype x = 1.0;
TFtype y = 2.0;
CTFtype cx = 3.0 + 4.0i;
CTFtype cy = 5.0 + 6.0i;
#include "abitest.h"
#else
ARG ( TFtype, x, Q0)
ARG (CTFtype, cx, Q1)
DOTS
ANON (CTFtype, cy, Q3)
LAST_ANON ( TFtype, y, Q5)
#endif
/* This header file defines some types that are used in the AAPCS64 tests. */
/* 64-bit vector of 2 floats. */
typedef float vf2_t __attribute__((vector_size (8)));
/* 128-bit vector of 4 floats. */
typedef float vf4_t __attribute__((vector_size (16)));
/* 128-bit vector of 4 ints. */
typedef int vi4_t __attribute__((vector_size (16)));
/* signed quad-word (in an union for the convenience of initialization). */
union int128_t
{
__int128 i;
struct
{
signed long long l64;
signed long long h64;
};
};
/* Homogeneous floating-point composite types. */
struct hfa_fx1_t
{
float a;
};
struct hfa_fx2_t
{
float a;
float b;
};
struct hfa_dx2_t
{
double a;
double b;
};
struct hfa_dx4_t
{
double a;
double b;
double c;
double d;
};
struct hfa_ldx3_t
{
long double a;
long double b;
long double c;
};
struct hfa_ffs_t
{
float a;
float b;
struct hfa_fx2_t c;
};
union hfa_union_t
{
struct
{
float a;
float b;
} s;
float c;
};
/* Non homogeneous floating-point-composite types. */
struct non_hfa_fx5_t
{
float a;
float b;
float c;
float d;
float e;
};
struct non_hfa_ffs_t
{
float a;
float b;
struct hfa_dx2_t c;
};
struct non_hfa_ffs_2_t
{
struct
{
int a;
int b;
} s;
float c;
float d;
};
struct hva_vf2x1_t
{
vf2_t a;
};
struct hva_vf2x2_t
{
vf2_t a;
vf2_t b;
};
struct hva_vi4x1_t
{
vi4_t a;
};
struct non_hfa_ffd_t
{
float a;
float b;
double c;
};
struct non_hfa_ii_t
{
int a;
int b;
};
struct non_hfa_c_t
{
char a;
};
struct non_hfa_ffvf2_t
{
float a;
float b;
vf2_t c;
};
struct non_hfa_fffd_t
{
float a;
float b;
float c;
double d;
};
union non_hfa_union_t
{
double a;
float b;
};
/* Test AAPCS64 layout and __builtin_va_arg.
This test covers fundamental data types as specified in AAPCS64 \S 4.1.
It is focus on unnamed parameter passed in registers. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-1.c"
#include "type-def.h"
vf2_t vf2 = (vf2_t){ 17.f, 18.f };
vi4_t vi4 = (vi4_t){ 0xdeadbabe, 0xbabecafe, 0xcafebeef, 0xbeefdead };
union int128_t qword;
signed char sc = 0xed;
signed int sc_promoted = 0xffffffed;
signed short ss = 0xcba9;
signed int ss_promoted = 0xffffcba9;
float fp = 65432.12345f;
double fp_promoted = (double)65432.12345f;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
/* Init signed quad-word integer. */
qword.l64 = 0xfdb9753102468aceLL;
qword.h64 = 0xeca8642013579bdfLL;
}
#include "abitest.h"
#else
ARG ( int , 0xff , X0, LAST_NAMED_ARG_ID)
DOTS
ANON_PROMOTED(unsigned char , 0xfe , unsigned int, 0xfe , X1, 1)
ANON_PROMOTED( signed char , sc , signed int, sc_promoted, X2, 2)
ANON_PROMOTED(unsigned short , 0xdcba, unsigned int, 0xdcba , X3, 3)
ANON_PROMOTED( signed short , ss , signed int, ss_promoted, X4, 4)
ANON (unsigned int , 0xdeadbeef, X5, 5)
ANON ( signed int , 0xcafebabe, X6, 6)
ANON (unsigned long long, 0xba98765432101234ULL, X7, 7)
ANON ( signed long long, 0xa987654321012345LL , STACK, 8)
ANON ( __int128, qword.i , STACK+16, 9)
ANON_PROMOTED( float , fp , double, fp_promoted, D0, 10)
ANON ( double , 9876543.212345, D1, 11)
ANON ( long double , 98765432123456789.987654321L, Q2, 12)
ANON ( vf2_t, vf2 , D3, 13)
ANON ( vi4_t, vi4 , Q4, 14)
LAST_ANON ( int , 0xeeee, STACK+32,15)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
Miscellaneous test: Anonymous arguments passed on the stack. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-10.c"
struct z
{
double x[4];
};
double d1 = 25.0;
double d2 = 103.0;
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(struct z, a, D0, 0)
ARG(struct z, b, D4, LAST_NAMED_ARG_ID)
DOTS
ANON(double, d1, STACK, 2)
LAST_ANON(double, d2, STACK+8, 3)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
Miscellaneous test: Anonymous arguments passed on the stack. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-11.c"
struct z
{
double x[2];
};
double d1 = 25.0;
struct z a = { 5.0, 6.0 };
#include "abitest.h"
#else
ARG(double, 1.0, D0, 0)
ARG(double, 2.0, D1, 1)
ARG(double, 3.0, D2, 2)
ARG(double, 4.0, D3, 3)
ARG(double, 5.0, D4, 4)
ARG(double, 6.0, D5, 5)
ARG(double, 7.0, D6, LAST_NAMED_ARG_ID)
DOTS
ANON(struct z, a, STACK, 8)
LAST_ANON(double, d1, STACK+16, 9)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
Pass by reference. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-12.c"
struct z
{
char c;
short s;
int ia[4];
};
struct z a, b, c;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
a.c = 0x11;
a.s = 0x2222;
a.ia[0] = 0x33333333;
a.ia[1] = 0x44444444;
a.ia[2] = 0x55555555;
a.ia[3] = 0x66666666;
b.c = 0x77;
b.s = 0x8888;
b.ia[0] = 0x99999999;
b.ia[1] = 0xaaaaaaaa;
b.ia[2] = 0xbbbbbbbb;
b.ia[3] = 0xcccccccc;
c.c = 0xdd;
c.s = 0xeeee;
c.ia[0] = 0xffffffff;
c.ia[1] = 0x12121212;
c.ia[2] = 0x23232323;
c.ia[3] = 0x34343434;
}
#include "abitest.h"
#else
PTR(struct z, a, X0, 0)
ARG(int, 0xdeadbeef, X1, 1)
ARG(int, 0xcafebabe, X2, 2)
ARG(int, 0xdeadbabe, X3, 3)
ARG(int, 0xcafebeef, X4, 4)
ARG(int, 0xbeefdead, X5, 5)
ARG(int, 0xbabecafe, X6, LAST_NAMED_ARG_ID)
DOTS
PTR_ANON(struct z, b, X7, 7)
PTR_ANON(struct z, c, STACK, 8)
ANON(int, 0xbabedead, STACK+8, 9)
LAST_ANON(double, 123.45, D0, 10)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
This test covers fundamental data types as specified in AAPCS64 \S 4.1.
It is focus on unnamed parameter passed on stack. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-2.c"
#include "type-def.h"
vf2_t vf2 = (vf2_t){ 17.f, 18.f };
vi4_t vi4 = (vi4_t){ 0xdeadbabe, 0xbabecafe, 0xcafebeef, 0xbeefdead };
union int128_t qword;
signed char sc = 0xed;
signed int sc_promoted = 0xffffffed;
signed short ss = 0xcba9;
signed int ss_promoted = 0xffffcba9;
float fp = 65432.12345f;
double fp_promoted = (double)65432.12345f;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
/* Init signed quad-word integer. */
qword.l64 = 0xfdb9753102468aceLL;
qword.h64 = 0xeca8642013579bdfLL;
}
#include "abitest.h"
#else
ARG ( int , 0xff , X0, 0)
ARG ( float , 1.0f , S0, 1)
ARG ( float , 1.0f , S1, 2)
ARG ( float , 1.0f , S2, 3)
ARG ( float , 1.0f , S3, 4)
ARG ( float , 1.0f , S4, 5)
ARG ( float , 1.0f , S5, 6)
ARG ( float , 1.0f , S6, 7)
ARG ( float , 1.0f , S7, LAST_NAMED_ARG_ID)
DOTS
ANON ( __int128, qword.i , X2, 8)
ANON ( signed long long, 0xa987654321012345LL , X4, 9)
ANON ( __int128, qword.i , X6, 10)
ANON_PROMOTED(unsigned char , 0xfe , unsigned int, 0xfe , STACK, 11)
ANON_PROMOTED( signed char , sc , signed int, sc_promoted, STACK+8, 12)
ANON_PROMOTED(unsigned short , 0xdcba, unsigned int, 0xdcba , STACK+16, 13)
ANON_PROMOTED( signed short , ss , signed int, ss_promoted, STACK+24, 14)
ANON (unsigned int , 0xdeadbeef, STACK+32, 15)
ANON ( signed int , 0xcafebabe, STACK+40, 16)
ANON (unsigned long long, 0xba98765432101234ULL, STACK+48, 17)
ANON_PROMOTED( float , fp , double, fp_promoted, STACK+56, 18)
ANON ( double , 9876543.212345, STACK+64, 19)
ANON ( long double , 98765432123456789.987654321L, STACK+80, 20)
ANON ( vf2_t, vf2 , STACK+96, 21)
ANON ( vi4_t, vi4 , STACK+112,22)
LAST_ANON ( int , 0xeeee, STACK+128,23)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
This test covers most composite types as described in AAPCS64 \S 4.3.
Homogeneous floating-point aggregate types are covered in other tests. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-3.c"
#include "type-def.h"
struct x0
{
char ch;
int i;
} y0 = { 'a', 12345 };
struct x1
{
int a;
int b;
int c;
int d;
} y1 = { 0xdeadbeef, 0xcafebabe, 0x87654321, 0xabcedf975 };
struct x2
{
long long a;
long long b;
char ch;
} y2 = { 0x12, 0x34, 0x56 };
union x3
{
char ch;
int i;
long long ll;
} y3;
union x4
{
int i;
struct x2 y2;
} y4;
struct x5
{
union int128_t qword;
} y5;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
/* Init small union. */
y3.ll = 0xfedcba98LL;
/* Init big union. */
y4.y2.a = 0x78;
y4.y2.b = 0x89;
y4.y2.ch= 0x9a;
/* Init signed quad-word integer. */
y5.qword.l64 = 0xfdb9753102468aceLL;
y5.qword.h64 = 0xeca8642013579bdfLL;
}
#include "abitest.h"
#else
ARG (float ,1.0f, S0, LAST_NAMED_ARG_ID)
DOTS
ANON (struct x0, y0, X0, 1)
ANON (struct x1, y1, X1, 2)
PTR_ANON (struct x2, y2, X3, 3)
ANON (union x3, y3, X4, 4)
PTR_ANON (union x4, y4, X5, 5)
ANON (struct x5, y5, X6, 6)
ANON (struct x0, y0, STACK, 7)
ANON (struct x1, y1, STACK+8, 8)
PTR_ANON (struct x2, y2, STACK+24, 9)
ANON (union x3, y3, STACK+32, 10)
PTR_ANON (union x4, y4, STACK+40, 11)
ANON (int , 1, STACK+48, 12)
ANON (struct x5, y5, STACK+64, 13)
LAST_ANON(int , 2, STACK+80, 14)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
This test covers homogeneous floating-point aggregate types and homogeneous
short-vector aggregate types as described in AAPCS64 \S 4.3.5. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-4.c"
#include "type-def.h"
struct hfa_fx1_t hfa_fx1 = {12.345f};
struct hfa_fx2_t hfa_fx2 = {123.456f, 234.456f};
struct hfa_dx2_t hfa_dx2 = {234.567, 345.678};
struct hfa_dx4_t hfa_dx4 = {1234.123, 2345.234, 3456.345, 4567.456};
struct hfa_ldx3_t hfa_ldx3 = {123456.7890, 234567.8901, 345678.9012};
struct non_hfa_fx5_t non_hfa_fx5 = {456.789f, 567.890f, 678.901f, 789.012f, 890.123f};
struct hfa_ffs_t hfa_ffs;
struct non_hfa_ffs_t non_hfa_ffs;
struct non_hfa_ffs_2_t non_hfa_ffs_2;
struct hva_vf2x1_t hva_vf2x1;
struct hva_vf2x2_t hva_vf2x2;
struct hva_vi4x1_t hva_vi4x1;
struct non_hfa_ffd_t non_hfa_ffd = {23.f, 24.f, 25.0};
struct non_hfa_ii_t non_hfa_ii = {26, 27};
struct non_hfa_c_t non_hfa_c = {28};
struct non_hfa_ffvf2_t non_hfa_ffvf2;
struct non_hfa_fffd_t non_hfa_fffd = {33.f, 34.f, 35.f, 36.0};
union hfa_union_t hfa_union;
union non_hfa_union_t non_hfa_union;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
hva_vf2x1.a = (vf2_t){17.f, 18.f};
hva_vf2x2.a = (vf2_t){19.f, 20.f};
hva_vf2x2.b = (vf2_t){21.f, 22.f};
hva_vi4x1.a = (vi4_t){19, 20, 21, 22};
non_hfa_ffvf2.a = 29.f;
non_hfa_ffvf2.b = 30.f;
non_hfa_ffvf2.c = (vf2_t){31.f, 32.f};
hfa_union.s.a = 37.f;
hfa_union.s.b = 38.f;
hfa_union.c = 39.f;
non_hfa_union.a = 40.0;
non_hfa_union.b = 41.f;
hfa_ffs.a = 42.f;
hfa_ffs.b = 43.f;
hfa_ffs.c.a = 44.f;
hfa_ffs.c.b = 45.f;
non_hfa_ffs.a = 46.f;
non_hfa_ffs.b = 47.f;
non_hfa_ffs.c.a = 48.0;
non_hfa_ffs.c.b = 49.0;
non_hfa_ffs_2.s.a = 50;
non_hfa_ffs_2.s.b = 51;
non_hfa_ffs_2.c = 52.f;
non_hfa_ffs_2.d = 53.f;
}
#include "abitest.h"
#else
ARG (int , 1, X0, LAST_NAMED_ARG_ID)
DOTS
/* HFA or HVA passed in fp/simd registers or on stack. */
ANON (struct hfa_fx1_t , hfa_fx1 , S0 , 0)
ANON (struct hfa_fx2_t , hfa_fx2 , S1 , 1)
ANON (struct hfa_dx2_t , hfa_dx2 , D3 , 2)
ANON (struct hva_vf2x1_t, hva_vf2x1, D5 , 11)
ANON (struct hva_vi4x1_t, hva_vi4x1, Q6 , 12)
ANON (struct hfa_dx4_t , hfa_dx4 , STACK , 3)
ANON (struct hfa_ffs_t , hfa_ffs , STACK+32, 4)
ANON (union hfa_union_t, hfa_union, STACK+48, 5)
ANON (struct hfa_ldx3_t , hfa_ldx3 , STACK+64, 6)
/* Non-H[FV]A passed in general registers or on stack or via reference. */
PTR_ANON (struct non_hfa_fx5_t , non_hfa_fx5 , X1 , 10)
ANON (struct non_hfa_ffd_t , non_hfa_ffd , X2 , 13)
ANON (struct non_hfa_ii_t , non_hfa_ii , X4 , 14)
ANON (struct non_hfa_c_t , non_hfa_c , X5 , 15)
ANON (struct non_hfa_ffvf2_t, non_hfa_ffvf2, X6 , 16)
PTR_ANON (struct non_hfa_fffd_t , non_hfa_fffd , STACK+112, 17)
PTR_ANON (struct non_hfa_ffs_t , non_hfa_ffs , STACK+120, 18)
ANON (struct non_hfa_ffs_2_t, non_hfa_ffs_2, STACK+128, 19)
ANON (union non_hfa_union_t, non_hfa_union, STACK+144, 20)
LAST_ANON(int , 2 , STACK+152, 30)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
This test is focus on certain unnamed homogeneous floating-point aggregate
types passed in fp/simd registers. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-5.c"
#include "type-def.h"
struct hfa_fx1_t hfa_fx1 = {12.345f};
struct hfa_fx2_t hfa_fx2 = {123.456f, 234.456f};
struct hfa_dx2_t hfa_dx2 = {234.567, 345.678};
struct hfa_dx4_t hfa_dx4 = {1234.123, 2345.234, 3456.345, 4567.456};
struct hfa_ldx3_t hfa_ldx3 = {123456.7890, 234567.8901, 345678.9012};
struct hfa_ffs_t hfa_ffs;
union hfa_union_t hfa_union;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
hfa_union.s.a = 37.f;
hfa_union.s.b = 38.f;
hfa_union.c = 39.f;
hfa_ffs.a = 42.f;
hfa_ffs.b = 43.f;
hfa_ffs.c.a = 44.f;
hfa_ffs.c.b = 45.f;
}
#include "abitest.h"
#else
ARG (int, 1, X0, LAST_NAMED_ARG_ID)
DOTS
/* HFA passed in fp/simd registers or on stack. */
ANON (struct hfa_dx4_t , hfa_dx4 , D0 , 0)
ANON (struct hfa_ldx3_t , hfa_ldx3 , Q4 , 1)
ANON (struct hfa_ffs_t , hfa_ffs , STACK , 2)
ANON (union hfa_union_t, hfa_union, STACK+16, 3)
ANON (struct hfa_fx1_t , hfa_fx1 , STACK+24, 4)
ANON (struct hfa_fx2_t , hfa_fx2 , STACK+32, 5)
ANON (struct hfa_dx2_t , hfa_dx2 , STACK+40, 6)
LAST_ANON(double , 1.0 , STACK+56, 7)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
This test is focus on certain unnamed homogeneous floating-point aggregate
types passed in fp/simd registers. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-6.c"
#include "type-def.h"
struct hfa_fx1_t hfa_fx1 = {12.345f};
struct hfa_dx2_t hfa_dx2 = {234.567, 345.678};
struct hfa_ffs_t hfa_ffs;
union hfa_union_t hfa_union;
#define HAS_DATA_INIT_FUNC
void init_data ()
{
hfa_union.s.a = 37.f;
hfa_union.s.b = 38.f;
hfa_union.c = 39.f;
hfa_ffs.a = 42.f;
hfa_ffs.b = 43.f;
hfa_ffs.c.a = 44.f;
hfa_ffs.c.b = 45.f;
}
#include "abitest.h"
#else
ARG (int, 1, X0, LAST_NAMED_ARG_ID)
DOTS
ANON (struct hfa_ffs_t , hfa_ffs , S0 , 0)
ANON (union hfa_union_t, hfa_union, S4 , 1)
ANON (struct hfa_dx2_t , hfa_dx2 , D6 , 2)
ANON (struct hfa_fx1_t , hfa_fx1 , STACK , 3)
LAST_ANON(double , 1.0 , STACK+8, 4)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
This test covers complex types. Complex floating-point types are treated
as homogeneous floating-point aggregates, while complex integral types
are treated as general composite types. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-7.c"
#include "type-def.h"
_Complex __int128 complex_qword = 567890 + 678901i;
#include "abitest.h"
#else
ARG (int, 1, X0, LAST_NAMED_ARG_ID)
DOTS
/* Complex floating-point types are passed in fp/simd registers. */
ANON (_Complex float , 12.3f + 23.4fi , S0, 0)
ANON (_Complex double , 34.56 + 45.67i , D2, 1)
ANON (_Complex long double, 56789.01234L + 67890.12345Li, Q4, 2)
/* Complex integral types are passed in general registers or via reference. */
ANON (_Complex short , (short)12345 + (short)23456i, X1, 10)
ANON (_Complex int , 34567 + 45678i , X2, 11)
PTR_ANON (_Complex __int128 , complex_qword , X3, 12)
LAST_ANON(int , 1 , X4, 20)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
Miscellaneous test: HFA anonymous parameter passed in SIMD/FP regs. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-8.c"
struct z
{
double x[4];
};
struct z a = { 5.0, 6.0, 7.0, 8.0 };
#include "abitest.h"
#else
ARG(int, 0xdeadbeef, W0, LAST_NAMED_ARG_ID)
DOTS
ANON(double, 4.0, D0, 1)
LAST_ANON(struct z, a, D1, 2)
#endif
/* Test AAPCS64 layout and __builtin_va_arg.
Miscellaneous test: HFA anonymous parameter passed in SIMD/FP regs. */
/* { dg-do run { target aarch64*-*-* } } */
#ifndef IN_FRAMEWORK
#define AAPCS64_TEST_STDARG
#define TESTFILE "va_arg-9.c"
struct z
{
double x[4];
};
double d1 = 25.0;
struct z a = { 5.0, 6.0, 7.0, 8.0 };
struct z b = { 9.0, 10.0, 11.0, 12.0 };
#include "abitest.h"
#else
ARG(double, 11.0, D0, LAST_NAMED_ARG_ID)
DOTS
ANON(int, 8, W0, 1)
ANON(struct z, a, D1, 2)
ANON(struct z, b, STACK, 3)
ANON(int, 5, W1, 4)
ANON(double, d1, STACK+32, 5)
LAST_ANON(double, 0.5, STACK+40, 6)
#endif
/* Memory validation functions for AArch64 procedure call standard.
Copyright (C) 2012 Free Software Foundation, Inc.
Contributed by ARM Ltd.
This file is part of GCC.
GCC 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, or (at your option)
any later version.
GCC 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/>. */
#ifndef VALIDATE_MEMORY_H
#define VALIDATE_MEMORY_H
enum structure_type
{
flat = 0,
i32in128,
f32in64,
i8in64,
i16in64,
i32in64,
};
/* Some explicit declarations as I can't include files outside the testsuite.
*/
typedef long unsigned int size_t;
int memcmp (void *, void *, size_t);
/* These two arrays contain element size and block size data for the enumeration
above. */
const int element_size[] = { 1, 4, 4, 1, 2, 4 };
const int block_reverse_size[] = { 1, 16, 8, 8, 8, 8 };
int
validate_memory (void *mem1, char *mem2, size_t size, enum structure_type type)
{
/* In big-endian mode, the data in mem2 will have been byte-reversed in
register sized groups, while the data in mem1 will have been byte-reversed
according to the true structure of the data. To compare them, we need to
compare chunks of data in reverse order.
This is only implemented for homogeneous data layouts at the moment. For
hetrogeneous structures a custom compare case will need to be written. */
unsigned int i;
char *cmem1 = (char *) mem1;
switch (type)
{
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
case i8in64:
case i16in64:
case i32in64:
case f32in64:
case i32in128:
for (i = 0; i < size; i += element_size[type])
{
if (memcmp (cmem1 + i,
mem2 + block_reverse_size[type] - i - element_size[type],
element_size[type]))
return 1;
}
return 0;
break;
#endif
default:
break;
}
return memcmp (mem1, mem2, size);
}
#endif /* VALIDATE_MEMORY_H. */
# Specific regression driver for AArch64.
# Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# Contributed by ARM Ltd.
#
# This file is part of GCC.
#
# GCC 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, or (at your option)
# any later version.
#
# GCC 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/>. */
# GCC testsuite that uses the `dg.exp' driver.
# Exit immediately if this isn't an AArch64 target.
if {![istarget aarch64*-*-*] } then {
return
}
# Load support procs.
load_lib gcc-dg.exp
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then {
set DEFAULT_CFLAGS " -ansi -pedantic-errors"
}
# Initialize `dg'.
dg-init
# Main loop.
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
"" $DEFAULT_CFLAGS
# All done.
dg-finish
/* { dg-do compile } */
/* { dg-options "-O2" } */
volatile unsigned int w0, w1, w2, w3, w4;
volatile int result;
void test_si() {
/* { dg-final { scan-assembler "adc\tw\[0-9\]*, w\[0-9\]*, w\[0-9\]*\n" } } */
w0 = w1 + w2 + (w3 >= w4);
}
volatile unsigned long long int x0, x1, x2, x3, x4;
void test_di() {
/* { dg-final { scan-assembler "adc\tx\[0-9\]*, x\[0-9\]*, x\[0-9\]*\n" } } */
x0 = x1 + x2 + (x3 >= x4);
}
/* { dg-do run } */
/* { dg-options "-O2" } */
extern void abort (void);
/* This series of tests looks for the optimization:
x = (a >= b) + c + d
=>
cmp a, b
adc x, c, d
*/
unsigned long
ltu_add (unsigned long a, unsigned long b, unsigned long c, unsigned long d)
{
return (a < b) + c + d;
}
unsigned long
gtu_add (unsigned long a, unsigned long b, unsigned long c, unsigned long d)
{
return (a > b) + c + d;
}
unsigned long
leu_add (unsigned long a, unsigned long b, unsigned long c, unsigned long d)
{
return (a <= b) + c + d;
}
unsigned long
geu_add (unsigned long a, unsigned long b, unsigned long c, unsigned long d)
{
return (a >= b) + c + d;
}
unsigned long
equ_add (unsigned long a, unsigned long b, unsigned long c, unsigned long d)
{
return (a == b) + c + d;
}
unsigned long
neu_add (unsigned long a, unsigned long b, unsigned long c, unsigned long d)
{
return (a != b) + c + d;
}
long
lt_add ( long a, long b, long c, long d)
{
return (a < b) + c + d;
}
long
gt_add ( long a, long b, long c, long d)
{
return (a > b) + c + d;
}
long
le_add ( long a, long b, long c, long d)
{
return (a <= b) + c + d;
}
long
ge_add ( long a, long b, long c, long d)
{
return (a >= b) + c + d;
}
long
eq_add ( long a, long b, long c, long d)
{
return (a == b) + c + d;
}
long
ne_add ( long a, long b, long c, long d)
{
return (a != b) + c + d;
}
int
main ()
{
if (ltu_add(1,2,3,4) != 8)
{
abort();
}
if (ltu_add(2,2,3,4) != 7)
{
abort();
}
if (ltu_add(3,2,3,4) != 7)
{
abort();
}
if (gtu_add(2,1,3,4) != 8)
{
abort();
}
if (gtu_add(2,2,3,4) != 7)
{
abort();
}
if (gtu_add(1,2,3,4) != 7)
{
abort();
}
if (leu_add(1,2,3,4) != 8)
{
abort();
}
if (leu_add(2,2,3,4) != 8)
{
abort();
}
if (leu_add(3,2,3,4) != 7)
{
abort();
}
if (leu_add(2,1,3,4) != 7)
{
abort();
}
if (geu_add(2,1,3,4) != 8)
{
abort();
}
if (geu_add(2,2,3,4) != 8)
{
abort();
}
if (geu_add(1,2,3,4) != 7)
{
abort();
}
if (equ_add(1,2,3,4) != 7)
{
abort();
}
if (equ_add(2,2,3,4) != 8)
{
abort();
}
if (equ_add(3,2,3,4) != 7)
{
abort();
}
if (neu_add(1,2,3,4) != 8)
{
abort();
}
if (neu_add(2,2,3,4) != 7)
{
abort();
}
if (neu_add(3,2,3,4) != 8)
{
abort();
}
if (lt_add(1,2,3,4) != 8)
{
abort();
}
if (lt_add(2,2,3,4) != 7)
{
abort();
}
if (lt_add(3,2,3,4) != 7)
{
abort();
}
if (gt_add(2,1,3,4) != 8)
{
abort();
}
if (gt_add(2,2,3,4) != 7)
{
abort();
}
if (gt_add(1,2,3,4) != 7)
{
abort();
}
if (le_add(1,2,3,4) != 8)
{
abort();
}
if (le_add(2,2,3,4) != 8)
{
abort();
}
if (le_add(3,2,3,4) != 7)
{
abort();
}
if (le_add(2,1,3,4) != 7)
{
abort();
}
if (ge_add(2,1,3,4) != 8)
{
abort();
}
if (ge_add(2,2,3,4) != 8)
{
abort();
}
if (ge_add(1,2,3,4) != 7)
{
abort();
}
if (eq_add(1,2,3,4) != 7)
{
abort();
}
if (eq_add(2,2,3,4) != 8)
{
abort();
}
if (eq_add(3,2,3,4) != 7)
{
abort();
}
if (ne_add(1,2,3,4) != 8)
{
abort();
}
if (ne_add(2,2,3,4) != 7)
{
abort();
}
if (ne_add(3,2,3,4) != 8)
{
abort();
}
return 0;
}
/* { dg-error "unknown" "" {target "aarch64*-*-*" } } */
/* { dg-options "-O2 -march=dummy" } */
void f ()
{
return;
}
/* { dg-error "missing" "" {target "aarch64*-*-*" } } */
/* { dg-options "-O2 -march=+dummy" } */
void f ()
{
return;
}
/* { dg-do compile { target { aarch64*-*-* } } } */
/* { dg-options "-O2" } */
#include "arm_neon.h"
void foo ()
{
int a;
int32x2_t arg1;
int32x2_t arg2;
int32x2_t result;
arg1 = vcreate_s32 (UINT64_C (0x0000ffffffffffff));
arg2 = vcreate_s32 (UINT64_C (0x16497fffffffffff));
result = __builtin_aarch64_srsra_nv2si (arg1, arg2, a); /* { dg-error "incompatible type for argument" } */
}
/* { dg-do compile } */
/* { dg-options "-O3" } */
typedef struct
{
int i;
int y;
} __attribute__ ((aligned (16))) struct64_t;
void foo ()
{
struct64_t tmp;
asm volatile ("ldr q0, %[value]" : : [value]"m"(tmp));
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
unsigned int functest (unsigned int x)
{
return __builtin_clrsb (x);
}
/* { dg-final { scan-assembler "cls\tw" } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
unsigned int functest (unsigned int x)
{
return __builtin_clz (x);
}
/* { dg-final { scan-assembler "clz\tw" } } */
/* { dg-error "unknown" "" {target "aarch64*-*-*" } } */
/* { dg-options "-O2 -mcpu=dummy" } */
void f ()
{
return;
}
/* { dg-error "missing" "" {target "aarch64*-*-*" } } */
/* { dg-options "-O2 -mcpu=example-1+no" } */
void f ()
{
return;
}
/* { dg-error "unknown" "" {target "aarch64*-*-*" } } */
/* { dg-options "-O2 -mcpu=example-1+dummy" } */
void f ()
{
return;
}
/* { dg-error "missing" "" {target "aarch64*-*-*" } } */
/* { dg-options "-O2 -mcpu=+dummy" } */
void f ()
{
return;
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
unsigned int
test_csinc32_ifcvt(unsigned int w0,
unsigned int w1,
unsigned int w2) {
/* { dg-final { scan-assembler "csinc\tw\[0-9\]*.*ne" } } */
if (w0 == w1)
++ w2;
return w2;
}
unsigned int
test_csinc32_condasn1(unsigned int w0,
unsigned int w1,
unsigned int w2,
unsigned int w3) {
unsigned int w4;
/* { dg-final { scan-assembler "csinc\tw\[0-9\]*.*ne" } } */
w4 = (w0 == w1) ? (w3 + 1) : w2;
return w4;
}
unsigned int
test_csinc32_condasn2(unsigned int w0,
unsigned int w1,
unsigned int w2,
unsigned int w3) {
unsigned int w4;
/* { dg-final { scan-assembler "csinc\tw\[0-9\]*.*eq" } } */
w4 = (w0 == w1) ? w2 : (w3 + 1);
return w4;
}
unsigned long long
test_csinc64_ifcvt(unsigned long long x0,
unsigned long long x1,
unsigned long long x2) {
/* { dg-final { scan-assembler "csinc\tx\[0-9\]*.*ne" } } */
if (x0 == x1)
++ x2;
return x2;
}
unsigned long long
test_csinc64_condasn1(unsigned long long x0,
unsigned long long x1,
unsigned long long x2,
unsigned long long x3) {
unsigned long long x4;
/* { dg-final { scan-assembler "csinc\tx\[0-9\]*.*ne" } } */
x4 = (x0 == x1) ? (x3 + 1) : x2;
return x4;
}
unsigned long long
test_csinc64_condasn2(unsigned long long x0,
unsigned long long x1,
unsigned long long x2,
unsigned long long x3) {
unsigned long long x4;
/* { dg-final { scan-assembler "csinc\tx\[0-9\]*.*eq" } } */
x4 = (x0 == x1) ? x2 : (x3 + 1);
return x4;
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
unsigned int
test_csinv32_condasn1(unsigned int w0,
unsigned int w1,
unsigned int w2,
unsigned int w3) {
unsigned int w4;
/* { dg-final { scan-assembler "csinv\tw\[0-9\]*.*ne" } } */
w4 = (w0 == w1) ? ~w3 : w2;
return w4;
}
unsigned int
test_csinv32_condasn2(unsigned int w0,
unsigned int w1,
unsigned int w2,
unsigned int w3) {
unsigned int w4;
/* { dg-final { scan-assembler "csinv\tw\[0-9\]*.*eq" } } */
w4 = (w0 == w1) ? w3 : ~w2;
return w4;
}
unsigned long long
test_csinv64_condasn1(unsigned long long x0,
unsigned long long x1,
unsigned long long x2,
unsigned long long x3) {
unsigned long long x4;
/* { dg-final { scan-assembler "csinv\tx\[0-9\]*.*ne" } } */
x4 = (x0 == x1) ? ~x3 : x2;
return x4;
}
unsigned long long
test_csinv64_condasn2(unsigned long long x0,
unsigned long long x1,
unsigned long long x2,
unsigned long long x3) {
unsigned long long x4;
/* { dg-final { scan-assembler "csinv\tx\[0-9\]*.*eq" } } */
x4 = (x0 == x1) ? x3 : ~x2;
return x4;
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
int
test_csneg32_condasn1(int w0,
int w1,
int w2,
int w3) {
int w4;
/* { dg-final { scan-assembler "csneg\tw\[0-9\]*.*ne" } } */
w4 = (w0 == w1) ? -w3 : w2;
return w4;
}
int
test_csneg32_condasn2(int w0,
int w1,
int w2,
int w3) {
int w4;
/* { dg-final { scan-assembler "csneg\tw\[0-9\]*.*eq" } } */
w4 = (w0 == w1) ? w3 : -w2;
return w4;
}
long long
test_csneg64_condasn1(long long x0,
long long x1,
long long x2,
long long x3) {
long long x4;
/* { dg-final { scan-assembler "csneg\tx\[0-9\]*.*ne" } } */
x4 = (x0 == x1) ? -x3 : x2;
return x4;
}
long long
test_csneg64_condasn2(long long x0,
long long x1,
long long x2,
long long x3) {
long long x4;
/* { dg-final { scan-assembler "csneg\tx\[0-9\]*.*eq" } } */
x4 = (x0 == x1) ? x3 : -x2;
return x4;
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
unsigned int functest (unsigned int x)
{
return __builtin_ctz (x);
}
/* { dg-final { scan-assembler "rbit\tw" } } */
/* { dg-final { scan-assembler "clz\tw" } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
int
ldr_uxtw (int *arr, unsigned int i)
{
/* { dg-final { scan-assembler "ldr\tw\[0-9\]+,.*uxtw #?2]" } } */
return arr[i];
}
int
ldr_uxtw0 (char *arr, unsigned int i)
{
/* { dg-final { scan-assembler "ldr\tw\[0-9\]+,.*uxtw]" } } */
return arr[i];
}
int
ldr_sxtw (int *arr, int i)
{
/* { dg-final { scan-assembler "ldr\tw\[0-9\]+,.*sxtw #?2]" } } */
return arr[i];
}
int
ldr_sxtw0 (char *arr, int i)
{
/* { dg-final { scan-assembler "ldr\tw\[0-9\]+,.*sxtw]" } } */
return arr[i];
}
unsigned long long
adddi_uxtw (unsigned long long a, unsigned int i)
{
/* { dg-final { scan-assembler "add\tx\[0-9\]+,.*uxtw #?3" } } */
return a + ((unsigned long long)i << 3);
}
unsigned long long
adddi_uxtw0 (unsigned long long a, unsigned int i)
{
/* { dg-final { scan-assembler "add\tx\[0-9\]+,.*uxtw\n" } } */
return a + i;
}
long long
adddi_sxtw (long long a, int i)
{
/* { dg-final { scan-assembler "add\tx\[0-9\]+,.*sxtw #?3" } } */
return a + ((long long)i << 3);
}
long long
adddi_sxtw0 (long long a, int i)
{
/* { dg-final { scan-assembler "add\tx\[0-9\]+,.*sxtw\n" } } */
return a + i;
}
unsigned long long
subdi_uxtw (unsigned long long a, unsigned int i)
{
/* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*uxtw #?3" } } */
return a - ((unsigned long long)i << 3);
}
unsigned long long
subdi_uxtw0 (unsigned long long a, unsigned int i)
{
/* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*uxtw\n" } } */
return a - i;
}
long long
subdi_sxtw (long long a, int i)
{
/* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*sxtw #?3" } } */
return a - ((long long)i << 3);
}
long long
subdi_sxtw0 (long long a, int i)
{
/* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*sxtw\n" } } */
return a - (long long)i;
}
unsigned long long
subdi_uxth (unsigned long long a, unsigned short i)
{
/* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*uxth #?1" } } */
return a - ((unsigned long long)i << 1);
}
unsigned long long
subdi_uxth0 (unsigned long long a, unsigned short i)
{
/* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*uxth\n" } } */
return a - i;
}
long long
subdi_sxth (long long a, short i)
{
/* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*sxth #?1" } } */
return a - ((long long)i << 1);
}
long long
subdi_sxth0 (long long a, short i)
{
/* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*sxth\n" } } */
return a - (long long)i;
}
unsigned int
subsi_uxth (unsigned int a, unsigned short i)
{
/* { dg-final { scan-assembler "sub\tw\[0-9\]+,.*uxth #?1" } } */
return a - ((unsigned int)i << 1);
}
unsigned int
subsi_uxth0 (unsigned int a, unsigned short i)
{
/* { dg-final { scan-assembler "sub\tw\[0-9\]+,.*uxth\n" } } */
return a - i;
}
int
subsi_sxth (int a, short i)
{
/* { dg-final { scan-assembler "sub\tw\[0-9\]+,.*sxth #?1" } } */
return a - ((int)i << 1);
}
int
subsi_sxth0 (int a, short i)
{
/* { dg-final { scan-assembler "sub\tw\[0-9\]+,.*sxth\n" } } */
return a - (int)i;
}
unsigned int
addsi_uxth (unsigned int a, unsigned short i)
{
/* { dg-final { scan-assembler "add\tw\[0-9\]+,.*uxth #?1" } } */
return a + ((unsigned int)i << 1);
}
unsigned int
addsi_uxth0 (unsigned int a, unsigned short i)
{
/* { dg-final { scan-assembler "add\tw\[0-9\]+,.*uxth\n" } } */
return a + i;
}
int
addsi_sxth (int a, short i)
{
/* { dg-final { scan-assembler "add\tw\[0-9\]+,.*sxth #?1" } } */
return a + ((int)i << 1);
}
int
addsi_sxth0 (int a, short i)
{
/* { dg-final { scan-assembler "add\tw\[0-9\]+,.*sxth\n" } } */
return a + (int)i;
}
extern GPF SUFFIX(trunc) (GPF);
extern GPF SUFFIX(ceil) (GPF);
extern GPF SUFFIX(floor) (GPF);
extern GPF SUFFIX(round) (GPF);
GPI test1a (GPF x) {
return SUFFIX(__builtin_trunc)(x);
}
GPI test1b (GPF x)
{
return SUFFIX(trunc)(x);
}
GPI test2a (GPF x)
{
return SUFFIX(__builtin_lceil)(x);
}
GPI test2b (GPF x)
{
return SUFFIX(ceil)(x);
}
GPI test2c (GPF x)
{
return SUFFIX(__builtin_ceil)(x);
}
GPI test3a (GPF x)
{
return SUFFIX(__builtin_lfloor)(x);
}
GPI test3b (GPF x)
{
return SUFFIX(floor)(x);
}
GPI test3c (GPF x)
{
return SUFFIX(__builtin_floor)(x);
}
GPI test4a (GPF x)
{
return SUFFIX(__builtin_round)(x);
}
GPI test4b (GPF x)
{
return SUFFIX(round)(x);
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF double
#define SUFFIX(x) x
#define GPI int
#include "fcvt.x"
/* { dg-final { scan-assembler-times "fcvtzs\tw\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtps\tx\[0-9\]+, *d\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtps\tw\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtms\tx\[0-9\]+, *d\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtms\tw\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtas\tw\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF double
#define SUFFIX(x) x
#define GPI long
#include "fcvt.x"
/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtps\tx\[0-9\]+, *d\[0-9\]" 3 } } */
/* { dg-final { scan-assembler-times "fcvtms\tx\[0-9\]+, *d\[0-9\]" 3 } } */
/* { dg-final { scan-assembler-times "fcvtas\tx\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF double
#define SUFFIX(x) x
#define GPI unsigned int
#include "fcvt.x"
/* { dg-final { scan-assembler-times "fcvtzu\tw\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtps\tx\[0-9\]+, *d\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtpu\tw\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtms\tx\[0-9\]+, *d\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtmu\tw\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtau\tw\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF double
#define SUFFIX(x) x
#define GPI unsigned long
#include "fcvt.x"
/* { dg-final { scan-assembler-times "fcvtzu\tx\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtps\tx\[0-9\]+, *d\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtpu\tx\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtms\tx\[0-9\]+, *d\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtmu\tx\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtau\tx\[0-9\]+, *d\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF float
#define SUFFIX(x) x##f
#define GPI int
#include "fcvt.x"
/* { dg-final { scan-assembler-times "fcvtzs\tw\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtps\tx\[0-9\]+, *s\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtps\tw\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtms\tx\[0-9\]+, *s\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtms\tw\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtas\tw\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF float
#define SUFFIX(x) x##f
#define GPI long
#include "fcvt.x"
/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtps\tx\[0-9\]+, *s\[0-9\]" 3 } } */
/* { dg-final { scan-assembler-times "fcvtms\tx\[0-9\]+, *s\[0-9\]" 3 } } */
/* { dg-final { scan-assembler-times "fcvtas\tx\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF float
#define SUFFIX(x) x##f
#define GPI unsigned int
#include "fcvt.x"
/* { dg-final { scan-assembler-times "fcvtzu\tw\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtps\tx\[0-9\]+, *s\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtpu\tw\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtms\tx\[0-9\]+, *s\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtmu\tw\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtau\tw\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF float
#define SUFFIX(x) x##f
#define GPI unsigned long
#include "fcvt.x"
/* { dg-final { scan-assembler-times "fcvtzu\tx\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtps\tx\[0-9\]+, *s\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtpu\tx\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtms\tx\[0-9\]+, *s\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fcvtmu\tx\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "fcvtau\tx\[0-9\]+, *s\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
unsigned int functest(unsigned int x)
{
return __builtin_ffs(x);
}
/* { dg-final { scan-assembler "cmp\tw" } } */
/* { dg-final { scan-assembler "rbit\tw" } } */
/* { dg-final { scan-assembler "clz\tw" } } */
/* { dg-final { scan-assembler "csinc\tw" } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
extern double fma (double, double, double);
extern float fmaf (float, float, float);
double test_fma1 (double x, double y, double z)
{
return fma (x, y, z);
}
float test_fma2 (float x, float y, float z)
{
return fmaf (x, y, z);
}
double test_fnma1 (double x, double y, double z)
{
return fma (-x, y, z);
}
float test_fnma2 (float x, float y, float z)
{
return fmaf (-x, y, z);
}
double test_fms1 (double x, double y, double z)
{
return fma (x, y, -z);
}
float test_fms2 (float x, float y, float z)
{
return fmaf (x, y, -z);
}
double test_fnms1 (double x, double y, double z)
{
return fma (-x, y, -z);
}
float test_fnms2 (float x, float y, float z)
{
return fmaf (-x, y, -z);
}
/* { dg-final { scan-assembler-times "fmadd\td\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fmadd\ts\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fmsub\td\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fmsub\ts\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fnmsub\td\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fnmsub\ts\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fnmadd\td\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fnmadd\ts\[0-9\]" 1 } } */
/* { dg-do compile } */
/* { dg-options "-O2 -ffast-math" } */
extern double fma (double, double, double);
extern float fmaf (float, float, float);
double test_fma1 (double x, double y, double z)
{
return - fma (x, y, z);
}
float test_fma2 (float x, float y, float z)
{
return - fmaf (x, y, z);
}
/* { dg-final { scan-assembler-times "fnmadd\td\[0-9\]" 1 } } */
/* { dg-final { scan-assembler-times "fnmadd\ts\[0-9\]" 1 } } */
extern GPF SUFFIX(trunc) (GPF);
extern GPF SUFFIX(ceil) (GPF);
extern GPF SUFFIX(floor) (GPF);
extern GPF SUFFIX(nearbyint) (GPF);
extern GPF SUFFIX(rint) (GPF);
extern GPF SUFFIX(round) (GPF);
GPF test1a (GPF x)
{
return SUFFIX(__builtin_trunc)(x);
}
GPF test1b (GPF x)
{
return SUFFIX(trunc)(x);
}
GPF test2a (GPF x)
{
return SUFFIX(__builtin_ceil)(x);
}
GPF test2b (GPF x)
{
return SUFFIX(ceil)(x);
}
GPF test3a (GPF x)
{
return SUFFIX(__builtin_floor)(x);
}
GPF test3b (GPF x)
{
return SUFFIX(floor)(x);
}
GPF test4a (GPF x)
{
return SUFFIX(__builtin_nearbyint)(x);
}
GPF test4b (GPF x)
{
return SUFFIX(nearbyint)(x);
}
GPF test5a (GPF x)
{
return SUFFIX(__builtin_rint)(x);
}
GPF test5b (GPF x)
{
return SUFFIX(rint)(x);
}
GPF test6a (GPF x)
{
return SUFFIX(__builtin_round)(x);
}
GPF test6b (GPF x)
{
return SUFFIX(round)(x);
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF double
#define SUFFIX(x) x
#include "frint.x"
/* { dg-final { scan-assembler-times "frintz\td\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frintp\td\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frintm\td\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frinti\td\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frintx\td\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frinta\td\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
#define GPF float
#define SUFFIX(x) x##f
#include "frint.x"
/* { dg-final { scan-assembler-times "frintz\ts\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frintp\ts\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frintm\ts\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frinti\ts\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frintx\ts\[0-9\]" 2 } } */
/* { dg-final { scan-assembler-times "frinta\ts\[0-9\]" 2 } } */
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-not "\[us\]xtw\t" } } */
/* { dg-final { scan-assembler-not "\[us\]bfiz\t" } } */
/* { dg-final { scan-assembler-not "lsl\t" } } */
int
load_scaled_sxtw (int *arr, int i)
{
return arr[arr[i]];
}
unsigned int
load_scaled_uxtw (unsigned int *arr, unsigned int i)
{
return arr[arr[i]];
}
void
store_scaled_sxtw (int *arr, int i)
{
arr[arr[i]] = 0;
}
void
store_scaled_uxtw (unsigned int *arr, unsigned int i)
{
arr[arr[i]] = 0;
}
int
load_unscaled_sxtw (signed char *arr, int i)
{
return arr[arr[i]];
}
unsigned int
load_unscaled_uxtw (unsigned char *arr, unsigned int i)
{
return arr[arr[i]];
}
void
store_unscaled_sxtw (signed char *arr, int i)
{
arr[arr[i]] = 0;
}
void
store_unscaled_uxtw (unsigned char *arr, unsigned int i)
{
arr[arr[i]] = 0;
}
int
load_scaled_tmp_sxtw (int *arr, int i)
{
int j = arr[i];
return arr[j];
}
unsigned int
load_scaled_tmp_uxtw (unsigned int *arr, unsigned int i)
{
unsigned int j = arr[i];
return arr[j];
}
void
store_scaled_tmp_sxtw (int *arr, int i)
{
int j = arr[i];
arr[j] = 0;
}
void
store_scaled_tmp_uxtw (unsigned int *arr, unsigned int i)
{
unsigned int j = arr[i];
arr[j] = 0;
}
int
load_unscaled_tmp_sxtw (signed char *arr, int i)
{
signed char j = arr[i];
return arr[j];
}
unsigned int
load_unscaled_tmp_uxtw (unsigned char *arr, unsigned int i)
{
unsigned char j = arr[i];
return arr[j];
}
void
store_unscaled_tmp_sxtw (signed char *arr, int i)
{
signed char j = arr[i];
arr[j] = 0;
}
void
store_unscaled_tmp_uxtw (unsigned char *arr, unsigned int i)
{
unsigned char j = arr[i];
arr[j] = 0;
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
int r;
void test (int a, int b)
{
/* { dg-final { scan-assembler "mneg\tw\[0-9\]*, w\[0-9\]*, w\[0-9\]*\n" } } */
r = (-a) * b;
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
int r;
void test (int a, int b)
{
/* { dg-final { scan-assembler "mneg\tw\[0-9\]*, w\[0-9\]*, w\[0-9\]*\n" } } */
r = a * (-b);
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
int r;
void test (int a, int b)
{
/* { dg-final { scan-assembler "mneg\tw\[0-9\]*, w\[0-9\]*, w\[0-9\]*\n" } } */
r = - (a * b);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment