arm: Declare MVE types internally via pragma

Move the implementation of MVE ACLE types from arm_mve_types.h to
inside GCC via a new pragma, which replaces the prior type
definitions.  This allows for the types to be used internally for
intrinsic function definitions.

gcc/ChangeLog:

	* config.gcc (arm*-*-*): Add arm-mve-builtins.o to extra_objs.
	* config/arm/arm-c.c (arm_pragma_arm): Handle "#pragma GCC arm".
	(arm_register_target_pragmas): Register it.
	* config/arm/arm-protos.h: (arm_mve::arm_handle_mve_types_h): New
	prototype.
	* config/arm/arm_mve_types.h: Replace MVE type definitions with
	new pragma.
	* config/arm/t-arm: (arm-mve-builtins.o): New target rule.
	* config/arm/arm-mve-builtins.cc: New file.
	* config/arm/arm-mve-builtins.def: New file.
	* config/arm/arm-mve-builtins.h: New file.

gcc/testsuite/ChangeLog:

	* gcc.target/arm/mve/mve.exp: Add new subdirectories.
	* gcc.target/arm/mve/general-c/type_redef_1.c: New test.
	* gcc.target/arm/mve/general/double_pragmas_1.c: New test.
	* gcc.target/arm/mve/general/nomve_1.c: New test.
This commit is contained in:
Murray Steele 2021-12-22 14:55:07 +00:00 committed by Richard Earnshaw
parent 8c61cefe2b
commit 9c1ce17bc4
12 changed files with 399 additions and 31 deletions

View file

@ -353,14 +353,14 @@ arc*-*-*)
;;
arm*-*-*)
cpu_type=arm
extra_objs="arm-builtins.o aarch-common.o"
extra_objs="arm-builtins.o arm-mve-builtins.o aarch-common.o"
extra_headers="mmintrin.h arm_neon.h arm_acle.h arm_fp16.h arm_cmse.h arm_bf16.h arm_mve_types.h arm_mve.h arm_cde.h"
target_type_format_char='%'
c_target_objs="arm-c.o"
cxx_target_objs="arm-c.o"
d_target_objs="arm-d.o"
extra_options="${extra_options} arm/arm-tables.opt"
target_gtfiles="\$(srcdir)/config/arm/arm-builtins.c"
target_gtfiles="\$(srcdir)/config/arm/arm-builtins.c \$(srcdir)/config/arm/arm-mve-builtins.h \$(srcdir)/config/arm/arm-mve-builtins.cc"
;;
avr-*-*)
cpu_type=avr

View file

