Index: c/src/tests/libffi/Makefile.am
===================================================================
--- c/src/tests/libffi/Makefile.am	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/libffi/Makefile.am	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,13 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
+
+SUBDIRS = ffitest
+
+EXTRA_DIST = libffi.am
+
+include $(top_srcdir)/../../../../automake/subdirs.am
+include $(top_srcdir)/../../../../automake/local.am
Index: c/src/tests/libffi/configure.in
===================================================================
--- c/src/tests/libffi/configure.in	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/libffi/configure.in	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,46 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl $Id$
+
+AC_PREREQ(2.13)
+AC_INIT(ffitest)
+RTEMS_TOP(../../../..)
+AC_CONFIG_AUX_DIR(../../../..)
+
+RTEMS_CANONICAL_TARGET_CPU
+
+AM_INIT_AUTOMAKE(rtems-c-src-tests-libffi,$RTEMS_VERSION,no)
+AM_MAINTAINER_MODE
+
+RTEMS_ENABLE_INLINES
+RTEMS_ENABLE_CXX
+RTEMS_ENABLE_GCC28
+RTEMS_ENABLE_BARE
+
+RTEMS_ENV_RTEMSBSP
+RTEMS_CHECK_CPU
+RTEMS_CANONICAL_HOST
+
+RTEMS_PROJECT_ROOT
+
+RTEMS_PROG_CC_FOR_TARGET
+
+if test "$RTEMS_HAS_CPLUSPLUS" = "yes"; then
+  RTEMS_PROG_CXX_FOR_TARGET
+fi
+
+RTEMS_CANONICALIZE_TOOLS
+
+RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
+RTEMS_CHECK_CXX(RTEMS_BSP)
+
+AC_SUBST(BARE_CPU_CFLAGS)
+AC_SUBST(BARE_CPU_MODEL)
+
+AM_CONDITIONAL(HAS_CXX,test "$HAS_CPLUSPLUS" = "yes")
+
+# Explicitly list all Makefiles here
+AC_OUTPUT( 
+Makefile
+ffitest/Makefile
+)
Index: c/src/tests/libffi/ffitest/Makefile.am
===================================================================
--- c/src/tests/libffi/ffitest/Makefile.am	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/libffi/ffitest/Makefile.am	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,43 @@
+##
+##  $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+TEST = ffitest
+
+MANAGERS = io
+
+C_FILES = init.c ffitest.c
+C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
+
+H_FILES = system.h
+noinst_HEADERS = $(H_FILES)
+
+DOCTYPES = scn
+DOCS = $(DOCTYPES:%=$(TEST).%)
+
+SRCS = $(DOCS) $(C_FILES) $(H_FILES)
+OBJS = $(C_O_FILES)
+
+PRINT_SRCS = $(DOCS)
+
+PGM = ${ARCH}/$(TEST).exe
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+include $(top_srcdir)/libffi.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+LD_LIBS += -lffi
+
+${PGM}: $(OBJS) $(LINK_FILES)
+	$(make-exe)
+
+all: ${ARCH} $(TMPINSTALL_FILES)
+
+EXTRA_DIST = $(C_FILES) $(DOCS)
+
+include $(top_srcdir)/../../../../automake/local.am
Index: c/src/tests/libffi/ffitest/ffitest.c
===================================================================
--- c/src/tests/libffi/ffitest/ffitest.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/libffi/ffitest/ffitest.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,735 @@
+/* -----------------------------------------------------------------------
+   ffitest.c - Copyright (c) 1996, 1997, 1998  Cygnus Solutions
+
+   $Id$
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#include <rtems.h>
+#include <rtems/error.h>
+
+/* This is lame. Long double support is barely there under SunOS 4.x  */
+#if defined(SPARC) && (SIZEOF_LONG_DOUBLE != 16)
+#define BROKEN_LONG_DOUBLE
+#endif
+
+#define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0 
+
+static int fail(char *file, int line)
+{
+  fprintf(stderr, "Test failure: %s line %d\n", file, line);
+  exit(EXIT_FAILURE);
+  /*@notreached@*/
+  return 0;
+}
+
+#define MAX_ARGS 256
+
+static size_t my_strlen(char *s)
+{
+  return (strlen(s));
+}
+
+static int promotion(signed char sc, signed short ss, 
+		     unsigned char uc, unsigned short us)
+{
+  int r = (int) sc + (int) ss + (int) uc + (int) us;
+
+  return r;
+}
+
+static signed char return_sc(signed char sc)
+{
+  return sc;
+}
+
+static unsigned char return_uc(unsigned char uc)
+{
+  return uc;
+}
+
+static long long return_ll(long long ll)
+{
+  return ll;
+}
+
+static int floating(int a, float b, double c, long double d, int e)
+{
+  int i;
+
+#if 0
+  /* This is ifdef'd out for now. long double support under SunOS/gcc
+     is pretty much non-existent.  You'll get the odd bus error in library
+     routines like printf().  */
+  printf("%d %f %f %Lf %d\n", a, (double)b, c, d, e);
+#endif
+
+  i = (int) ((float)a/b + ((float)c/(float)d));
+
+  return i;
+}
+
+static float many(float f1,
+		  float f2,
+		  float f3,
+		  float f4,
+		  float f5,
+		  float f6,
+		  float f7,
+		  float f8,
+		  float f9,
+		  float f10,
+		  float f11,
+		  float f12,
+		  float f13)
+{
+#if 0
+  printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
+	 (double) f1, (double) f2, (double) f3, (double) f4, (double) f5, 
+	 (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
+	 (double) f11, (double) f12, (double) f13);
+#endif
+
+  return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+static double dblit(float f)
+{
+  return f/3.0;
+}
+
+static long double ldblit(float f)
+{
+  return (long double) (((long double) f)/ (long double) 3.0);
+}
+
+typedef struct
+{
+  unsigned char uc;
+  double d;
+  unsigned int ui;
+} test_structure_1;
+
+typedef struct
+{
+  double d1;
+  double d2;
+} test_structure_2;
+
+typedef struct
+{
+  int si;
+} test_structure_3;
+
+typedef struct
+{
+  unsigned ui1;
+  unsigned ui2;
+  unsigned ui3;
+} test_structure_4;
+
+typedef struct
+{
+  char c1;
+  char c2;
+} test_structure_5;
+
+static test_structure_1 struct1(test_structure_1 ts)
+{
+  /*@-type@*/
+  ts.uc++;
+  /*@=type@*/
+  ts.d--;
+  ts.ui++;
+
+  return ts;
+}
+
+static test_structure_2 struct2(test_structure_2 ts)
+{
+  ts.d1--;
+  ts.d2--;
+
+  return ts;
+}
+
+static test_structure_3 struct3(test_structure_3 ts)
+{
+  ts.si = -(ts.si*2);
+
+  return ts;
+}
+
+static test_structure_4 struct4(test_structure_4 ts)
+{
+  ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
+
+  return ts;
+}
+
+static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
+{
+  ts1.c1 += ts2.c1;
+  ts1.c2 -= ts2.c2;
+
+  return ts1;
+}
+
+/* Take an int and a float argument, together with int userdata, and 	*/
+/* return the sum.							*/
+static void closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
+{
+    *(int*)resp =
+	 *(int *)args[0] + (int)(*(float *)args[1]) + (int)(long)userdata;
+}
+
+typedef int (*closure_test_type)(int, float);
+
+int ffi_main( void )
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  char *s;
+  signed char sc;
+  unsigned char uc;
+  signed short ss;
+  unsigned short us;
+  unsigned long ul;
+  long long ll;
+  float f;
+  double d;
+  long double ld;
+  signed int si1;
+  signed int si2;
+
+#if defined(ALPHA) || defined(IA64) || defined(SPARC64) || (defined(MIPS) && (_MIPS_SIM == _ABIN32))
+  long long rint;
+#else
+  int rint;
+#endif
+  long long rlonglong;
+
+  ffi_type ts1_type;
+  ffi_type ts2_type;
+  ffi_type ts3_type;
+  ffi_type ts4_type;  
+  ffi_type ts5_type;
+  ffi_type *ts1_type_elements[4];
+  ffi_type *ts2_type_elements[3];
+  ffi_type *ts3_type_elements[2];
+  ffi_type *ts4_type_elements[4];
+  ffi_type *ts5_type_elements[3];
+
+  ts1_type.size = 0;
+  ts1_type.alignment = 0;
+  ts1_type.type = FFI_TYPE_STRUCT;
+
+  ts2_type.size = 0;
+  ts2_type.alignment = 0;
+  ts2_type.type = FFI_TYPE_STRUCT;
+
+  ts3_type.size = 0;
+  ts3_type.alignment = 0;
+  ts3_type.type = FFI_TYPE_STRUCT;
+
+  ts4_type.size = 0;
+  ts4_type.alignment = 0;
+  ts4_type.type = FFI_TYPE_STRUCT;
+
+  ts5_type.size = 0;
+  ts5_type.alignment = 0;
+  ts5_type.type = FFI_TYPE_STRUCT;
+
+  /*@-immediatetrans@*/
+  ts1_type.elements = ts1_type_elements;
+  ts2_type.elements = ts2_type_elements;
+  ts3_type.elements = ts3_type_elements;
+  ts4_type.elements = ts4_type_elements;
+  ts5_type.elements = ts5_type_elements;
+  /*@=immediatetrans@*/
+  
+  ts1_type_elements[0] = &ffi_type_uchar;
+  ts1_type_elements[1] = &ffi_type_double;
+  ts1_type_elements[2] = &ffi_type_uint;
+  ts1_type_elements[3] = NULL;
+  
+  ts2_type_elements[0] = &ffi_type_double;
+  ts2_type_elements[1] = &ffi_type_double;
+  ts2_type_elements[2] = NULL;
+
+  ts3_type_elements[0] = &ffi_type_sint;
+  ts3_type_elements[1] = NULL;
+
+  ts4_type_elements[0] = &ffi_type_uint;
+  ts4_type_elements[1] = &ffi_type_uint;
+  ts4_type_elements[2] = &ffi_type_uint;
+  ts4_type_elements[3] = NULL;
+
+  ts5_type_elements[0] = &ffi_type_schar;
+  ts5_type_elements[1] = &ffi_type_schar;
+  ts5_type_elements[2] = NULL;
+
+  ul = 0;
+
+  /* return value tests */
+  {
+#if defined(MIPS) /* || defined(ARM) */
+    puts ("long long tests not run. This is a known bug on this architecture.");
+#else
+    args[0] = &ffi_type_sint64;
+    values[0] = &ll;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ffi_type_sint64, args) == FFI_OK);
+
+    for (ll = 0LL; ll < 100LL; ll++)
+      {
+	ul++;
+	ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+	CHECK(rlonglong == ll);
+      }
+
+    for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
+      {
+	ul++;
+	ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+	CHECK(rlonglong == ll);
+      }
+#endif
+
+    args[0] = &ffi_type_schar;
+    values[0] = &sc;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ffi_type_schar, args) == FFI_OK);
+
+    for (sc = (signed char) -127; 
+	 sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
+      {
+	ul++;
+	ffi_call(&cif, FFI_FN(return_sc), &rint, values);
+	CHECK(rint == (int) sc);
+      }
+
+    args[0] = &ffi_type_uchar;
+    values[0] = &uc;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ffi_type_uchar, args) == FFI_OK);
+
+    for (uc = (unsigned char) '\x00'; 
+	 uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
+      {
+	ul++;
+	ffi_call(&cif, FFI_FN(return_uc), &rint, values);
+	CHECK(rint == (signed int) uc);
+      }
+
+    printf("%lu return value tests run\n", ul);
+  }
+
+#ifdef BROKEN_LONG_DOUBLE
+  printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
+#else
+  /* float arg tests */
+  {
+    args[0] = &ffi_type_float;
+    values[0] = &f;
+
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ffi_type_longdouble, args) == FFI_OK);
+
+    f = 3.14159;
+
+#if 0
+  /* This is ifdef'd out for now. long double support under SunOS/gcc
+     is pretty much non-existent.  You'll get the odd bus error in library
+     routines like printf().  */
+    printf ("%Lf\n", ldblit(f));
+#endif
+    ld = 666;
+    ffi_call(&cif, FFI_FN(ldblit), &ld, values);
+
+#if 0
+  /* This is ifdef'd out for now. long double support under SunOS/gcc
+     is pretty much non-existent.  You'll get the odd bus error in library
+     routines like printf().  */
+    printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
+#endif
+
+    /* These are not always the same!! Check for a reasonable delta */
+    /*@-realcompare@*/
+    if (ld - ldblit(f) < LDBL_EPSILON)
+    /*@=realcompare@*/
+	puts("long double return value tests ok!");
+    else
+        CHECK(0);
+  }
+
+  /* float arg tests */
+  {
+    args[0] = &ffi_type_sint;
+    values[0] = &si1;
+    args[1] = &ffi_type_float;
+    values[1] = &f;
+    args[2] = &ffi_type_double;
+    values[2] = &d;
+    args[3] = &ffi_type_longdouble;
+    values[3] = &ld;
+    args[4] = &ffi_type_sint;
+    values[4] = &si2;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
+		       &ffi_type_sint, args) == FFI_OK);
+
+    si1 = 6;
+    f = 3.14159;
+    d = (double)1.0/(double)3.0;
+    ld = 2.71828182846L;
+    si2 = 10;
+
+    floating (si1, f, d, ld, si2);
+
+    ffi_call(&cif, FFI_FN(floating), &rint, values);
+
+    printf ("%d vs %d\n", rint, floating (si1, f, d, ld, si2));
+
+    CHECK(rint == floating(si1, f, d, ld, si2));
+
+    printf("float arg tests ok!\n");
+  }
+#endif
+
+  /* strlen tests */
+  {
+    args[0] = &ffi_type_pointer;
+    values[0] = (void*) &s;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ffi_type_sint, args) == FFI_OK);
+
+    s = "a";
+    ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+    CHECK(rint == 1);
+
+    s = "1234567";
+    ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+    CHECK(rint == 7);
+
+    s = "1234567890123456789012345";
+    ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+    CHECK(rint == 25);
+
+    printf("strlen tests passed\n");
+  }
+
+  /* float arg tests */
+  {
+    args[0] = &ffi_type_float;
+    values[0] = &f;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ffi_type_double, args) == FFI_OK);
+
+    f = 3.14159;
+
+    ffi_call(&cif, FFI_FN(dblit), &d, values);
+
+    /* These are not always the same!! Check for a reasonable delta */
+    /*@-realcompare@*/
+    CHECK(d - dblit(f) < DBL_EPSILON);
+    /*@=realcompare@*/
+
+    printf("double return value tests ok!\n");
+  }
+
+  /* many arg tests */
+  {
+    float ff;
+    float fa[13];
+    
+    for (ul = 0; ul < 13; ul++)
+      {
+	args[ul] = &ffi_type_float;
+	values[ul] = &fa[ul];
+	fa[ul] = (float) ul;
+      }
+
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, 
+		       &ffi_type_float, args) == FFI_OK);
+
+    /*@-usedef@*/
+    ff =  many(fa[0], fa[1],
+	       fa[2], fa[3],
+	       fa[4], fa[5],
+	       fa[6], fa[7],
+	       fa[8], fa[9],
+	       fa[10],fa[11],fa[12]);
+    /*@=usedef@*/
+
+    ffi_call(&cif, FFI_FN(many), &f, values);
+
+    /*@-realcompare@*/
+    if (f - ff < FLT_EPSILON)
+    /*@=realcompare@*/
+	printf("many arg tests ok!\n");
+    else
+#ifdef POWERPC
+	printf("many arg tests failed!  This is a gcc bug.\n");
+#else
+        CHECK(0);
+#endif
+  }
+
+  /* promotion tests */
+  {
+    args[0] = &ffi_type_schar;
+    args[1] = &ffi_type_sshort;
+    args[2] = &ffi_type_uchar;
+    args[3] = &ffi_type_ushort;
+    values[0] = &sc;
+    values[1] = &ss;
+    values[2] = &uc;
+    values[3] = &us;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 
+		       &ffi_type_sint, args) == FFI_OK);
+
+    us = 0;
+    ul = 0;
+
+    for (sc = (signed char) -127; 
+	 sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/)
+      for (ss = -30000; ss <= 30000; ss += 10000)
+	for (uc = (unsigned char) 0; 
+	     uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/)
+	  for (us = 0; us <= 60000; us += 10000)
+	    {
+	      ul++;
+	      ffi_call(&cif, FFI_FN(promotion), &rint, values);
+	      CHECK(rint == (int) sc + (int) ss + (int) uc + (int) us);
+	    }
+    printf("%lu promotion tests run\n", ul);
+  }
+
+  /* struct tests */
+  {
+    test_structure_1 ts1_arg;
+    /* This is a hack to get a properly aligned result buffer */
+    test_structure_1 *ts1_result = 
+      (test_structure_1 *) malloc (sizeof(test_structure_1));
+		if (! ts1_result )
+			rtems_panic("Could not get memory for struct 1 result.");
+    args[0] = &ts1_type;
+    values[0] = &ts1_arg;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ts1_type, args) == FFI_OK);
+
+    ts1_arg.uc = '\x01';
+    ts1_arg.d = 3.14159;
+    ts1_arg.ui = 555;
+
+    ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
+
+    CHECK(ts1_result->ui == 556);
+    CHECK(ts1_result->d == 3.14159 - 1);
+
+    puts ("structure test 1 ok!\n");
+
+    free (ts1_result);
+  }
+
+  /* struct tests */
+  {
+    test_structure_2 ts2_arg;
+
+    /* This is a hack to get a properly aligned result buffer */
+    test_structure_2 *ts2_result = 
+      (test_structure_2 *) malloc (sizeof(test_structure_2));
+
+    args[0] = &ts2_type;
+    values[0] = &ts2_arg;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ts2_type, args) == FFI_OK);
+
+    ts2_arg.d1 = 5.55;
+    ts2_arg.d2 = 6.66;
+
+    printf ("%g\n", ts2_result->d1);
+    printf ("%g\n", ts2_result->d2);
+
+    ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
+
+    printf ("%g\n", ts2_result->d1);
+    printf ("%g\n", ts2_result->d2);
+    
+    CHECK(ts2_result->d1 == 5.55 - 1);
+    CHECK(ts2_result->d2 == 6.66 - 1);
+
+    printf("structure test 2 ok!\n");
+
+    free (ts2_result);
+  }
+
+  /* struct tests */
+  {
+    int compare_value;
+    test_structure_3 ts3_arg;
+    test_structure_3 *ts3_result = 
+      (test_structure_3 *) malloc (sizeof(test_structure_3));
+
+    args[0] = &ts3_type;
+    values[0] = &ts3_arg;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ts3_type, args) == FFI_OK);
+
+    ts3_arg.si = -123;
+    compare_value = ts3_arg.si;
+
+    ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
+
+    printf ("%d %d\n", ts3_result->si, -(compare_value*2));
+
+    if (ts3_result->si == -(ts3_arg.si*2))
+	puts ("structure test 3 ok!");
+    else
+      {
+	puts ("Structure test 3 found structure passing bug.");
+	puts ("  Current versions of GCC are not 100% compliant with the");
+	puts ("  n32 ABI.  There is a known problem related to passing");
+	puts ("  small structures.  Send a bug report to the gcc maintainers.");
+      }
+
+    free (ts3_result);
+  }
+
+  /* struct tests */
+  {
+    test_structure_4 ts4_arg;
+
+    /* This is a hack to get a properly aligned result buffer */
+    test_structure_4 *ts4_result = 
+      (test_structure_4 *) malloc (sizeof(test_structure_4));
+
+    args[0] = &ts4_type;
+    values[0] = &ts4_arg;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ts4_type, args) == FFI_OK);
+
+    ts4_arg.ui1 = 2;
+    ts4_arg.ui2 = 3;
+    ts4_arg.ui3 = 4;
+
+    ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
+    
+    if (ts4_result->ui3 == 2U * 3U * 4U)
+      puts ("structure test 4 ok!");
+    else
+      puts ("Structure test 4 found GCC's structure passing bug.");
+
+    free (ts4_result);
+  }
+
+  /* struct tests */
+  {
+    test_structure_5 ts5_arg1, ts5_arg2;
+
+    /* This is a hack to get a properly aligned result buffer */
+    test_structure_5 *ts5_result = 
+      (test_structure_5 *) malloc (sizeof(test_structure_5));
+
+    args[0] = &ts5_type;
+    args[1] = &ts5_type;
+    values[0] = &ts5_arg1;
+    values[1] = &ts5_arg2;
+    
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 
+		       &ts5_type, args) == FFI_OK);
+
+    ts5_arg1.c1 = 2;
+    ts5_arg1.c2 = 6;
+    ts5_arg2.c1 = 5;
+    ts5_arg2.c2 = 3;
+
+    ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
+    
+    if (ts5_result->c1 == 7 
+	&& ts5_result->c2 == 3)
+      puts ("structure test 5 ok!");
+    else
+      puts ("Structure test 5 found GCC's structure passing bug.");
+
+    free (ts5_result);
+  }
+
+# if FFI_CLOSURES
+  /* A simple closure test */
+    {
+      ffi_closure cl;
+      ffi_type * cl_arg_types[3];
+
+      cl_arg_types[0] = &ffi_type_sint;
+      cl_arg_types[1] = &ffi_type_float;
+      cl_arg_types[2] = NULL;
+      
+      /* Initialize the cif */
+      CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 
+	    	         &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+      CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
+			     (void *) 3 /* userdata */)
+	    == FFI_OK);
+      CHECK((*((closure_test_type)(&cl)))(1, 2.0) == 6);
+    }
+# endif
+
+  /* If we arrived here, all is good */
+  (void) puts("\nLooks good. No surprises.\n");
+
+  /*@-compdestroy@*/
+
+  return 0;
+}
+
Index: c/src/tests/libffi/ffitest/init.c
===================================================================
--- c/src/tests/libffi/ffitest/init.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/libffi/ffitest/init.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,35 @@
+/*  Init
+ *
+ *  This routine is the initialization task for this test program.
+ *  It is called from init_exec and has the responsibility for creating
+ *  and starting the tasks that make up the test.  If the time of day
+ *  clock is required for the test, it should also be set to a known
+ *  value by this function.
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters:  NONE
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ */
+
+#define TEST_INIT
+#include "system.h"
+
+extern int ffi_main ( void );
+
+rtems_task Init(
+  rtems_task_argument ignored
+)
+{
+  printf( "\n\n*** LIBFFI TEST ***\n" );
+  ffi_main();
+  printf( "*** END OF LIBFFI TEST ***\n" );
+  exit( 0 );
+}
Index: c/src/tests/libffi/ffitest/system.h
===================================================================
--- c/src/tests/libffi/ffitest/system.h	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/libffi/ffitest/system.h	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,36 @@
+/*  system.h
+ *
+ *  This include file contains information that is included in every
+ *  function in the test set.
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  $Id$
+ */
+
+#include <tmacros.h>
+
+/* functions */
+
+rtems_task Init(
+  rtems_task_argument argument
+);
+
+/* configuration information */
+
+#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+
+#include <confdefs.h>
+
+/* global variables */
+
+TEST_EXTERN rtems_id Global_variable;   /* example global variable     */
+
+/* end of include file */
Index: c/src/tests/libffi/libffi.am
===================================================================
--- c/src/tests/libffi/libffi.am	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/libffi/libffi.am	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,11 @@
+project_bspdir=$(PROJECT_ROOT)/@RTEMS_BSP@
+
+$(project_bspdir)/tests:
+	@$(mkinstalldirs) $@
+
+$(project_bspdir)/tests/$(TEST)$(LIB_VARIANT).exe: $(PGM)
+	$(INSTALL_PROGRAM) $< $@
+
+TMPINSTALL_FILES += \
+$(project_bspdir)/tests \
+$(project_bspdir)/tests/$(TEST)$(LIB_VARIANT).exe
Index: c/src/tests/sptests/threaditerate/Makefile.am
===================================================================
--- c/src/tests/sptests/threaditerate/Makefile.am	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/sptests/threaditerate/Makefile.am	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,43 @@
+## 
+## $Id$
+## 
+
+AUTOMAKE_OPTIONS = foreign 1.4
+TEST = threaditerate
+
+MANAGERS = all
+
+C_FILES = init.c threadinfo.c rtemstask.c pthread.c itron_task.c
+C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
+
+H_FILES = system.h
+noinst_HEADERS =$(H_FILES)
+
+DOCTYPES = scn doc
+DOCS = $(DOCTYPES:%=$(TEST).%)
+
+SRCS = $(C_FILES) $(H_FILES)
+OBJS = $(C_O_FILES)
+
+PRINT_SRCS = $(DOCS)
+
+PGM = ${ARCH}/$(TEST).exe
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+include $(top_srcdir)/sptests.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+AM_CPPFLAGS = -I$(top_srcdir)/../psxtests/include
+
+${PGM}: $(OBJS) $(LINK_FILES)
+	$(make-exe)
+
+all: $(ARCH) $(TMPINSTALL_FILES)
+
+EXTRA_DIST = $(C_FILES) $(DOCS)
+
+include $(top_srcdir)/../../../../automake/local.am
Index: c/src/tests/sptests/threaditerate/init.c
===================================================================
--- c/src/tests/sptests/threaditerate/init.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/sptests/threaditerate/init.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,202 @@
+/*  Init
+ *
+ *  This routine is the initialization task for this test program.
+ *  It is a user initialization task and has the responsibility for creating
+ *  and starting the tasks that make up the test.  If the time of day
+ *  clock is required for the test, it should also be set to a known
+ *  value by this function.
+ *
+ *  Input parameters:
+ *    argument - task argument
+ *
+ *  Output parameters:  NONE
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  $Id$
+ */
+
+#define TEST_INIT
+#include "system.h"
+
+rtems_task Init(
+  rtems_task_argument argument
+)
+{
+  rtems_time_of_day time;
+  rtems_status_code rtems_status;
+
+#ifdef RTEMS_POSIX_API
+  int posix_status;
+#endif
+
+#ifdef RTEMS_ITRON_API
+  ER itron_status;
+  T_CTSK pk_ctsk;
+#endif
+
+  puts( "\n\n*** Thread Iteration Test ***" );
+
+  build_time( &time, 12, 31, 2000, 9, 0, 0, 0 );
+  rtems_status = rtems_clock_set( &time );
+  directive_failed( rtems_status, "rtems_clock_set" );
+
+  Task_name[ 1 ] = rtems_build_name( 'T', 'A', '1', ' ' );
+  Task_name[ 2 ] = rtems_build_name( 'T', 'A', '2', ' ' );
+  Task_name[ 3 ] = rtems_build_name( 'T', 'A', '3', ' ' );
+
+  rtems_status = rtems_task_create(
+     Task_name[ 1 ],
+     1,
+     RTEMS_MINIMUM_STACK_SIZE * 2,
+     RTEMS_INTERRUPT_LEVEL(31),
+     RTEMS_DEFAULT_ATTRIBUTES,
+     &Task_id[ 1 ]
+  );
+  directive_failed( rtems_status, "rtems_task_create of TA1" );
+
+  rtems_status = rtems_task_create(
+     Task_name[ 2 ],
+     1,
+     RTEMS_MINIMUM_STACK_SIZE * 2,
+     RTEMS_DEFAULT_MODES,
+     RTEMS_DEFAULT_ATTRIBUTES,
+     &Task_id[ 2 ]
+  );
+  directive_failed( rtems_status, "rtems_task_create of TA2" );
+
+  rtems_status = rtems_task_create(
+     Task_name[ 3 ],
+     1,
+     RTEMS_MINIMUM_STACK_SIZE * 3,
+     RTEMS_DEFAULT_MODES,
+     RTEMS_DEFAULT_ATTRIBUTES,
+     &Task_id[ 3 ]
+  );
+  directive_failed( rtems_status, "rtems_task_create of TA3" );
+
+  rtems_status = rtems_task_start( Task_id[ 1 ], RTEMS_task_1_through_3, 0 );
+  if ( rtems_status == RTEMS_SUCCESSFUL )
+    printf("Created and started an RTEMS task with id = 0x%08x\n", Task_id[1] );
+  else
+    directive_failed( rtems_status, "rtems_task_start of TA1" );
+
+  rtems_status = rtems_task_start( Task_id[ 2 ], RTEMS_task_1_through_3, 0 );
+  if ( rtems_status == RTEMS_SUCCESSFUL )
+    printf("Created and started an RTEMS task with id = 0x%08x\n", Task_id[2] );
+  else
+    directive_failed( rtems_status, "rtems_task_start of TA2" );
+
+  rtems_status = rtems_task_start( Task_id[ 3 ], RTEMS_task_1_through_3, 0 );
+  if ( rtems_status == RTEMS_SUCCESSFUL )
+    printf("Created and started an RTEMS task with id = 0x%08x\n", Task_id[3] );
+  else
+    directive_failed( rtems_status, "rtems_task_start of TA3" );
+
+#ifdef RTEMS_POSIX_API
+  posix_status = pthread_create( &pthread_id[0], NULL, pthread_1_through_3, NULL );
+  if ( !posix_status )
+    printf("Created and started a pthread with id = 0x%08x\n", pthread_id[0] );
+  else
+    assert( !posix_status );
+
+  posix_status = pthread_create( &pthread_id[1], NULL, pthread_1_through_3, NULL );
+  if ( !posix_status )
+    printf("Created and started a pthread with id = 0x%08x\n", pthread_id[1] );
+  else
+    assert( !posix_status );
+
+  posix_status = pthread_create( &pthread_id[2], NULL, pthread_1_through_3, NULL );
+  if ( !posix_status )
+    printf("Created and started a pthread with id = 0x%08x\n", pthread_id[2] );
+  else
+    assert( !posix_status );
+
+#endif
+
+#ifdef RTEMS_ITRON_API
+
+#define ITRON_GET_TASK_ID(_index) \
+  _ITRON_Task_Information.local_table[_index]->id
+
+  pk_ctsk.exinf    = NULL;
+  pk_ctsk.tskatr   = TA_HLNG;
+  pk_ctsk.itskpri  = 1; 
+  pk_ctsk.task     = ITRON_task_2_through_4;
+  pk_ctsk.stksz    = RTEMS_MINIMUM_STACK_SIZE * 2;
+  
+  itron_status = cre_tsk( 2, &pk_ctsk );
+  directive_failed( itron_status, "cre_tsk of task" );
+
+  pk_ctsk.stksz = RTEMS_MINIMUM_STACK_SIZE * 2;
+  itron_status = cre_tsk( 3, &pk_ctsk );
+  directive_failed( itron_status, "cre_tsk of TA2" );
+
+  pk_ctsk.stksz = RTEMS_MINIMUM_STACK_SIZE * 3; 
+  itron_status = cre_tsk( 4, &pk_ctsk );
+  directive_failed( itron_status, "cre_tsk of TA3" );
+
+  itron_status  = sta_tsk( 2, 0 );
+  if ( !itron_status )
+    printf("Created and started an ITRON task with id = 0x%08x\n", ITRON_GET_TASK_ID( 2 ) );
+  else
+    directive_failed( itron_status, "sta_tsk of ITRON task 2" );
+
+  itron_status  = sta_tsk( 3, 0 );
+  if ( !itron_status )
+    printf("Created and started an ITRON task with id = 0x%08x\n", ITRON_GET_TASK_ID( 3 ) );
+  else
+    directive_failed( itron_status, "sta_tsk of ITRON task 3" );
+
+  itron_status  = sta_tsk( 4, 0 );
+  if ( !itron_status )
+    printf("Created and started an ITRON task with id = 0x%08x\n", ITRON_GET_TASK_ID( 4 ) );
+  else
+    directive_failed( itron_status, "sta_tsk of ITRON task 4" );
+#endif
+
+  printf( "Sleeping for 5 seconds\n" );
+  fflush( stdout );
+
+  rtems_status = rtems_task_wake_after( 5 * TICKS_PER_SECOND );
+  directive_failed( rtems_status, "rtems_task_wake_after" );
+
+  printf( "\nLooking for all threads\n\n" );
+  _Thread_Local_iterate( print_thread_info, NULL, FALSE );
+
+  printf( "That was it. Sleeping for 20 seconds.\n" );
+  
+  rtems_status = rtems_task_wake_after( 20 * TICKS_PER_SECOND );
+  directive_failed( rtems_status, "rtems_task_wake_after" );
+
+  /* If we get here, all threads were created */
+  printf( "\nDeleting the second thread of each type\n\n" );
+
+  rtems_status = rtems_task_suspend( Task_id[2] );
+  directive_failed( rtems_status, "rtems_task_suspend" );
+  rtems_status = rtems_task_delete( Task_id[2] );
+  directive_failed( rtems_status, "rtems_task_delete" );
+
+#ifdef RTEMS_POSIX_API
+  posix_status = pthread_cancel( pthread_id[2] );
+  assert( !posix_status );
+#endif
+
+#ifdef RTEMS_ITRON_API
+  itron_status = ter_tsk( 3 );
+   directive_failed( itron_status, "ter_tsk of ITRON task 3" );
+#endif
+
+  printf( "\nLooking for all threads\n\n" );
+  _Thread_Local_iterate( print_thread_info, NULL, FALSE );
+
+  printf( "That was it. Exiting\n" );
+  fflush( stdout );
+  
+  exit( 0 );
+}
Index: c/src/tests/sptests/threaditerate/itrontask.c
===================================================================
--- c/src/tests/sptests/threaditerate/itrontask.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/sptests/threaditerate/itrontask.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,52 @@
+/*  Task_1_through_3
+ *
+ *  This routine serves as a test task.  It verifies the basic task
+ *  switching capabilities of the executive.
+ *
+ *  Input parameters:
+ *    argument - task argument
+ *
+ *  Output parameters:  NONE
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  $Id$
+ */
+
+#include "system.h"
+
+void ITRON_task_2_through_4( void )
+{
+  ID                tid;
+  int               tid_index;
+  rtems_time_of_day time;
+  ER                status;
+  char              name[30];
+
+  status = get_tid( &tid );
+  directive_failed( status, "get_tid");
+
+  tid_index = tid - 1;  /* account for init tasks */
+  
+  status = rtems_task_wake_after( 10 * TICKS_PER_SECOND );
+  directive_failed( status, "rtems_task_wake_after" );
+
+  sprintf(name, "ITRON task %d", tid_index);
+
+  while( FOREVER ) {
+    status = rtems_clock_get( RTEMS_CLOCK_GET_TOD, &time );
+    directive_failed( status, "rtems_clock_get" );
+
+    printf(name);
+    print_time( " - rtems_clock_get - ", &time, "\n" );
+
+    status = rtems_task_wake_after( 30 * TICKS_PER_SECOND );
+    directive_failed( status, "rtems_task_wake_after" );
+  }
+}
+
Index: c/src/tests/sptests/threaditerate/pthread.c
===================================================================
--- c/src/tests/sptests/threaditerate/pthread.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/sptests/threaditerate/pthread.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,46 @@
+/*  pthread_1_through_3
+ *
+ *  This routine serves as a test task.  It verifies the basic task
+ *  switching capabilities of the executive.
+ *
+ *  Input parameters:
+ *    argument - task argument
+ *
+ *  Output parameters:  NONE
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  $Id$
+ */
+
+#include "system.h"
+#include <sys/utsname.h>
+
+void * pthread_1_through_3( void *argument )
+{
+  int status;
+  struct timespec tv;
+  struct timespec tr;
+  time_t remaining;
+
+  remaining = sleep( 10 );
+  assert( !remaining );
+    
+  while( FOREVER ) {
+    status = clock_gettime( CLOCK_REALTIME, &tv );
+    posix_service_failed( status, "clock_gettime" );
+    
+    printf( "pthread: ID is 0x%08x\n", pthread_self() );
+    printf( " - clock_gettime - %s\n", ctime( &tv.tv_sec ) );
+
+    remaining = sleep( 30 );
+    assert( !remaining );
+  }
+  
+  return NULL; /* just so the compiler thinks we returned something */
+}
Index: c/src/tests/sptests/threaditerate/rtemstask.c
===================================================================
--- c/src/tests/sptests/threaditerate/rtemstask.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/sptests/threaditerate/rtemstask.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,47 @@
+/*  Task_1_through_3
+ *
+ *  This routine serves as a test task.  It verifies the basic task
+ *  switching capabilities of the executive.
+ *
+ *  Input parameters:
+ *    argument - task argument
+ *
+ *  Output parameters:  NONE
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  $Id$
+ */
+
+#include "system.h"
+
+rtems_task RTEMS_task_1_through_3(
+  rtems_task_argument argument
+)
+{
+  rtems_id          tid;
+  rtems_time_of_day time;
+  rtems_status_code status;
+
+  status = rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &tid );
+  directive_failed( status, "rtems_task_ident" );
+
+  status = rtems_task_wake_after( 10 * TICKS_PER_SECOND );
+  directive_failed( status, "rtems_task_wake_after" );
+  
+  while( FOREVER ) {
+    status = rtems_clock_get( RTEMS_CLOCK_GET_TOD, &time );
+    directive_failed( status, "rtems_clock_get" );
+
+    put_name( Task_name[ task_number( tid ) ], FALSE );
+    print_time( " - rtems_clock_get - ", &time, "\n" );
+
+    status = rtems_task_wake_after( 30 * TICKS_PER_SECOND );
+    directive_failed( status, "rtems_task_wake_after" );
+  }
+}
Index: c/src/tests/sptests/threaditerate/system.h
===================================================================
--- c/src/tests/sptests/threaditerate/system.h	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/sptests/threaditerate/system.h	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,98 @@
+/*  system.h
+ *
+ *  This include file contains information that is included in every
+ *  function in the test set.
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  $Id$
+ */
+
+/* RTEMS API */
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+
+unsigned32 print_thread_info( Thread_Control *thread, void * arg );
+
+#include <tmacros.h>
+
+/* functions */
+
+rtems_task Init( rtems_task_argument argument );
+rtems_task RTEMS_task_1_through_3( rtems_task_argument argument );
+
+/* global variables */
+
+TEST_EXTERN rtems_id   Task_id[ 4 ];         /* array of task ids */
+TEST_EXTERN rtems_name Task_name[ 4 ];       /* array of task names */
+
+/* configuration information */
+
+#define CONFIGURE_SPTEST
+
+#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_EXTRA_TASK_STACKS         (4 * RTEMS_MINIMUM_STACK_SIZE)
+
+
+
+/* POSIX API */
+
+#ifdef RTEMS_POSIX_API
+
+#include <pmacros.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sched.h>
+
+/* functions */
+
+void *pthread_1_through_3( void *argument );
+
+/* global variables */
+
+TEST_EXTERN pthread_t pthread_id[3];        /* array of pthread ids */
+
+/* configuration information */
+
+#define CONFIGURE_MAXIMUM_POSIX_THREADS     3
+
+#endif
+
+
+
+/* ITRON API */
+
+#ifdef RTEMS_ITRON_API
+
+#include <itron.h>
+#include <rtems/itron/task.h>
+
+/* functions */
+
+void ITRON_task_2_through_4( void );
+
+/* global variables */
+
+TEST_EXTERN Objects_Locations location;
+
+
+/* configuration information */
+
+#endif
+
+#include <confdefs.h>
+
+/* end of include file */
Index: c/src/tests/sptests/threaditerate/threadinfo.c
===================================================================
--- c/src/tests/sptests/threaditerate/threadinfo.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/sptests/threaditerate/threadinfo.c	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,178 @@
+/*  threadinfo.c
+ *  
+ *  Routines to print out information about threads.
+ */
+
+#include "system.h"
+#include <stdlib.h>
+
+#define PTR unsigned int
+#define PTR_MASK "0x%08x"
+
+/*
+ *  Return a pointer to a string describing the object type.
+ */
+
+const char * _Objects_Type_to_String( Objects_Control * object )
+{
+  switch( _Objects_Get_class( object->id ) ) {
+    case OBJECTS_NO_CLASS:
+      return "NO_CLASS";
+      
+    case OBJECTS_INTERNAL_THREADS:
+      return "INTERNAL_THREADS";
+      
+    case OBJECTS_RTEMS_TASKS:
+      return "RTEMS_TASKS";
+      
+    case OBJECTS_POSIX_THREADS:
+      return "POSIX_THREADS";
+      
+    case OBJECTS_ITRON_TASKS:
+      return "ITRON_TASKS";
+      
+    case OBJECTS_RTEMS_TIMERS:
+      return "RTEMS_TIMERS";
+      
+    case OBJECTS_RTEMS_SEMAPHORES:
+      return "RTEMS_SEMAPHORES";
+      
+    case OBJECTS_RTEMS_MESSAGE_QUEUES:
+      return "RTEMS_MESSAGE_QUEUES";
+      
+    case OBJECTS_RTEMS_PARTITIONS:
+      return "RTEMS_PARTITIONS";
+      
+    case OBJECTS_RTEMS_REGIONS:
+      return "RTEMS_REGIONS";
+      
+    case OBJECTS_RTEMS_PORTS:
+      return "RTEMS_PORTS";
+      
+    case OBJECTS_RTEMS_PERIODS:
+      return "RTEMS_PERIODS";
+      
+    case OBJECTS_RTEMS_EXTENSIONS:
+      return "RTEMS_EXTENSIONS";
+      
+    case OBJECTS_POSIX_KEYS:
+      return "POSIX_KEYS";
+      
+    case OBJECTS_POSIX_INTERRUPTS:
+      return "POSIX_INTERRUPTS";
+      
+    case OBJECTS_POSIX_MESSAGE_QUEUES:
+      return "POSIX_MESSAGE_QUEUES";
+      
+    case OBJECTS_POSIX_MUTEXES:
+      return "POSIX_MUTEXES";
+      
+    case OBJECTS_POSIX_SEMAPHORES:
+      return "POSIX_SEMAPHORES";
+      
+    case OBJECTS_POSIX_CONDITION_VARIABLES:
+      return "POSIX_CONDITION_VARIABLES";
+      
+    case OBJECTS_ITRON_EVENTFLAGS:
+      return "ITRON_EVENTFLAGS";
+      
+    case OBJECTS_ITRON_MAILBOXES:
+      return "ITRON_MAILBOXES";
+      
+    case OBJECTS_ITRON_MESSAGE_BUFFERS:    
+       return "ITRON_MESSAGE_BUFFERS";
+       
+    case OBJECTS_ITRON_PORTS:
+      return "ITRON_PORTS";
+      
+    case OBJECTS_ITRON_SEMAPHORES:
+      return "ITRON_SEMAPHORES";
+      
+    case OBJECTS_ITRON_VARIABLE_MEMORY_POOLS:
+      return "ITRON_VARIABLE_MEMORY_POOLS";
+      
+    case OBJECTS_ITRON_FIXED_MEMORY_POOLS:
+      return "ITRON_FIXED_MEMORY_POOLS";
+      
+    default:
+      return "UNKNOWN";
+  }
+}
+
+
+/*
+ *  Return a pointer to a string describing the thread state
+ */
+
+const char * _Thread_State_to_String( States_Control state )
+{
+  States_Control orig_state = state;
+  int i;
+  int first_entry = TRUE;
+  static char buffer[256];
+  static const char *desc[] = {
+    "READY",                          /* 0 - 0x00000 */
+    "DORMANT",                        /* 1 - 0x00001 */
+    "SUSPENDED",                      /* 2 - 0x00002 */
+    "TRANSIENT",                      /* 3 - 0x00004 */
+    "DELAYING",                       /* 4 - 0x00008 */
+    "WAITING_FOR_TIME",               /* 5 - 0x00010 */
+    "WAITING_FOR_BUFFER",             /* 6 - 0x00020 */
+    "WAITING_FOR_SEGMENT",            /* 7 - 0x00040 */
+    "WAITING_FOR_MESSAGE",            /* 8 - 0x00080 */
+    "WAITING_FOR_EVENT",              /* 9 - 0x00100 */
+    "WAITING_FOR_SEMAPHORE",          /* 10 - 0x00200 */
+    "WAITING_FOR_MUTEX",              /* 11 - 0x00400 */
+    "WAITING_FOR_CONDITION_VARIABLE", /* 12 - 0x00800 */
+    "WAITING_FOR_JOIN_AT_EXIT",       /* 13 - 0x01000 */
+    "WAITING_FOR_RPC_REPLY",          /* 14 - 0x02000 */
+    "WAITING_FOR_PERIOD",             /* 15 - 0x04000 */
+    "WAITING_FOR_SIGNAL",             /* 16 - 0x08000 */
+    "INTERRUPTIBLE_BY_SIGNAL",        /* 17 - 0x10000 */
+    "UNKNOWN"                         /* 18 - all higher bits */
+  };
+
+  if( state == STATES_READY )
+    return desc[0];
+    
+  memset( buffer, '\0', sizeof( buffer ) );
+  for ( i = 1; i < 18; i++ ) {
+    if ( state & 0x1 ) {
+      if ( !first_entry ) {
+        strcat ( buffer, " | " );
+      }
+      strcat ( buffer, desc[i] );
+      first_entry = FALSE;
+    }
+    state = state >> 1;
+  }
+
+  if ( state != 0 ) {
+    if ( !first_entry ) {
+      strcat ( buffer, " | " );
+    }
+    strcat ( buffer, desc[18] );
+  }
+
+  return buffer;
+}
+
+
+/*
+ *  Callback function to print out thread Ids, thread priorities, and thread stack
+ *  information.
+ */
+
+unsigned32 print_thread_info( Thread_Control *thread, void * arg )
+{
+  printf( "Thread ID 0x%08x at "PTR_MASK"\n", thread->Object.id, (PTR)thread );
+  printf( "\ttype = %s\n", _Objects_Type_to_String( &(thread->Object) ) );
+  printf( "\tstate = %s\n", _Thread_State_to_String( thread->current_state ) );
+  printf( "\treal priority = %d\n", thread->real_priority );
+  printf( "\tcurrent priority = %d\n", thread->current_priority );
+  printf( "\tstack base = "PTR_MASK"\n", (PTR)thread->Start.Initial_stack.area );
+  printf( "\tstack size = 0x%08x\n", thread->Start.Initial_stack.size );
+  /* printf( "\tstack pointer = "PTR_MASK"\n", */
+  printf( "\n" );
+  return 0;
+}
Index: c/src/tests/sptests/threaditerate/threaditerate.scn
===================================================================
--- c/src/tests/sptests/threaditerate/threaditerate.scn	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ c/src/tests/sptests/threaditerate/threaditerate.scn	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,205 @@
+*** Thread Iteration Test ***
+Created and started an RTEMS task with id = 0x08010002
+Created and started an RTEMS task with id = 0x08010003
+Created and started an RTEMS task with id = 0x08010004
+Created and started a pthread with id = 0x0c010001
+Created and started a pthread with id = 0x0c010002
+Created and started a pthread with id = 0x0c010003
+Created and started an ITRON task with id = 0x10010002
+Created and started an ITRON task with id = 0x10010003
+Created and started an ITRON task with id = 0x10010004
+Sleeping for 5 seconds
+
+Looking for all threads
+
+Thread ID 0x04010001 at 0x00192364
+        type = INTERNAL_THREADS
+        state = READY
+        real priority = 255
+        current priority = 255
+        stack base = 0x0018cde8
+        stack size = 0x00002008
+
+Thread ID 0x08010001 at 0x00191390
+        type = RTEMS_TASKS
+        state = READY
+        real priority = 1
+        current priority = 1
+        stack base = 0x0018ac54
+        stack size = 0x00002008
+
+Thread ID 0x08010002 at 0x001914ec
+        type = RTEMS_TASKS
+        state = DELAYING
+        real priority = 1
+        current priority = 1
+        stack base = 0x00186ac0
+        stack size = 0x00004008
+
+Thread ID 0x08010003 at 0x00191648
+        type = RTEMS_TASKS
+        state = DELAYING
+        real priority = 1
+        current priority = 1
+        stack base = 0x0018292c
+        stack size = 0x00004008
+
+Thread ID 0x08010004 at 0x001917a4
+        type = RTEMS_TASKS
+        state = DELAYING
+        real priority = 1
+        current priority = 1
+        stack base = 0x0017c798
+        stack size = 0x00006008
+
+Thread ID 0x0c010001 at 0x0018fbf4
+        type = POSIX_THREADS
+        state = DELAYING | INTERRUPTIBLE_BY_SIGNAL
+        real priority = 1
+        current priority = 1
+        stack base = 0x00178604
+        stack size = 0x00004008
+
+Thread ID 0x0c010002 at 0x0018fd50
+        type = POSIX_THREADS
+        state = DELAYING | INTERRUPTIBLE_BY_SIGNAL
+        real priority = 1
+        current priority = 1
+        stack base = 0x00174470
+        stack size = 0x00004008
+
+Thread ID 0x0c010003 at 0x0018feac
+        type = POSIX_THREADS
+        state = DELAYING | INTERRUPTIBLE_BY_SIGNAL
+        real priority = 1
+        current priority = 1
+        stack base = 0x001702dc
+        stack size = 0x00004008
+
+Thread ID 0x10010002 at 0x0018ef58
+        type = ITRON_TASKS
+        state = DELAYING
+        real priority = 1
+        current priority = 1
+        stack base = 0x0016c148
+        stack size = 0x00004008
+
+Thread ID 0x10010003 at 0x0018f0b4
+        type = ITRON_TASKS
+        state = DELAYING
+        real priority = 1
+        current priority = 1
+        stack base = 0x00167f24
+        stack size = 0x00004008
+
+Thread ID 0x10010004 at 0x0018f210
+        type = ITRON_TASKS
+        state = DELAYING
+        real priority = 1
+        current priority = 1
+        stack base = 0x00161d00
+        stack size = 0x00006008
+
+That was it. Sleeping for 20 seconds.
+TA1  - rtems_clock_get - 09:00:10   12/31/2000
+TA2  - rtems_clock_get - 09:00:10   12/31/2000
+TA3  - rtems_clock_get - 09:00:10   12/31/2000
+pthread: ID is 0x0c010001
+ - clock_gettime - Sun Dec 31 09:00:10 2000
+
+pthread: ID is 0x0c010002
+ - clock_gettime - Sun Dec 31 09:00:10 2000
+
+pthread: ID is 0x0c010003
+ - clock_gettime - Sun Dec 31 09:00:10 2000
+ITRON task 1 - rtems_clock_get - 09:00:10   12/31/2000
+
+ITRON task 2 - rtems_clock_get - 09:00:10   12/31/2000
+ITRON task 3 - rtems_clock_get - 09:00:10   12/31/2000
+
+Deleting the second thread of each type
+
+
+Looking for all threads
+
+Thread ID 0x04010001 at 0x00192364
+        type = INTERNAL_THREADS
+        state = READY
+        real priority = 255
+        current priority = 255
+        stack base = 0x0018cde8
+        stack size = 0x00002008
+
+Thread ID 0x08010001 at 0x00191390
+        type = RTEMS_TASKS
+        state = READY
+        real priority = 1
+        current priority = 1
+        stack base = 0x0018ac54
+        stack size = 0x00002008
+
+Thread ID 0x08010002 at 0x001914ec
+        type = RTEMS_TASKS
+        state = DELAYING
+        real priority = 1
+        current priority = 1
+        stack base = 0x00186ac0
+        stack size = 0x00004008
+
+Thread ID 0x08010004 at 0x001917a4
+        type = RTEMS_TASKS
+        state = DELAYING
+        real priority = 1
+        current priority = 1
+        stack base = 0x0017c798
+        stack size = 0x00006008
+
+Thread ID 0x0c010001 at 0x0018fbf4
+        type = POSIX_THREADS
+        state = DELAYING | INTERRUPTIBLE_BY_SIGNAL
+        real priority = 1
+        current priority = 1
+        stack base = 0x00178604
+        stack size = 0x00004008
+
+Thread ID 0x0c010002 at 0x0018fd50
+        type = POSIX_THREADS
+        state = DELAYING | INTERRUPTIBLE_BY_SIGNAL
+        real priority = 1
+        current priority = 1
+        stack base = 0x00174470
+        stack size = 0x00004008
+
+Thread ID 0x0c010003 at 0x0018feac
+        type = POSIX_THREADS
+        state = DELAYING | INTERRUPTIBLE_BY_SIGNAL
+        real priority = 1
+        current priority = 1
+        stack base = 0x001702dc
+        stack size = 0x00004008
+
+Thread ID 0x10010002 at 0x0018ef58
+        type = ITRON_TASKS
+        state = DELAYING
+        real priority = 1
+        current priority = 1
+        stack base = 0x0016c148
+        stack size = 0x00004008
+
+Thread ID 0x10010003 at 0x0018f0b4
+        type = ITRON_TASKS
+        state = DORMANT
+        real priority = 1
+        current priority = 1
+        stack base = 0x00167f24
+        stack size = 0x00004008
+
+Thread ID 0x10010004 at 0x0018f210
+        type = ITRON_TASKS
+        state = DELAYING
+        real priority =1
+        current priority = 1
+        stack base = 0x00161d00
+        stack size = 0x00006008
+
+That was it. Exiting
Index: make/custom/mbx821_001.cfg
===================================================================
--- make/custom/mbx821_001.cfg	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ make/custom/mbx821_001.cfg	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,12 @@
+#
+#  Config file for a PowerPC MPC860-based MBX821-001 card.
+#
+
+#
+#  All MBX8xx configurations share the same base file, only a few
+#  parameters differ.
+#  
+
+RTEMS_MBX_MODEL=mbx821_001
+
+include $(RTEMS_ROOT)/make/custom/mbx8xx.cfg
Index: make/custom/mbx860_002.cfg
===================================================================
--- make/custom/mbx860_002.cfg	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ make/custom/mbx860_002.cfg	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,12 @@
+#
+#  Config file for a PowerPC MPC860-based MBX860-002 card.
+#
+
+#
+#  All MBX8xx configurations share the same base file, only a few
+#  parameters differ.
+#  
+
+RTEMS_MBX_MODEL=mbx860_002
+
+include $(RTEMS_ROOT)/make/custom/mbx8xx.cfg
Index: make/custom/mbx8xx.cfg
===================================================================
--- make/custom/mbx8xx.cfg	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
+++ make/custom/mbx8xx.cfg	(revision 41ab696625ec33c00b1788f200bc6e25edf30c8d)
@@ -0,0 +1,196 @@
+#
+#  Config file for a PowerPC MPC821- or MPC860-based MBX card
+#
+#  This file is derived from:
+#
+#  Config file for a PowerPC 403 based helas403 card
+#  Config file for MPC860 based Ethernet Comm Board
+#
+
+include $(RTEMS_ROOT)/make/custom/default.cfg
+
+RTEMS_CPU=powerpc
+RTEMS_CPU_MODEL=mpc8xx
+
+# This is the actual bsp directory used during the build process.
+RTEMS_BSP_FAMILY=mbx8xx
+
+# The value assigned to RTEMS_CPU, RTEMS_CPU_MODEL and RTEMS_BSP get
+# #defined in targopts.h. Source code can switch on these values with #ifdef
+# to select what code to compile for a specific CPU family member and specific
+# board. The RTEMS_CPU_MODEL is also used as the name of the libcpu directory,
+# while the RTEMS_BSP_FAMILY is used as the name of the libbsp directory.
+# For the MBX860 and MBX821, the boards and processors are sufficiently
+# similar that the ports are unified and use RTEMS_CPU_MODEL=mpc8xx and
+# RTEMS_BSP_FAMILY=mbx8xx. Because there are minor differences in the CPUs
+# and the boards, it is necessary to specify them fully during the build.
+# Do a "make RTEMS_BSP=<your_board> <target>" See below for a list of valid
+# values for <your_board>.
+
+ifeq ($(findstring mbx821,$(RTEMS_MBX_MODEL)),mbx821)
+CPU_TYPE=821
+else
+ifeq ($(findstring mbx860,$(RTEMS_MBX_MODEL)),mbx860)
+CPU_TYPE=860
+else
+RTEMS_BSP = mbx860_002
+RTEMS_MBX_MODEL = mbx860_002
+TARGET_ARCH=o-mbx860_002
+CPU_TYPE=860
+endif # mbx860
+endif # mbx821
+
+#  This section makes the target dependent options file.
+#
+#  Note that RTEMS_BSP matches the RTEMS_MBX_MODEL. Its value must be
+#  defined in targopts.h, so the few places that require different code
+#  for different MBX models can be distinguished. The value of
+#  RTEMS_BSP is already defined in targopts.h and is one of:
+#     mbx860_001    mbx821_001
+#     mbx860_002    mbx821_002
+#     mbx860_003    mbx821_003
+#     mbx860_004    mbx821_004
+#     mbx860_005    mbx821_005
+#     mbx860_001b   mbx821_001b
+#     mbx860_002b   mbx821_002b
+#     mbx860_003b   mbx821_003b
+#     mbx860_004b   mbx821_004b
+#     mbx860_005b   mbx821_005b
+#     mbx860_006b   mbx821_006b
+
+#  The specific CPU model is defined, so the few places that require
+#  different code for the MPC860 and MPC821 can be distinguished.
+#  Either mpc860 or mpc821 is defined.
+#
+#  MBX8xx-specific options:
+#
+#  CONSOLE_MINOR (BSP--console driver)
+#    Must be defined to be one of SMC1_MINOR, SMC2_MINOR, SCC2_MINOR,
+#    SCC3_MINOR, or SCC4_MINOR. Determines which device will be registered
+#    as /dev/console.
+#
+#  UARTS_USE_INTERRUPTS (BSP--console driver)
+#    Define if you want interrupt-driven I/O instead of polling. Superceeded
+#    by EPPCBUG_SMC1 on SMC1. 
+#
+#  EPPCBUG_SMC1 (BSP--console driver)
+#    If defined, the I/O through the SCM1 is done through the EPPCBug firmware.
+#    Because of limitations in revision 1.1 of the firmware, EPPCBug must be
+#    configured to use SMC1 as its console. If not defined, I/O through SMC1
+#    is done through a RTEMS device driver.
+#
+#  EPPCBUG_VECTORS (BSP--RTEMS)
+#    If defined, the most vectors branch to EPPCBug, except the following: 
+#    0x500 (external interrupt), 0x900 (decrementer).
+#
+#  INSTRUCTION_CACHE_ENABLE (BSP--RTEMS)
+#    If defined, the instruction cache will be enabled after address translation
+#    is turned on.
+#
+#  DATA_CACHE_ENABLE (BSP--RTEMS)
+#    If defined, the data cache will be enabled after address translation
+#    is turned on. 
+#    
+#  PowerPC-specific options:
+#       
+#  PPC_USE_SPRG (RTEMS PowerPC port)
+#     If defined (=1), then the PowerPC specific code in RTEMS will use some
+#     of the special purpose registers to slightly optimize interrupt
+#     response time.  The use of these registers can conflict with 
+#     other tools like debuggers.  This should be 0 when using EPPCBug 
+#     because its uses most SPRGs (don't believe the documentation!).
+#
+#  PPC_USE_DATA_CACHE (RTEMS PowerPC port)
+#     If defined, then the PowerPC specific code in RTEMS will use 
+#     data cache instructions to optimize the context switch code.
+#     This code can conflict with debuggers or emulators.
+#
+#  RTEMS generic options:
+#
+#  NDEBUG (C library)
+#     If defined, asserts do not generate code.  This is commonly used
+#     as a command line option.
+#
+#  RTEMS_TEST_NO_PAUSE (RTEMS tests)
+#     If defined, do not pause between screens of output in the rtems tests.
+#
+#  STACK_CHECKER_ON (RTEMS support code)
+#     If defined, stack bounds checking is enabled.
+#
+#  STACK_CHECKER_REPORT_USAGE (RTEMS support code)
+#     If this and STACK_CHECKER_ON are defined, then a report on stack usage
+#     per task is printed when the program exits.
+#
+#  RTEMS_DEBUG (RTEMS)
+#     If defined, debug checks in RTEMS and support library code are enabled.
+
+define make-target-options
+	@echo "#ifdef mpc$(CPU_TYPE)"                       >>$@
+	@echo "#undef mpc$(CPU_TYPE)"                       >>$@
+	@echo "#endif"                                      >>$@
+	@echo "#define mpc$(CPU_TYPE) 1"                    >>$@
+	@echo                                               >>$@
+	@echo "#define CONSOLE_MINOR SMC2_MINOR"            >>$@
+	@echo "#define UARTS_USE_INTERRUPTS 1"              >>$@
+	@echo "#define EPPCBUG_SMC1 1"                      >>$@
+	@echo "#define EPPCBUG_VECTORS 1"                   >>$@
+	@echo "#define INSTRUCTION_CACHE_ENABLE 1"          >>$@
+	@echo "#define DATA_CACHE_ENABLE 1"                 >>$@
+	@echo                                               >>$@
+	@echo "#define PPC_VECTOR_FILE_BASE 0x0000"         >>$@
+	@echo "#define PPC_USE_SPRG 0"                      >>$@
+	@echo "/* #define PPC_USE_DATA_CACHE 1" */          >>$@
+	@echo                                               >>$@
+	@echo "/* #define NDEBUG 1 */ "                     >>$@
+	@echo "#define RTEMS_TEST_NO_PAUSE 1"               >>$@
+	@echo "/* #define STACK_CHECKER_ON  1 */"           >>$@
+	@echo "/* #define STACK_CHECKER_REPORT_USAGE  1 */" >>$@
+	@echo "/* #define RTEMS_DEBUG  1 */"                >>$@
+endef
+
+#  This contains the compiler options necessary to select the CPU model
+#  and (hopefully) optimize for it.
+#
+CPU_CFLAGS = -mcpu=$(CPU_TYPE)
+
+CFLAGS_DEBUG_V += -ggdb
+CXXFLAGS_DEBUG_V += -ggdb
+
+# optimize flag: typically -O, could use -O4 or -fast
+# -O4 is ok for RTEMS
+# NOTE: some level of -O may be actually required by inline assembler
+# CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions
+CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions
+CXXFLAGS_OPTIMIZE_V=-O4
+
+# The following are definitions of make-exe which will work using ld as
+# is currently required.  It is expected that as of gcc 2.8, the end user
+# will be able to override parts of the compilers specs and link using gcc.
+
+ifeq ($(RTEMS_USE_GCC272),yes)
+# The --defsym arguments define arguments which are required by the linkcmds
+# file which is designed for gcc 2.8
+define make-exe
+	$(LD) $(XLDFLAGS) -T $(LINKCMDS) \
+	    --defsym __fini=0 --defsym __init=0 \
+	    -o $@ -u atexit -u __vectors -u start \
+	    $(START_FILE) $(LINK_OBJS) --start-group $(LINK_LIBS) --end-group
+	$(NM) -g -n $@ > $(basename $@).num
+	$(STRIP) -o $(basename $@).elf $@
+	$(SIZE) $@
+endef
+else
+define make-exe
+	$(CC) $(CFLAGS) $(CPU_CFLAGS) $(XLDFLAGS) -o $(basename $@).exe \
+	    $(LINK_OBJS) $(LINK_LIBS)
+	$(NM) -g -n $@ > $(basename $@).nm
+	$(STRIP) -o $(basename $@) $@
+	$(SIZE) $@
+endef
+endif
+
+# Miscellaneous additions go here
+
+# Override default start file
+START_BASE=
+