@ -28,6 +28,7 @@
#include "c-family/c-pragma.h"
#include "stringpool.h"
#include "arm-builtins.h"
#include "arm-protos.h"
tree
arm_resolve_cde_builtin (location_t loc, tree fndecl, void *arglist)
@ -129,6 +130,24 @@ arm_resolve_cde_builtin (location_t loc, tree fndecl, void *arglist)
return call_expr;
}
/* Implement "#pragma GCC arm". */
static void
arm_pragma_arm (cpp_reader *)
{
tree x;
if (pragma_lex (&x) != CPP_STRING)
{
error ("%<#pragma GCC arm%> requires a string parameter");
return;
}
const char *name = TREE_STRING_POINTER (x);
if (strcmp (name, "arm_mve_types.h") == 0)
arm_mve::handle_arm_mve_types_h ();
else
error ("unknown %<#pragma GCC arm%> option %qs", name);
}
/* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. This is currently only
used for the MVE related builtins for the CDE extension.
Here we ensure the type of arguments is such that the size is correct, and
@ -476,6 +495,8 @@ arm_register_target_pragmas (void)
targetm.target_option.pragma_parse = arm_pragma_target_parse;
targetm.resolve_overloaded_builtin = arm_resolve_overloaded_builtin;
c_register_pragma ("GCC", "arm", arm_pragma_arm);
#ifdef REGISTER_SUBTARGET_PRAGMAS
REGISTER_SUBTARGET_PRAGMAS ();
#endif

View file

@ -0,0 +1,196 @@
/* ACLE support for Arm MVE
Copyright (C) 2021 Free Software Foundation, Inc.
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/>. */
#define IN_TARGET_CODE 1
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "fold-const.h"
#include "langhooks.h"
#include "stringpool.h"
#include "attribs.h"
#include "diagnostic.h"
#include "arm-protos.h"
#include "arm-builtins.h"
#include "arm-mve-builtins.h"
namespace arm_mve {
/* Static information about each single-predicate or single-vector
ACLE type. */
struct vector_type_info
{
/* The name of the type as declared by arm_mve.h. */
const char *acle_name;
/* Whether the type requires a floating point abi. */
const bool requires_float;
};
/* Flag indicating whether the arm MVE types have been handled. */
static bool handle_arm_mve_types_p;
/* Information about each single-predicate or single-vector type. */
static CONSTEXPR const vector_type_info vector_types[] = {
#define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
{ #ACLE_NAME, REQUIRES_FLOAT },
#include "arm-mve-builtins.def"
#undef DEF_MVE_TYPE
};
/* The scalar type associated with each vector type. */
GTY(()) tree scalar_types[NUM_VECTOR_TYPES];
/* The single-predicate and single-vector types, with their built-in
"__simd128_..._t" name. Allow an index of NUM_VECTOR_TYPES, which always
yields a null tree. */
static GTY(()) tree abi_vector_types[NUM_VECTOR_TYPES + 1];
/* Same, but with the arm_mve.h names. */
GTY(()) tree acle_vector_types[3][NUM_VECTOR_TYPES + 1];
/* Return the MVE abi type with element of type TYPE. */
static tree
arm_mve_type_for_scalar_type (tree eltype)
{
for (unsigned int i = 0; i < __TYPE_FINAL; ++i)
if (arm_simd_types[i].eltype == eltype
&& GET_MODE_SIZE (arm_simd_types[i].mode) == 16)
return arm_simd_types[i].itype;
gcc_unreachable ();
}
/* Register the built-in MVE ABI vector types, such as uint32x4_t. */
static void
register_builtin_types ()
{
#define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
scalar_types[VECTOR_TYPE_ ## ACLE_NAME] = SCALAR_TYPE;
#include "arm-mve-builtins.def"
#undef DEF_MVE_TYPE
for (unsigned int i = 0; i < NUM_VECTOR_TYPES; ++i)
{
if (vector_types[i].requires_float && !TARGET_HAVE_MVE_FLOAT)
continue;
tree eltype = scalar_types[i];
tree vectype;
if (eltype == boolean_type_node)
{
vectype = get_typenode_from_name (UINT16_TYPE);
gcc_assert (GET_MODE_SIZE (TYPE_MODE (vectype)) == 2);
}
else
{
vectype = arm_mve_type_for_scalar_type (eltype);
gcc_assert (VECTOR_MODE_P (TYPE_MODE (vectype))
&& GET_MODE_SIZE (TYPE_MODE (vectype)) == 16);
}
abi_vector_types[i] = vectype;
}
}
/* Register vector type TYPE under its arm_mve.h name. */
static void
register_vector_type (vector_type_index type)
{
if (vector_types[type].requires_float && !TARGET_HAVE_MVE_FLOAT)
return;
tree vectype = abi_vector_types[type];
tree id = get_identifier (vector_types[type].acle_name);
tree decl = build_decl (input_location, TYPE_DECL, id, vectype);
decl = lang_hooks.decls.pushdecl (decl);
/* Record the new ACLE type if pushdecl succeeded without error. Use
the ABI type otherwise, so that the type we record at least has the
right form, even if it doesn't have the right name. This should give
better error recovery behavior than installing error_mark_node or
installing an incorrect type. */
if (decl
&& TREE_CODE (decl) == TYPE_DECL
&& TREE_TYPE (decl) != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == vectype)
vectype = TREE_TYPE (decl);
acle_vector_types[0][type] = vectype;
}
/* Register tuple type TYPE with NUM_VECTORS arity under its
arm_mve_types.h name. */
static void
register_builtin_tuple_types (vector_type_index type)
{
const vector_type_info* info = &vector_types[type];
if (scalar_types[type] == boolean_type_node
|| (info->requires_float && !TARGET_HAVE_MVE_FLOAT))
return;
const char *vector_type_name = info->acle_name;
char buffer[sizeof ("float32x4x2_t")];
for (unsigned int num_vectors = 2; num_vectors <= 4; num_vectors += 2)
{
snprintf (buffer, sizeof (buffer), "%.*sx%d_t",
(int) strlen (vector_type_name) - 2, vector_type_name,
num_vectors);
tree vectype = acle_vector_types[0][type];
tree arrtype = build_array_type_nelts (vectype, num_vectors);
gcc_assert (TYPE_MODE_RAW (arrtype) == TYPE_MODE (arrtype));
tree field = build_decl (input_location, FIELD_DECL,
get_identifier ("val"), arrtype);
tree t = lang_hooks.types.simulate_record_decl (input_location, buffer,
make_array_slice (&field,
1));
gcc_assert (TYPE_MODE_RAW (t) == TYPE_MODE (t));
acle_vector_types[num_vectors >> 1][type] = TREE_TYPE (t);
}
}
/* Implement #pragma GCC arm "arm_mve_types.h". */
void
handle_arm_mve_types_h ()
{
if (handle_arm_mve_types_p)
{
error ("duplicate definition of %qs", "arm_mve_types.h");
return;
}
handle_arm_mve_types_p = true;
if (!TARGET_HAVE_MVE)
{
error ("this definition requires the MVE ISA extension");
return;
}
register_builtin_types ();
for (unsigned int type_i = 0; type_i < NUM_VECTOR_TYPES; ++type_i)
{
vector_type_index type = vector_type_index (type_i);
register_vector_type (type);
if (type_i != VECTOR_TYPE_mve_pred16_t)
register_builtin_tuple_types (type);
}
}
} /* end namespace arm_mve */
using namespace arm_mve;
#include "gt-arm-mve-builtins.h"

View file

@ -0,0 +1,39 @@
/* Builtin lists for Arm MVE
Copyright (C) 2021 Free Software Foundation, Inc.
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 DEF_MVE_TYPE
#error "arm-mve-builtins.def included without defining DEF_MVE_TYPE"
#endif
#define REQUIRES_FLOAT false
DEF_MVE_TYPE (mve_pred16_t, boolean_type_node)
DEF_MVE_TYPE (uint8x16_t, unsigned_intQI_type_node)
DEF_MVE_TYPE (uint16x8_t, unsigned_intHI_type_node)
DEF_MVE_TYPE (uint32x4_t, unsigned_intSI_type_node)
DEF_MVE_TYPE (uint64x2_t, unsigned_intDI_type_node)
DEF_MVE_TYPE (int8x16_t, intQI_type_node)
DEF_MVE_TYPE (int16x8_t, intHI_type_node)
DEF_MVE_TYPE (int32x4_t, intSI_type_node)
DEF_MVE_TYPE (int64x2_t, intDI_type_node)
#undef REQUIRES_FLOAT
#define REQUIRES_FLOAT true
DEF_MVE_TYPE (float16x8_t, arm_fp16_type_node)
DEF_MVE_TYPE (float32x4_t, float_type_node)
#undef REQUIRES_FLOAT

View file

@ -0,0 +1,41 @@
/* ACLE support for Arm MVE
Copyright (C) 2021 Free Software Foundation, Inc.
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 GCC_ARM_MVE_BUILTINS_H
#define GCC_ARM_MVE_BUILTINS_H
namespace arm_mve {
/* Enumerates the MVE predicate and (data) vector types, together called
"vector types" for brevity. */
enum vector_type_index
{
#define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
VECTOR_TYPE_ ## ACLE_NAME,
#include "arm-mve-builtins.def"
NUM_VECTOR_TYPES
#undef DEF_MVE_TYPE
};
extern tree scalar_types[NUM_VECTOR_TYPES];
extern tree acle_vector_types[3][NUM_VECTOR_TYPES + 1];
} /* end namespace arm_mve */
#endif /* GCC_ARM_MVE_BUILTINS_H */

View file

@ -204,6 +204,11 @@ extern int arm_apply_result_size (void);
#endif /* RTX_CODE */
/* MVE functions. */
namespace arm_mve {
void handle_arm_mve_types_h ();
}
/* Thumb functions. */
extern void arm_init_expanders (void);
extern const char *thumb1_unexpanded_epilogue (void);

View file

@ -25,37 +25,9 @@
#if (__ARM_FEATURE_MVE & 2) /* MVE Floating point. */
typedef __fp16 float16_t;
typedef float float32_t;
typedef __simd128_float16_t float16x8_t;
typedef __simd128_float32_t float32x4_t;
typedef struct { float16x8_t val[2]; } float16x8x2_t;
typedef struct { float16x8_t val[4]; } float16x8x4_t;
typedef struct { float32x4_t val[2]; } float32x4x2_t;
typedef struct { float32x4_t val[4]; } float32x4x4_t;
#endif
typedef uint16_t mve_pred16_t;
typedef __simd128_uint8_t uint8x16_t;
typedef __simd128_uint16_t uint16x8_t;
typedef __simd128_uint32_t uint32x4_t;
typedef __simd128_uint64_t uint64x2_t;
typedef __simd128_int8_t int8x16_t;
typedef __simd128_int16_t int16x8_t;
typedef __simd128_int32_t int32x4_t;
typedef __simd128_int64_t int64x2_t;
typedef struct { int16x8_t val[2]; } int16x8x2_t;
typedef struct { int16x8_t val[4]; } int16x8x4_t;
typedef struct { int32x4_t val[2]; } int32x4x2_t;
typedef struct { int32x4_t val[4]; } int32x4x4_t;
typedef struct { int8x16_t val[2]; } int8x16x2_t;
typedef struct { int8x16_t val[4]; } int8x16x4_t;
typedef struct { uint16x8_t val[2]; } uint16x8x2_t;
typedef struct { uint16x8_t val[4]; } uint16x8x4_t;
typedef struct { uint32x4_t val[2]; } uint32x4x2_t;
typedef struct { uint32x4_t val[4]; } uint32x4x4_t;
typedef struct { uint8x16_t val[2]; } uint8x16x2_t;
typedef struct { uint8x16_t val[4]; } uint8x16x4_t;
#pragma GCC arm "arm_mve_types.h"
__extension__ extern __inline int16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))

View file

@ -153,6 +153,16 @@ arm-builtins.o: $(srcdir)/config/arm/arm-builtins.c $(CONFIG_H) \
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/arm/arm-builtins.c
arm-mve-builtins.o: $(srcdir)/config/arm/arm-mve-builtins.cc $(CONFIG_H) \
$(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
fold-const.h langhooks.h stringpool.h attribs.h diagnostic.h \
$(srcdir)/config/arm/arm-protos.h \
$(srcdir)/config/arm/arm-builtins.h \
$(srcdir)/config/arm/arm-mve-builtins.h \
$(srcdir)/config/arm/arm-mve-builtins.def
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/arm/arm-mve-builtins.cc
arm-c.o: $(srcdir)/config/arm/arm-c.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \

View file

@ -0,0 +1,67 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
int mve_pred16_t; /* { dg-message "note: previous declaration of 'mve_pred16_t'" } */
int int8x16_t; /* { dg-message "note: previous declaration of 'int8x16_t'" } */
int int16x8_t; /* { dg-message "note: previous declaration of 'int16x8_t'" } */
int int32x4_t; /* { dg-message "note: previous declaration of 'int32x4_t'" } */
int int64x2_t; /* { dg-message "note: previous declaration of 'int64x2_t'" } */
int uint8x16_t; /* { dg-message "note: previous declaration of 'uint8x16_t'" } */
int uint16x8_t; /* { dg-message "note: previous declaration of 'uint16x8_t'" } */
int uint32x4_t; /* { dg-message "note: previous declaration of 'uint32x4_t'" } */
int uint64x2_t; /* { dg-message "note: previous declaration of 'uint64x2_t'" } */
int float16x8_t; /* { dg-message "note: previous declaration of 'float16x8_t'" } */
int float32x4_t; /* { dg-message "note: previous declaration of 'float32x4_t'" } */
int int8x16x2_t; /* { dg-message "note: previous declaration of 'int8x16x2_t'" } */
int int8x16x4_t; /* { dg-message "note: previous declaration of 'int8x16x4_t'" } */
int int16x8x2_t; /* { dg-message "note: previous declaration of 'int16x8x2_t'" } */
int int16x8x4_t; /* { dg-message "note: previous declaration of 'int16x8x4_t'" } */
int int32x4x2_t; /* { dg-message "note: previous declaration of 'int32x4x2_t'" } */
int int32x4x4_t; /* { dg-message "note: previous declaration of 'int32x4x4_t'" } */
int int64x2x2_t; /* { dg-message "note: previous declaration of 'int64x2x2_t'" } */
int int64x2x4_t; /* { dg-message "note: previous declaration of 'int64x2x4_t'" } */
int uint8x16x2_t; /* { dg-message "note: previous declaration of 'uint8x16x2_t'" } */
int uint8x16x4_t; /* { dg-message "note: previous declaration of 'uint8x16x4_t'" } */
int uint16x8x2_t; /* { dg-message "note: previous declaration of 'uint16x8x2_t'" } */
int uint16x8x4_t; /* { dg-message "note: previous declaration of 'uint16x8x4_t'" } */
int uint32x4x2_t; /* { dg-message "note: previous declaration of 'uint32x4x2_t'" } */
int uint32x4x4_t; /* { dg-message "note: previous declaration of 'uint32x4x4_t'" } */
int uint64x2x2_t; /* { dg-message "note: previous declaration of 'uint64x2x2_t'" } */
int uint64x2x4_t; /* { dg-message "note: previous declaration of 'uint64x2x4_t'" } */
int float16x8x2_t; /* { dg-message "note: previous declaration of 'float16x8x2_t'" } */
int float16x8x4_t; /* { dg-message "note: previous declaration of 'float16x8x4_t'" } */
int float32x4x2_t; /* { dg-message "note: previous declaration of 'float32x4x2_t'" } */
int float32x4x4_t; /* { dg-message "note: previous declaration of 'float32x4x4_t'" } */
#pragma GCC arm "arm_mve_types.h" /* { dg-error {'mve_pred16_t' redeclared} } */
/* { dg-error {'int8x16_t' redeclared} "" {target *-*-*} .-1 } */
/* { dg-error {'int16x8_t' redeclared} "" {target *-*-*} .-2 } */
/* { dg-error {'int32x4_t' redeclared} "" {target *-*-*} .-3 } */
/* { dg-error {'int64x2_t' redeclared} "" {target *-*-*} .-4 } */
/* { dg-error {'uint8x16_t' redeclared} "" {target *-*-*} .-5 } */
/* { dg-error {'uint16x8_t' redeclared} "" {target *-*-*} .-6 } */
/* { dg-error {'uint32x4_t' redeclared} "" {target *-*-*} .-7 } */
/* { dg-error {'uint64x2_t' redeclared} "" {target *-*-*} .-8 } */
/* { dg-error {'float16x8_t' redeclared} "" {target *-*-*} .-9 } */
/* { dg-error {'float32x4_t' redeclared} "" {target *-*-*} .-10 } */
/* { dg-error {'int8x16x2_t' redeclared} "" {target *-*-*} .-11 } */
/* { dg-error {'int8x16x4_t' redeclared} "" {target *-*-*} .-12 } */
/* { dg-error {'int16x8x2_t' redeclared} "" {target *-*-*} .-13 } */
/* { dg-error {'int16x8x4_t' redeclared} "" {target *-*-*} .-14 } */
/* { dg-error {'int32x4x2_t' redeclared} "" {target *-*-*} .-15 } */
/* { dg-error {'int32x4x4_t' redeclared} "" {target *-*-*} .-16 } */
/* { dg-error {'int64x2x2_t' redeclared} "" {target *-*-*} .-17 } */
/* { dg-error {'int64x2x4_t' redeclared} "" {target *-*-*} .-18 } */
/* { dg-error {'uint8x16x2_t' redeclared} "" {target *-*-*} .-19 } */
/* { dg-error {'uint8x16x4_t' redeclared} "" {target *-*-*} .-20 } */
/* { dg-error {'uint16x8x2_t' redeclared} "" {target *-*-*} .-21 } */
/* { dg-error {'uint16x8x4_t' redeclared} "" {target *-*-*} .-22 } */
/* { dg-error {'uint32x4x2_t' redeclared} "" {target *-*-*} .-23 } */
/* { dg-error {'uint32x4x4_t' redeclared} "" {target *-*-*} .-24 } */
/* { dg-error {'uint64x2x2_t' redeclared} "" {target *-*-*} .-25 } */
/* { dg-error {'uint64x2x4_t' redeclared} "" {target *-*-*} .-26 } */
/* { dg-error {'float16x8x2_t' redeclared} "" {target *-*-*} .-27 } */
/* { dg-error {'float16x8x4_t' redeclared} "" {target *-*-*} .-28 } */
/* { dg-error {'float32x4x2_t' redeclared} "" {target *-*-*} .-29 } */
/* { dg-error {'float32x4x4_t' redeclared} "" {target *-*-*} .-30 } */

View file

@ -0,0 +1,8 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* It doesn't really matter if this produces errors about redefinitions,
but it mustn't trigger an ICE. */
#pragma GCC arm "arm_mve_types.h"
#pragma GCC arm "arm_mve_types.h" /* { dg-error "duplicate definition of 'arm_mve_types.h'" } */

View file

@ -0,0 +1,3 @@
/* { dg-options "-mfloat-abi=soft" } */
#pragma GCC arm "arm_mve_types.h" /* { dg-error {this definition requires the MVE ISA extension} } */

View file

@ -44,6 +44,12 @@ dg-init
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/intrinsics/*.\[cCS\]]] \
"" $DEFAULT_CFLAGS
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/general/*.\[cCS\]]] \
"" $DEFAULT_CFLAGS
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/general-c/*.\[cCS\]]] \
"" $DEFAULT_CFLAGS
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
"" $DEFAULT_CFLAGS