diff --git a/avcall/Makefile.devel b/avcall/Makefile.devel
index a125a15..6ec6700 100644
--- a/avcall/Makefile.devel
+++ b/avcall/Makefile.devel
@@ -9,7 +9,7 @@ RM = rm -f
 SED = sed
 ROFF_MAN = groff -Tascii -mandoc
 
-all : avcall-i386-macro.S avcall-i386-msvc.c avcall-i386-mingw32.c avcall.h.msvc avcall.h.mingw32 avcall-m68k.mit.S avcall-m68k.mot.s avcall-m68k-amiga.s avcall-mips.S avcall-mipsn32.S avcall-mips64.S avcall-sparc.S avcall-sparc64.S avcall-alpha.s avcall-hppa.s avcall-arm.S avcall-powerpc-aix.old.s avcall-powerpc-aix.new.s avcall-powerpc-sysv4.s avcall-powerpc-macos.s avcall-powerpc64.s avcall-m88k.s avcall-convex.s avcall-ia64.s avcall-x86_64.s avcall.man
+all : avcall-i386-macro.S avcall-i386-msvc.c avcall-i386-mingw32.c avcall.h.msvc avcall.h.mingw32 avcall-m68k.mit.S avcall-m68k.mot.s avcall-m68k-amiga.s avcall-mips.S avcall-mipsn32.S avcall-mips64.S avcall-sparc.S avcall-sparc64.S avcall-alpha.s avcall-hppa.s avcall-arm.S avcall-armel.S avcall-powerpc-aix.old.s avcall-powerpc-aix.new.s avcall-powerpc-sysv4.s avcall-powerpc-macos.s avcall-powerpc64.s avcall-m88k.s avcall-convex.s avcall-ia64.s avcall-x86_64.s avcall.man
 
 avcall-i386-macro.S : avcall-i386.c avcall.h.in asmi386.sh
 	$(GCC) -V 2.7.2 -b i486-linuxaout $(GCCFLAGS) -D__i386__ -fno-omit-frame-pointer -S avcall-i386.c -o avcall-i386.s
@@ -81,6 +81,11 @@ avcall-arm.S : avcall-arm.c avcall.h.in asmarm.sh
 	(echo '#include "asmarm.h"' ; ./asmarm.sh < avcall-arm.s) > avcall-arm.S
 	$(RM) avcall-arm.s
 
+avcall-armel.S : avcall-arm.c avcall.h.in
+	$(GCC) $(GCCFLAGS) -D__arm__ -S avcall-armel.c -o avcall-armel.s
+	(echo '#include "asmarm.h"' ; cat < avcall-armel.s) > avcall-armel.S
+	$(RM) avcall-armel.s
+
 avcall-powerpc-aix.old.s : avcall-powerpc.c avcall.h.in
 	$(GCC) -V 2.95.2 -b rs6000 -mno-power -mno-power2 -mno-powerpc -mold-mnemonics $(GCCFLAGS) -D__powerpc__ -S avcall-powerpc.c -o avcall-powerpc-aix.old.s
 
diff --git a/avcall/Makefile.in b/avcall/Makefile.in
index 0fedcfe..e9cb322 100644
--- a/avcall/Makefile.in
+++ b/avcall/Makefile.in
@@ -117,6 +117,12 @@ avcall-arm.lo : avcall-arm.s
 avcall-arm.s : $(srcdir)/avcall-arm.S
 	$(CPP) $(ASPFLAGS) $(srcdir)/avcall-arm.S | grep -v '^ *#line' | grep -v '^#' | sed -e 's,% ,%,g' -e 's,//,@,g' -e 's,\$$,#,g' > avcall-arm.s
 
+avcall-armel.lo : avcall-armel.s
+	$(LIBTOOL_COMPILE) $(CC) @GCC_X_NONE@ -c avcall-armel.s
+
+avcall-armel.s : $(srcdir)/avcall-armel.S
+	cp $(srcdir)/avcall-armel.S avcall-armel.s
+
 avcall-powerpc.lo : $(srcdir)/avcall-powerpc-aix.old.s $(srcdir)/avcall-powerpc-aix.new.s $(srcdir)/avcall-powerpc-sysv4.s $(srcdir)/avcall-powerpc-macos.s
 	case "$(OS)" in \
 	  aix3*) syntax=aix.old;; \
@@ -223,7 +229,7 @@ mostlyclean : clean
 
 clean : force
 	$(RM) *.o *.lo *.a libavcall.* core
-	$(RM) avcall-i386.s avcall-sparc.s avcall-sparc64.s avcall-m68k.s avcall-mips.s avcall-mipsn32.s avcall-mips64.s avcall-arm.s
+	$(RM) avcall-i386.s avcall-sparc.s avcall-sparc64.s avcall-m68k.s avcall-mips.s avcall-mipsn32.s avcall-mips64.s avcall-arm.s avcall-armel.s
 	$(RM) -r .libs _libs
 	$(RM) minitests.o minitests.s minitests minitests.out
 	$(RM) tests.o tests.s tests tests.out
diff --git a/avcall/avcall-armel.S b/avcall/avcall-armel.S
new file mode 100644
index 0000000..c674ce1
--- /dev/null
+++ b/avcall/avcall-armel.S
@@ -0,0 +1,150 @@
+#include "asmarm.h"
+	.cpu arm10tdmi
+	.fpu softvfp
+	.file	"avcall-armel.c"
+	.text
+	.align	2
+	.global	__builtin_avcall
+	.type	__builtin_avcall, %function
+__builtin_avcall:
+	@ args = 0, pretend = 0, frame = 1024
+	@ frame_needed = 0, uses_anonymous_args = 0
+	stmfd	sp!, {r4, lr}
+	ldr	r3, [r0, #20]
+	mov	lr, #4
+	rsb	r3, r0, r3
+	sub	r3, r3, #32
+	mov	ip, r3, asr #2
+	sub	sp, sp, #1024
+	cmp	lr, ip
+	mov	r4, r0
+	mov	r0, sp
+	bge	.L59
+.L75:
+	mov	r3, lr, asl #2
+	add	r2, r3, r4
+	ldr	r1, [r2, #32]
+	add	lr, lr, #1
+	add	r3, r3, r0
+	cmp	lr, ip
+	str	r1, [r3, #-16]
+	blt	.L75
+.L59:
+	add	r0, r4, #32
+	ldmia	r0, {r0, r1, r2, r3}	@ phole ldm
+	mov	lr, pc
+	ldr	pc, [r4, #0]
+	ldr	r2, [r4, #12]
+	mov	lr, r0
+	cmp	r2, #1
+	beq	.L7
+	cmp	r2, #0
+	beq	.L73
+	cmp	r2, #2
+	beq	.L65
+	cmp	r2, #3
+	beq	.L65
+	cmp	r2, #4
+	beq	.L65
+	cmp	r2, #5
+	beq	.L66
+	cmp	r2, #6
+	beq	.L66
+	cmp	r2, #7
+	beq	.L73
+	cmp	r2, #8
+	beq	.L73
+	cmp	r2, #9
+	beq	.L73
+	cmp	r2, #10
+	beq	.L73
+	sub	r3, r2, #11
+	cmp	r3, #1
+	bls	.L72
+	cmp	r2, #13
+	ldreq	r3, [r4, #8]
+	streq	r0, [r3, #0]	@ float
+	beq	.L7
+	cmp	r2, #14
+	beq	.L76
+	cmp	r2, #15
+	beq	.L73
+	cmp	r2, #16
+	bne	.L7
+	ldr	r3, [r4, #4]
+	tst	r3, #1
+	beq	.L37
+	ldr	r3, [r4, #16]
+	cmp	r3, #1
+	ldreq	r2, [r4, #8]
+	ldreqb	r3, [r0, #0]	@ zero_extendqisi2
+	streqb	r3, [r2, #0]
+	beq	.L7
+	cmp	r3, #2
+	ldreq	r3, [r4, #8]
+	ldreqh	lr, [r0, #0]
+	beq	.L64
+	cmp	r3, #4
+	ldrls	r2, [r4, #8]
+	ldrls	r3, [lr, #0]
+	strls	r3, [r2, #0]
+	bls	.L7
+	cmp	r3, #8
+	beq	.L77
+	add	r3, r3, #3
+	mov	r2, r3, lsr #2
+	subs	r2, r2, #1
+	bmi	.L7
+	ldr	r0, [r4, #8]
+.L48:
+	ldr	r3, [lr, r2, asl #2]
+	str	r3, [r0, r2, asl #2]
+	subs	r2, r2, #1
+	bpl	.L48
+.L7:
+	mov	r0, #0
+	add	sp, sp, #1024
+	ldmfd	sp!, {r4, pc}
+.L73:
+	ldr	r3, [r4, #8]
+	str	lr, [r3, #0]
+	b	.L7
+.L65:
+	ldr	r3, [r4, #8]
+	strb	lr, [r3, #0]
+	b	.L7
+.L66:
+	ldr	r3, [r4, #8]
+.L64:
+	strh	lr, [r3, #0]	@ movhi 
+	b	.L7
+.L37:
+	tst	r3, #512
+	beq	.L7
+	ldr	r3, [r4, #16]
+	cmp	r3, #1
+	beq	.L65
+	cmp	r3, #2
+	beq	.L66
+	cmp	r3, #4
+	beq	.L73
+	cmp	r3, #8
+	bne	.L7
+.L72:
+	ldr	r3, [r4, #8]
+	str	r1, [r3, #4]
+	str	lr, [r3, #0]
+	b	.L7
+.L76:
+	ldr	r3, [r4, #8]
+	stmia	r3, {r0-r1}
+	b	.L7
+.L77:
+	ldr	r3, [r4, #8]
+	ldr	r2, [lr, #0]
+	str	r2, [r3, #0]
+	ldr	r1, [lr, #4]
+	str	r1, [r3, #4]
+	b	.L7
+	.size	__builtin_avcall, .-__builtin_avcall
+	.ident	"GCC: (GNU) 3.4.4 (release) (CodeSourcery ARM 2005q3-2)"
diff --git a/avcall/avcall-armel.c b/avcall/avcall-armel.c
new file mode 100644
index 0000000..a85271a
--- /dev/null
+++ b/avcall/avcall-armel.c
@@ -0,0 +1,144 @@
+#ifndef _avcall_arm_c				/*-*- C -*-*/
+#define _avcall_arm_c
+/**
+  Copyright 1993 Bill Triggs, <Bill.Triggs@inrialpes.fr>
+  Copyright 1995-1999 Bruno Haible, <bruno@clisp.org>
+
+  This is free software distributed under the GNU General Public
+  Licence described in the file COPYING. Contact the author if
+  you don't have this or can't live with it. There is ABSOLUTELY
+  NO WARRANTY, explicit or implied, on this software.
+**/
+/*----------------------------------------------------------------------
+  !!! THIS ROUTINE MUST BE COMPILED gcc -O !!!
+
+  Foreign function interface for an Acorn Risc Maschine with gcc.
+
+  This calls a C function with an argument list built up using macros
+  defined in av_call.h.
+
+  ARM Argument Passing Conventions:
+
+  All arguments, except the first 4 words, are passed on the stack with
+  word alignment. Doubles take two words. Structure args are passed as
+  true structures embedded in the argument stack. To return a structure,
+  the called function copies the return value to the address supplied
+  in register "%r0".
+
+  Compile this routine with gcc -O (or -O2 or -g -O) to get the right
+  register variables, or use the assembler version.
+  ----------------------------------------------------------------------*/
+#include "avcall.h.in"
+
+#define RETURN(TYPE,VAL)	(*(TYPE*)l->raddr = (TYPE)(VAL))
+
+int
+__builtin_avcall(av_alist* l)
+{
+  register __avword*	sp	__asm__("r13");  /* C names for registers */
+/*register __avword	iret	__asm__("r0"); */
+  register __avword	iret2	__asm__("r1");
+  register float	fret	__asm__("r0");	/* r0 */
+  register double	dret	__asm__("r0");	/* r0,r1 */
+
+  __avword space[__AV_ALIST_WORDS];	/* space for callee's stack frame */
+  __avword* argframe = sp;		/* stack offset for argument list */
+  int arglen = l->aptr - l->args;
+  __avword i;
+
+  for (i = 4; i < arglen; i++)		/* push function args onto stack */
+    argframe[i-4] = l->args[i];
+
+				/* call function, pass 4 args in registers */
+  i = (*l->func)(l->args[0], l->args[1], l->args[2], l->args[3]);
+
+  /* save return value */
+  if (l->rtype == __AVvoid) {
+  } else
+  if (l->rtype == __AVword) {
+    RETURN(__avword, i);
+  } else
+  if (l->rtype == __AVchar) {
+    RETURN(char, i);
+  } else
+  if (l->rtype == __AVschar) {
+    RETURN(signed char, i);
+  } else
+  if (l->rtype == __AVuchar) {
+    RETURN(unsigned char, i);
+  } else
+  if (l->rtype == __AVshort) {
+    RETURN(short, i);
+  } else
+  if (l->rtype == __AVushort) {
+    RETURN(unsigned short, i);
+  } else
+  if (l->rtype == __AVint) {
+    RETURN(int, i);
+  } else
+  if (l->rtype == __AVuint) {
+    RETURN(unsigned int, i);
+  } else
+  if (l->rtype == __AVlong) {
+    RETURN(long, i);
+  } else
+  if (l->rtype == __AVulong) {
+    RETURN(unsigned long, i);
+  } else
+  if (l->rtype == __AVlonglong || l->rtype == __AVulonglong) {
+    ((__avword*)l->raddr)[0] = i;
+    ((__avword*)l->raddr)[1] = iret2;
+  } else
+  if (l->rtype == __AVfloat) {
+    RETURN(float, fret);
+  } else
+  if (l->rtype == __AVdouble) {
+    RETURN(double, dret);
+  } else
+  if (l->rtype == __AVvoidp) {
+    RETURN(void*, i);
+  } else
+  if (l->rtype == __AVstruct) {
+    /* NB: On arm, all structure sizes are divisible by 4. */
+    if (l->flags & __AV_PCC_STRUCT_RETURN) {
+      /* pcc struct return convention: need a  *(TYPE*)l->raddr = *(TYPE*)i;  */
+      if (l->rsize == sizeof(char)) { /* can't occur */
+        RETURN(char, *(char*)i);
+      } else
+      if (l->rsize == sizeof(short)) { /* can't occur */
+        RETURN(short, *(short*)i);
+      } else
+      if (l->rsize <= sizeof(int)) { /* structs of size 3 also returned in registers */
+        RETURN(int, *(int*)i);
+      } else
+      if (l->rsize == sizeof(double)) {
+        ((int*)l->raddr)[0] = ((int*)i)[0];
+        ((int*)l->raddr)[1] = ((int*)i)[1];
+      } else {
+        int n = (l->rsize+3)/4;
+        while (--n >= 0)
+          ((__avword*)l->raddr)[n] = ((__avword*)i)[n];
+      }
+    } else {
+      /* normal struct return convention */
+      if (l->flags & __AV_REGISTER_STRUCT_RETURN) {
+        if (l->rsize == sizeof(char)) { /* can't occur */
+          RETURN(char, i);
+        } else
+        if (l->rsize == sizeof(short)) { /* can't occur */
+          RETURN(short, i);
+        } else
+        if (l->rsize == sizeof(int)) {
+          RETURN(int, i);
+        } else
+        if (l->rsize == 2*sizeof(__avword)) {
+          ((__avword*)l->raddr)[0] = i;
+          ((__avword*)l->raddr)[1] = iret2;
+        }
+      }
+    }
+  }
+  return 0;
+}
+
+#endif /*_avcall_arm_c */
diff --git a/avcall/avcall.h.in b/avcall/avcall.h.in
index cb1eb7c..8d4838c 100644
--- a/avcall/avcall.h.in
+++ b/avcall/avcall.h.in
@@ -195,7 +195,7 @@ enum __AV_alist_flags
 #if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */
 				  __AV_PCC_STRUCT_RETURN,
 #else
-#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) /* defined through configure, see above */
+#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) || defined(__ARMEL__) /* defined through configure, see above */
 				  __AV_SMALL_STRUCT_RETURN |
 #endif
 #if defined(__GNUC__)
@@ -541,7 +541,7 @@ typedef struct
 #define __av_start_struct3(LIST)  \
   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
 #endif
-#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
+#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
 #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4		\
    || ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE)				\
@@ -553,6 +553,14 @@ typedef struct
 #define __av_start_struct3(LIST)  \
   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
 #endif
+
+#if defined(__ARMEL__)
+#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
+    ((TYPE_SIZE) <= 4)
+#define __av_start_struct3(LIST)  \
+  ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
+#endif
+
 #if defined(__alpha__)
 #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8	\
@@ -748,11 +756,18 @@ typedef struct
 #define av_longlong(LIST,VAL)	__av_longlong(LIST,long long,VAL)
 #define av_ulonglong(LIST,VAL)	__av_longlong(LIST,unsigned long long,VAL)
 #if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
+#if defined(__ARMEL__)
+/* `long long's are 8 bytes aligned on ARM. */
+#define __av_longlong(LIST,TYPE,VAL)                                   \
+  (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST)        \
+   ? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
+#else
 /* `long long's are (at most) word-aligned. */
 #define __av_longlong(LIST,TYPE,VAL)					\
   (((LIST).aptr += sizeof(TYPE)/sizeof(__avword)) > __av_eptr(LIST)	\
    ? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
 #endif
+#endif
 #if defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__s390__)
 /* `long long's have alignment 8. */
 #if defined(__mips__)
@@ -799,6 +814,17 @@ typedef struct
   (++(LIST).aptr > __av_eptr(LIST)					\
    ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0))
 
+#if defined(__ARMEL__)
+/* Almost identical normal case, but we must align location */
+#define av_double(LIST,VAL)                                            \
+   (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+15)&-8))          \
+    > __av_eptr(LIST)                                                   \
+    ? -1 :                                                             \
+    ((LIST).tmp._double = (double)(VAL),                               \
+     (LIST).aptr[-2] = (LIST).tmp.words[0],                            \
+     (LIST).aptr[-1] = (LIST).tmp.words[1],                            \
+     0))
+#else
 /* This assumes sizeof(double) == 2*sizeof(__avword). */
 #define av_double(LIST,VAL)						\
    (((LIST).aptr += 2) > __av_eptr(LIST)				\
@@ -807,7 +833,7 @@ typedef struct
      (LIST).aptr[-2] = (LIST).tmp.words[0],				\
      (LIST).aptr[-1] = (LIST).tmp.words[1],				\
      0))
-
+#endif
 #endif
 
 #if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
@@ -1111,14 +1137,14 @@ typedef struct
 #define __av_struct_alignment(TYPE_ALIGN)  \
   (TYPE_ALIGN)
 #endif
-#if defined(__i386__) || defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || (defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__powerpc64__) || defined(__m88k__) || defined(__ia64__) || defined(__s390__)
+#if defined(__i386__) || defined(__mips__) || defined(__ARMEL__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || (defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__powerpc64__) || defined(__m88k__) || defined(__ia64__) || defined(__s390__)
 /* Structures are passed as fully aligned structures on the arg stack.
  * We align the aptr, store the structure, then fill to word alignment.
  * Single-small-integer structures are NOT promoted to integers and have
  * different alignment.
  */
 /* little endian -> small structures < 1 word are adjusted to the left */
-#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || (defined(__ia64__) && defined(__GNUC__) && (__GNUC__ >= 3))
+#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__ARMEL__) || (defined(__ia64__) && defined(__GNUC__) && (__GNUC__ >= 3))
 #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)		\
   (((LIST).aptr =							\
     (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN)))\
@@ -1259,7 +1285,7 @@ typedef struct
 	   0))
 #endif
 #endif
-#if defined(__m68k__) || defined(__arm__) || defined(__convex__)
+#if defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__convex__)
 /* Structures are passed as embedded copies on the arg stack.
  */
 #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)		\
diff --git a/avcall/configure b/avcall/configure
index 25b6a1f..3220b41 100755
--- a/avcall/configure
+++ b/avcall/configure
@@ -3806,6 +3806,12 @@ case "$host_cpu" in
     ;;
   arm* )
     host_cpu_abi=arm
+    # check for armel
+    if which dpkg-architecture > /dev/null; then
+      if dpkg-architecture -iarmel; then
+        host_cpu_abi=armel
+      fi
+    fi
     ;;
   mips* )
     { $as_echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
diff --git a/avcall/tests.c b/avcall/tests.c
index b1666fb..07d6800 100644
--- a/avcall/tests.c
+++ b/avcall/tests.c
@@ -18,6 +18,7 @@
   and some varargs ones, and also try to test structure alignment more
   throughly.
  ----------------------------------------------------------------------*/
+#include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/callback/configure b/callback/configure
index 8322e8c..51e2d20 100755
--- a/callback/configure
+++ b/callback/configure
@@ -3787,6 +3787,12 @@ case "$host_cpu" in
     ;;
   arm* )
     host_cpu_abi=arm
+    # check for armel
+    if which dpkg-architecture > /dev/null; then
+      if dpkg-architecture -iarmel; then
+        host_cpu_abi=armel
+      fi
+    fi
     ;;
   mips* )
     { $as_echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
diff --git a/callback/tests.c b/callback/tests.c
index 23fb183..d5cdb39 100644
--- a/callback/tests.c
+++ b/callback/tests.c
@@ -9,6 +9,7 @@
  * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
  * on this software.
  */
+#include "config.h"
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/callback/trampoline_r/Makefile.devel b/callback/trampoline_r/Makefile.devel
index 383c349..a9bed5e 100644
--- a/callback/trampoline_r/Makefile.devel
+++ b/callback/trampoline_r/Makefile.devel
@@ -93,6 +93,9 @@ cache-powerpc-macos.s : cache-powerpc.c
 cache-convex.s : cache-convex.c
 	$(GCC) -V 2.6.3 -b convex-c2 $(GCCFLAGS) -D__convex__ -S $< -o $@
 
+cache-armel.s : cache-armel.c
+	$(GCC) $(GCCFLAGS)  -fomit-frame-pointer -S cache-armel.c -o cache-armel.s
+
 trampoline_r.man : trampoline_r.3
 	$(ROFF_MAN) trampoline_r.3 > trampoline_r.man
 
diff --git a/callback/trampoline_r/Makefile.in b/callback/trampoline_r/Makefile.in
index 864014d..fcf9814 100644
--- a/callback/trampoline_r/Makefile.in
+++ b/callback/trampoline_r/Makefile.in
@@ -103,6 +103,9 @@ cache-alpha.lo : $(srcdir)/cache-alpha.s
 cache-arm.lo : $(srcdir)/cache-arm.s
 	$(LIBTOOL_COMPILE) $(CC) @GCC_X_NONE@ -c $(srcdir)/cache-arm.s
 
+cache-armel.lo : $(srcdir)/cache-armel.s
+	$(LIBTOOL_COMPILE) $(CC) @GCC_X_NONE@ -c $(srcdir)/cache-armel.s
+
 cache-hppa.lo : $(srcdir)/cache-hppa.s
 	$(LIBTOOL_COMPILE) $(CC) @GCC_X_NONE@ -c $(srcdir)/cache-hppa.s
 
diff --git a/callback/trampoline_r/cache-armel.c b/callback/trampoline_r/cache-armel.c
new file mode 100644
index 0000000..c3dd520
--- /dev/null
+++ b/callback/trampoline_r/cache-armel.c
@@ -0,0 +1,19 @@
+/* Instruction cache flushing for arm */
+
+/*
+ * Copyright 1997 Bruno Haible, <bruno@clisp.org>
+ *
+ * This is free software distributed under the GNU General Public Licence
+ * described in the file COPYING. Contact the author if you don't have this
+ * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
+ * on this software.
+ */
+#include <linux/unistd.h>
+
+void __TR_clear_cache (char *first_addr, char *last_addr)
+{
+    register unsigned long _beg __asm ("a1") = first_addr;
+    register unsigned long _end __asm ("a2") = last_addr;
+    register unsigned long _flg __asm ("a3") = 0; 
+    __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
+}
diff --git a/callback/trampoline_r/cache-armel.s b/callback/trampoline_r/cache-armel.s
new file mode 100644
index 0000000..58b9dd2
--- /dev/null
+++ b/callback/trampoline_r/cache-armel.s
@@ -0,0 +1,18 @@
+	.cpu arm10tdmi
+	.fpu softvfp
+	.file	"cache-armel.c"
+	.text
+	.align	2
+	.global	__TR_clear_cache
+	.type	__TR_clear_cache, %function
+__TR_clear_cache:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 0, uses_anonymous_args = 0
+	@ link register save eliminated.
+	@ lr needed for prologue
+	mov	r2, #0
+#APP
+	swi 0x9f0002
+	bx	lr
+	.size	__TR_clear_cache, .-__TR_clear_cache
+	.ident	"GCC: (GNU) 3.4.4 (release) (CodeSourcery ARM 2005q3-2)"
diff --git a/callback/trampoline_r/configure b/callback/trampoline_r/configure
index 81562be..c2f19e5 100755
--- a/callback/trampoline_r/configure
+++ b/callback/trampoline_r/configure
@@ -3829,6 +3829,12 @@ case "$host_cpu" in
     ;;
   arm* )
     host_cpu_abi=arm
+    # check for armel
+    if which dpkg-architecture > /dev/null; then
+      if dpkg-architecture -iarmel; then
+        host_cpu_abi=armel
+      fi
+    fi
     ;;
   mips* )
     { $as_echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
@@ -22584,7 +22590,7 @@ if test ${host_cpu_abi} = powerpc; then
     *) ;;
   esac
 fi
-if test ${host_cpu_abi} = sparc -o ${host_cpu_abi} = sparc64 -o ${host_cpu_abi} = alpha -o ${host_cpu_abi} = hppa -o ${host_cpu_abi} = convex -o ${host_cpu_abi} = arm; then
+if test ${host_cpu_abi} = sparc -o ${host_cpu_abi} = sparc64 -o ${host_cpu_abi} = alpha -o ${host_cpu_abi} = hppa -o ${host_cpu_abi} = convex -o ${host_cpu_abi} = arm -o ${host_cpu_abi} = armel; then
   CPU_OBJECTS="$CPU_OBJECTS "'cache-$(CPU).lo'
 fi
 if test ${host_cpu_abi} = powerpc; then
diff --git a/callback/trampoline_r/configure.in b/callback/trampoline_r/configure.in
index d3a824a..3aacd30 100644
--- a/callback/trampoline_r/configure.in
+++ b/callback/trampoline_r/configure.in
@@ -32,7 +32,7 @@ if test ${host_cpu_abi} = powerpc; then
     *) ;;
   esac
 fi
-if test ${host_cpu_abi} = sparc -o ${host_cpu_abi} = sparc64 -o ${host_cpu_abi} = alpha -o ${host_cpu_abi} = hppa -o ${host_cpu_abi} = convex -o ${host_cpu_abi} = arm; then
+if test ${host_cpu_abi} = sparc -o ${host_cpu_abi} = sparc64 -o ${host_cpu_abi} = alpha -o ${host_cpu_abi} = hppa -o ${host_cpu_abi} = convex -o ${host_cpu_abi} = arm -o ${host_cpu_abi} = armel; then
   CPU_OBJECTS="$CPU_OBJECTS "'cache-$(CPU).lo'
 fi
 if test ${host_cpu_abi} = powerpc; then
diff --git a/callback/vacall_r/Makefile.devel b/callback/vacall_r/Makefile.devel
index 9f2358f..86c82e5 100644
--- a/callback/vacall_r/Makefile.devel
+++ b/callback/vacall_r/Makefile.devel
@@ -9,7 +9,7 @@ RM = rm -f
 SED = sed
 ROFF_MAN = groff -Tascii -mandoc
 
-all : vacall-i386-macro.S vacall-i386-msvc.c vacall-i386-mingw32.c vacall-m68k.mit.S vacall-m68k.mot.s vacall-m68k-netbsd.S vacall-mips.S vacall-mipsn32.S vacall-mips64.S vacall-sparc.S vacall-sparc64.S vacall-alpha.s vacall-hppa.s vacall-arm.S vacall-powerpc-aix.old.s vacall-powerpc-aix.new.s vacall-powerpc-sysv4.s vacall-powerpc-macos.s vacall-powerpc64.s vacall-m88k.s vacall-convex.s vacall-ia64.s vacall-x86_64.s \
+all : vacall-i386-macro.S vacall-i386-msvc.c vacall-i386-mingw32.c vacall-m68k.mit.S vacall-m68k.mot.s vacall-m68k-netbsd.S vacall-mips.S vacall-mipsn32.S vacall-mips64.S vacall-sparc.S vacall-sparc64.S vacall-alpha.s vacall-hppa.s vacall-arm.S vacall-armel.s vacall-powerpc-aix.old.s vacall-powerpc-aix.new.s vacall-powerpc-sysv4.s vacall-powerpc-macos.s vacall-powerpc64.s vacall-m88k.s vacall-convex.s vacall-ia64.s vacall-x86_64.s \
       vacall_r.h.msvc config.h.msvc vacall_r.h.mingw32 config.h.mingw32
 
 vacall-i386-macro.S : vacall-i386.c vacall_r.h.in asmi386.sh
@@ -74,6 +74,9 @@ vacall-arm.S : vacall-arm.c vacall_r.h.in asmarm.sh
 	(echo '#include "asmarm.h"' ; ./asmarm.sh < vacall-arm.s) > vacall-arm.S
 	$(RM) vacall-arm.s
 
+vacall-armel.s : vacall-armel.c vacall_r.h.in
+	$(GCC) $(GCCFLAGS) -D__arm__ -D__ARMEL__ -DHAVE_LONG_LONG -fomit-frame-pointer -S vacall-armel.c -o vacall-armel.s
+
 vacall-powerpc-aix.old.s : vacall-powerpc.c vacall_r.h.in
 	$(GCC) -V 2.95.2 -b rs6000 -mno-power -mno-power2 -mno-powerpc -mold-mnemonics $(GCCFLAGS) -D__powerpc__ -S vacall-powerpc.c -o vacall-powerpc-aix.old.s
 
diff --git a/callback/vacall_r/Makefile.in b/callback/vacall_r/Makefile.in
index 880569b..afac9ad 100644
--- a/callback/vacall_r/Makefile.in
+++ b/callback/vacall_r/Makefile.in
@@ -121,6 +121,9 @@ vacall-arm.lo : vacall-arm.s
 vacall-arm.s : $(srcdir)/vacall-arm.S
 	$(CPP) $(ASPFLAGS) $(srcdir)/vacall-arm.S | grep -v '^ *#line' | grep -v '^#' | sed -e 's,% ,%,g' -e 's,//,@,g' -e 's,\$$,#,g' > vacall-arm.s
 
+vacall-armel.lo : vacall-armel.s
+	$(LIBTOOL_COMPILE) $(CC) @GCC_X_NONE@ -c vacall-armel.s
+
 vacall-powerpc.lo : $(srcdir)/vacall-powerpc-aix.old.s $(srcdir)/vacall-powerpc-aix.new.s $(srcdir)/vacall-powerpc-sysv4.s $(srcdir)/vacall-powerpc-linux.s $(srcdir)/vacall-powerpc-macos.s $(srcdir)/vacall-powerpc-netbsd.s
 	case "$(OS)" in \
 	  aix3*) syntax=aix.old;; \
diff --git a/callback/vacall_r/configure b/callback/vacall_r/configure
index f9995a8..d73e337 100755
--- a/callback/vacall_r/configure
+++ b/callback/vacall_r/configure
@@ -3806,6 +3806,12 @@ case "$host_cpu" in
     ;;
   arm* )
     host_cpu_abi=arm
+    # check for armel
+    if which dpkg-architecture > /dev/null; then
+      if dpkg-architecture -iarmel; then
+        host_cpu_abi=armel
+      fi
+    fi
     ;;
   mips* )
     { $as_echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
diff --git a/callback/vacall_r/vacall-armel.c b/callback/vacall_r/vacall-armel.c
new file mode 100644
index 0000000..dd81cba
--- /dev/null
+++ b/callback/vacall_r/vacall-armel.c
@@ -0,0 +1,134 @@
+/* vacall function for arm CPU */
+
+/*
+ * Copyright 1995-2004 Bruno Haible, <bruno@clisp.org>
+ *
+ * This is free software distributed under the GNU General Public Licence
+ * described in the file COPYING. Contact the author if you don't have this
+ * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
+ * on this software.
+ */
+
+#ifndef REENTRANT
+#include "vacall.h.in"
+#else /* REENTRANT */
+#include "vacall_r.h.in"
+#endif
+
+#ifdef REENTRANT
+#define __vacall __vacall_r
+register struct { void (*vacall_function) (void*,va_alist); void* arg; }
+         *		env	__asm__("r12");
+#endif
+
+/* armel have only softvfp which uses generic registers */
+register __vaword	iret	__asm__("r0");
+register __vaword	iret2	__asm__("r1");
+register float		fret	__asm__("r0");
+register __vaword	dret1	__asm__("r0");
+register __vaword	dret2	__asm__("r1");
+
+void /* the return type is variable, not void! */
+__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
+          __vaword firstword)
+{
+  struct { long retaddr, sav1, sav2, sav3, sav4, arg1, arg2, arg3, arg4; } args;
+  __va_alist list;
+  /* MAGIC ALERT!
+   * This is the last struct on the stack, so that
+   * &args + 1 == &return_address == &firstword - 1.
+   * Look at the assembly code to convince yourself.
+   */
+  /* Move the arguments passed in registers to their stack locations. */
+  args.retaddr = (&firstword)[-1]; /* save the return address and saved registers */
+  args.sav1 = (&firstword)[-2];
+  args.sav2 = (&firstword)[-3];
+  args.sav3 = (&firstword)[-4];
+  args.sav4 = (&firstword)[-5];
+  args.arg1 = word1;
+  args.arg2 = word2;
+  args.arg3 = word3;
+  args.arg4 = word4;
+  (&firstword)[-4] = args.arg1;
+  (&firstword)[-3] = args.arg2;
+  (&firstword)[-2] = args.arg3;
+  (&firstword)[-1] = args.arg4;
+  /* Prepare the va_alist. */
+  list.flags = 0;
+  list.aptr = (long)(&firstword - 4);
+  list.raddr = (void*)0;
+  list.rtype = __VAvoid;
+  /* Call vacall_function. The macros do all the rest. */
+#ifndef REENTRANT
+  (*vacall_function) (&list);
+#else /* REENTRANT */
+  (*env->vacall_function) (env->arg,&list);
+#endif
+  /* Put return value into proper register. */
+  if (list.rtype == __VAvoid) {
+  } else
+  if (list.rtype == __VAchar) {
+    iret = list.tmp._char;
+  } else
+  if (list.rtype == __VAschar) {
+    iret = list.tmp._schar;
+  } else
+  if (list.rtype == __VAuchar) {
+    iret = list.tmp._uchar;
+  } else
+  if (list.rtype == __VAshort) {
+    iret = list.tmp._short;
+  } else
+  if (list.rtype == __VAushort) {
+    iret = list.tmp._ushort;
+  } else
+  if (list.rtype == __VAint) {
+    iret = list.tmp._int;
+  } else
+  if (list.rtype == __VAuint) {
+    iret = list.tmp._uint;
+  } else
+  if (list.rtype == __VAlong) {
+    iret = list.tmp._long;
+  } else
+  if (list.rtype == __VAulong) {
+    iret = list.tmp._ulong;
+  } else
+  if (list.rtype == __VAlonglong || list.rtype == __VAulonglong) {
+    iret  = ((__vaword *) &list.tmp._longlong)[0];
+    iret2 = ((__vaword *) &list.tmp._longlong)[1];
+  } else
+  if (list.rtype == __VAfloat) {
+    fret = list.tmp._float;
+  } else
+  if (list.rtype == __VAdouble) {
+      dret1 = ((__vaword *) &list.tmp._double)[0];
+      dret2 = ((__vaword *) &list.tmp._double)[1];
+  } else
+  if (list.rtype == __VAvoidp) {
+    iret = (long)list.tmp._ptr;
+  } else
+  if (list.rtype == __VAstruct) {
+    /* NB: On arm, all structure sizes are divisible by 4. */
+    if (list.flags & __VA_PCC_STRUCT_RETURN) {
+      /* pcc struct return convention */
+      iret = (long) list.raddr;
+    } else {
+      /* normal struct return convention */
+      if (list.flags & __VA_REGISTER_STRUCT_RETURN) {
+        if (list.rsize == sizeof(char)) { /* can't occur */
+          iret = *(unsigned char *) list.raddr;
+        } else
+        if (list.rsize == sizeof(short)) { /* can't occur */
+          iret = *(unsigned short *) list.raddr;
+        } else
+          iret = *(unsigned int *) list.raddr; /* struct of size 3 :) */
+      }
+    }
+  }
+  (&firstword)[-1] = args.retaddr; /* restore the return address and saved registers */
+  (&firstword)[-2] = args.sav1;
+  (&firstword)[-3] = args.sav2;
+  (&firstword)[-4] = args.sav3;
+  (&firstword)[-5] = args.sav4;
+}
diff --git a/callback/vacall_r/vacall-armel.s b/callback/vacall_r/vacall-armel.s
new file mode 100644
index 0000000..8c02831
--- /dev/null
+++ b/callback/vacall_r/vacall-armel.s
@@ -0,0 +1,120 @@
+	.cpu arm10tdmi
+	.fpu softvfp
+	.file	"vacall-armel.c"
+	.text
+	.align	2
+	.global	__vacall_r
+	.type	__vacall_r, %function
+__vacall_r:
+	@ args = 4, pretend = 0, frame = 72
+	@ frame_needed = 0, uses_anonymous_args = 0
+	stmfd	sp!, {r4, r5, r6, r7, r8, lr}
+	sub	sp, sp, #72
+	add	r6, sp, #96
+	ldr	r4, [r6, #-4]
+	ldr	lr, [sp, #88]
+	str	r4, [sp, #32]
+	ldr	r4, [sp, #84]
+	str	lr, [sp, #36]
+	ldr	lr, [sp, #80]
+	mov	r5, #0
+	str	r4, [sp, #40]
+	ldr	r4, [sp, #76]
+	str	lr, [sp, #44]
+	str	r5, [sp, #8]
+	add	lr, sp, #80
+	str	r0, [sp, #80]
+	str	r1, [sp, #84]
+	str	r4, [sp, #48]
+	str	r2, [sp, #88]
+	mov	r7, r0
+	str	r3, [r6, #-4]
+	mov	r8, r1
+	str	lr, [sp, #4]
+	str	r0, [sp, #52]
+	str	r1, [sp, #56]
+	str	r5, [sp, #12]
+	str	r2, [sp, #60]
+	str	r3, [sp, #64]
+	str	r5, [sp, #0]
+	ldr	r0, [ip, #4]
+	mov	r1, sp
+	mov	lr, pc
+	ldr	pc, [ip, #0]
+	ldr	lr, [sp, #12]
+	cmp	lr, r5
+	beq	.L3
+	cmp	lr, #1
+	beq	.L40
+	cmp	lr, #2
+	ldreqsb	r0, [sp, #24]
+	beq	.L3
+	cmp	lr, #3
+	beq	.L40
+	cmp	lr, #4
+	ldreqsh	r0, [sp, #24]
+	beq	.L3
+	cmp	lr, #5
+	ldreqh	r0, [sp, #24]
+	beq	.L3
+	cmp	lr, #6
+	beq	.L39
+	cmp	lr, #7
+	beq	.L39
+	cmp	lr, #8
+	beq	.L39
+	cmp	lr, #9
+	beq	.L39
+	sub	r3, lr, #10
+	cmp	r3, #1
+	bls	.L38
+	cmp	lr, #12
+	ldreq	r0, [sp, #24]	@ float
+	beq	.L3
+	cmp	lr, #13
+	beq	.L38
+	cmp	lr, #14
+	beq	.L39
+	cmp	lr, #15
+	bne	.L3
+	ldr	r3, [sp, #0]
+	tst	r3, #1
+	ldrne	r0, [sp, #8]
+	bne	.L3
+	tst	r3, #1024
+	beq	.L3
+	ldr	r3, [sp, #16]
+	cmp	r3, #1
+	ldreq	r3, [sp, #8]
+	ldreqb	r0, [r3, #0]	@ zero_extendqisi2
+	beq	.L3
+	cmp	r3, #2
+	ldreq	r3, [sp, #8]
+	ldrne	r3, [sp, #8]
+	ldreqh	r0, [r3, #0]
+	ldrne	r0, [r3, #0]
+.L3:
+	ldr	r3, [sp, #32]
+	str	r3, [r6, #-4]
+	ldr	r2, [sp, #48]
+	str	r2, [r6, #-20]
+	ldr	r3, [sp, #36]
+	str	r3, [r6, #-8]
+	ldr	r2, [sp, #40]
+	str	r2, [r6, #-12]
+	ldr	r3, [sp, #44]
+	str	r3, [r6, #-16]
+	add	sp, sp, #72
+	ldmfd	sp!, {r4, r5, r6, r7, r8, pc}
+.L40:
+	ldrb	r0, [sp, #24]	@ zero_extendqisi2
+	b	.L3
+.L39:
+	ldr	r0, [sp, #24]
+	b	.L3
+.L38:
+	ldr	r0, [sp, #24]
+	ldr	r1, [sp, #28]
+	b	.L3
+	.size	__vacall_r, .-__vacall_r
+	.ident	"GCC: (GNU) 3.4.4 (release) (CodeSourcery ARM 2005q3-2)"
diff --git a/callback/vacall_r/vacall_r.h.in b/callback/vacall_r/vacall_r.h.in
index 798f71b..2a3e3ec 100644
--- a/callback/vacall_r/vacall_r.h.in
+++ b/callback/vacall_r/vacall_r.h.in
@@ -197,7 +197,7 @@ enum __VA_alist_flags
 #if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */
 				  __VA_PCC_STRUCT_RETURN,
 #else
-#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) /* defined through configure, see above */
+#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) || defined(__ARMEL__)/* defined through configure, see above */
 				  __VA_SMALL_STRUCT_RETURN |
 #endif
 #if defined(__GNUC__)
@@ -471,7 +471,7 @@ typedef __va_alist* va_alist;
 #define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
   ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 #endif
-#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
+#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
 #define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4		\
    || ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE)				\
@@ -483,6 +483,17 @@ typedef __va_alist* va_alist;
 #define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
   ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 #endif
+
+#if defined(__ARMEL__)
+/* structs of size 3 also will be returned in register */
+#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
+    ((TYPE_SIZE) <= 4)
+/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
+ * and the struct will actually be returned in registers.
+ */
+#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
+  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
+#endif
 #if defined(__alpha__)
 #define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8	\
@@ -703,12 +714,12 @@ typedef __va_alist* va_alist;
    (LIST)->aptr + ((-(TYPE_SIZE)) & 3)					\
   )
 #endif
-#if defined(__i386__) || defined(__alpha__) || defined(__ia64__) || ((defined(__mipsn32__) || defined(__mips64__)) && defined(_MIPSEL))
+#if defined(__i386__) || defined(__alpha__) || defined(__ia64__) || defined(__ARMEL__) || ((defined(__mipsn32__) || defined(__mips64__)) && defined(_MIPSEL))
 /* little endian -> small args < 1 word are adjusted to the left */
 #define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
   __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
 #endif
-#if defined(__m68k__) || ((defined(__mipsn32__) || defined(__mips64__)) && defined(_MIPSEB)) || defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
+#if defined(__m68k__) || ((defined(__mipsn32__) || defined(__mips64__)) && defined(_MIPSEB)) || defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
 /* big endian -> small args < 1 word are adjusted to the right */
 #define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
   __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
@@ -761,11 +772,11 @@ typedef __va_alist* va_alist;
 /* `long long's are passed embedded on the arg stack. */
 #define va_arg_longlong(LIST)	__va_arg_longlong(LIST,long long)
 #define va_arg_ulonglong(LIST)	__va_arg_longlong(LIST,unsigned long long)
-#if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
+#if defined(__i386__) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
 /* `long long's are (at most) word-aligned. */
 #define __va_arg_longlong(LIST,TYPE)	__va_arg(LIST,TYPE)
 #endif
-#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__)
+#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__ARMEL__)
 /* `long long's have alignment 8. */
 #define __va_arg_longlong(LIST,TYPE)					\
   ((LIST)->aptr = (((LIST)->aptr+__VA_alignof(TYPE)-1) & -(long)__VA_alignof(TYPE)), \
@@ -791,10 +802,10 @@ typedef __va_alist* va_alist;
 
 /* Floating point arguments. */
 
-#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
+#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__alpha__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
 #define __va_align_double(LIST)
 #endif
-#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) || defined(__m88k__)
+#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) || defined(__m88k__) || defined(__ARMEL__)
 /* __VA_alignof(double) > sizeof(__vaword) */
 #define __va_align_double(LIST)  \
   (LIST)->aptr = ((LIST)->aptr + sizeof(double)-1) & -(long)sizeof(double),
diff --git a/m4/general.m4 b/m4/general.m4
index 7a96bd9..f1eaa15 100644
--- a/m4/general.m4
+++ b/m4/general.m4
@@ -70,6 +70,12 @@ changequote(,)dnl
     ;;
   arm* )
     host_cpu_abi=arm
+    # check for armel
+    if which dpkg-architecture > /dev/null; then
+      if dpkg-architecture -iarmel; then
+        host_cpu_abi=armel
+      fi
+    fi
     ;;
 changequote([,])dnl
   mips* )
diff --git a/trampoline/Makefile.devel b/trampoline/Makefile.devel
index 8a52ca6..eea6a4f 100644
--- a/trampoline/Makefile.devel
+++ b/trampoline/Makefile.devel
@@ -90,6 +90,9 @@ cache-powerpc-macos.s : cache-powerpc.c
 cache-convex.s : cache-convex.c
 	$(GCC) -V 2.6.3 -b convex-c2 $(GCCFLAGS) -D__convex__ -S $< -o $@
 
+cache-armel.s : cache-armel.c
+	$(GCC) $(GCCFLAGS)  -fomit-frame-pointer -S cache-armel.c -o cache-armel.s
+
 trampoline.man : trampoline.3
 	$(ROFF_MAN) trampoline.3 > trampoline.man
 
diff --git a/trampoline/Makefile.in b/trampoline/Makefile.in
index e650752..2499568 100644
--- a/trampoline/Makefile.in
+++ b/trampoline/Makefile.in
@@ -95,6 +95,12 @@ cache-alpha.o : $(srcdir)/cache-alpha.s
 cache-hppa.o : $(srcdir)/cache-hppa.s
 	$(CC) @GCC_X_NONE@ -c $(srcdir)/cache-hppa.s
 
+cache-arm.o : $(srcdir)/cache-arm.s
+	$(CC) @GCC_X_NONE@ -c $(srcdir)/cache-arm.s
+
+cache-armel.o : $(srcdir)/cache-armel.s
+	$(CC) @GCC_X_NONE@ -c $(srcdir)/cache-armel.s
+
 cache-powerpc.o : $(srcdir)/cache-powerpc-sysv4.s $(srcdir)/cache-powerpc-macos.s
 	case "$(OS)" in \
 	  macos* | darwin*) syntax=macos;; \
diff --git a/trampoline/cache-armel.c b/trampoline/cache-armel.c
new file mode 100644
index 0000000..c3dd520
--- /dev/null
+++ b/trampoline/cache-armel.c
@@ -0,0 +1,19 @@
+/* Instruction cache flushing for arm */
+
+/*
+ * Copyright 1997 Bruno Haible, <bruno@clisp.org>
+ *
+ * This is free software distributed under the GNU General Public Licence
+ * described in the file COPYING. Contact the author if you don't have this
+ * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
+ * on this software.
+ */
+#include <linux/unistd.h>
+
+void __TR_clear_cache (char *first_addr, char *last_addr)
+{
+    register unsigned long _beg __asm ("a1") = first_addr;
+    register unsigned long _end __asm ("a2") = last_addr;
+    register unsigned long _flg __asm ("a3") = 0; 
+    __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
+}
diff --git a/trampoline/cache-armel.s b/trampoline/cache-armel.s
new file mode 100644
index 0000000..e0aaf43
--- /dev/null
+++ b/trampoline/cache-armel.s
@@ -0,0 +1,24 @@
+	.cpu arm10tdmi
+	.fpu softvfp
+	.file	"cache-armel.c"
+	.text
+	.align	2
+	.global	__TR_clear_cache
+	.type	__TR_clear_cache, %function
+__TR_clear_cache:
+	@ args = 0, pretend = 0, frame = 8
+	@ frame_needed = 0, uses_anonymous_args = 0
+	@ link register save eliminated.
+	sub	sp, sp, #8
+	@ lr needed for prologue
+	str	r0, [sp, #4]
+	str	r1, [sp, #0]
+	ldr	r0, [sp, #4]
+	ldr	r1, [sp, #0]
+	mov	r2, #0
+#APP
+	swi 0x9f0002
+	add	sp, sp, #8
+	bx	lr
+	.size	__TR_clear_cache, .-__TR_clear_cache
+	.ident	"GCC: (GNU) 3.4.4 (release) (CodeSourcery ARM 2005q3-2)"
diff --git a/trampoline/configure b/trampoline/configure
index cb9c33c..ae46077 100755
--- a/trampoline/configure
+++ b/trampoline/configure
@@ -3625,6 +3625,12 @@ case "$host_cpu" in
     ;;
   arm* )
     host_cpu_abi=arm
+    # check for armel
+    if which dpkg-architecture > /dev/null; then
+      if dpkg-architecture -iarmel; then
+        host_cpu_abi=armel
+      fi
+    fi
     ;;
   mips* )
     { $as_echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
@@ -6918,7 +6924,7 @@ if test ${host_cpu_abi} = powerpc; then
     *) ;;
   esac
 fi
-if test ${host_cpu_abi} = sparc -o ${host_cpu_abi} = sparc64 -o ${host_cpu_abi} = alpha -o ${host_cpu_abi} = hppa -o ${host_cpu_abi} = convex -o ${host_cpu_abi} = arm; then
+if test ${host_cpu_abi} = sparc -o ${host_cpu_abi} = sparc64 -o ${host_cpu_abi} = alpha -o ${host_cpu_abi} = hppa -o ${host_cpu_abi} = convex -o ${host_cpu_abi} = arm -o ${host_cpu_abi} = armel; then
   CPU_OBJECTS="$CPU_OBJECTS "'cache-$(CPU).o'
 fi
 if test ${host_cpu_abi} = powerpc; then
diff --git a/trampoline/configure.in b/trampoline/configure.in
index 33685a0..a92e7d3 100644
--- a/trampoline/configure.in
+++ b/trampoline/configure.in
@@ -30,7 +30,7 @@ if test ${host_cpu_abi} = powerpc; then
     *) ;;
   esac
 fi
-if test ${host_cpu_abi} = sparc -o ${host_cpu_abi} = sparc64 -o ${host_cpu_abi} = alpha -o ${host_cpu_abi} = hppa -o ${host_cpu_abi} = convex -o ${host_cpu_abi} = arm; then
+if test ${host_cpu_abi} = sparc -o ${host_cpu_abi} = sparc64 -o ${host_cpu_abi} = alpha -o ${host_cpu_abi} = hppa -o ${host_cpu_abi} = convex -o ${host_cpu_abi} = arm -o ${host_cpu_abi} = armel; then
   CPU_OBJECTS="$CPU_OBJECTS "'cache-$(CPU).o'
 fi
 if test ${host_cpu_abi} = powerpc; then
diff --git a/vacall/Makefile.devel b/vacall/Makefile.devel
index 0c94973..7ab3372 100644
--- a/vacall/Makefile.devel
+++ b/vacall/Makefile.devel
@@ -9,7 +9,7 @@ RM = rm -f
 SED = sed
 ROFF_MAN = groff -Tascii -mandoc
 
-all : vacall-i386-macro.S vacall-i386-msvc.c vacall-i386-mingw32.c vacall-m68k.mit.S vacall-m68k.mot.s vacall-mips.S vacall-mipsn32.S vacall-mips64.S vacall-sparc.S vacall-sparc64.S vacall-alpha.s vacall-hppa.s vacall-arm.S vacall-powerpc-aix.old.s vacall-powerpc-aix.new.s vacall-powerpc-sysv4.s vacall-powerpc-macos.s vacall-powerpc64.s vacall-m88k.s vacall-convex.s vacall-ia64.s vacall-x86_64.s vacall.man \
+all : vacall-i386-macro.S vacall-i386-msvc.c vacall-i386-mingw32.c vacall-m68k.mit.S vacall-m68k.mot.s vacall-mips.S vacall-mipsn32.S vacall-mips64.S vacall-sparc.S vacall-sparc64.S vacall-alpha.s vacall-hppa.s vacall-arm.S vacall-armel.s vacall-powerpc-aix.old.s vacall-powerpc-aix.new.s vacall-powerpc-sysv4.s vacall-powerpc-macos.s vacall-powerpc64.s vacall-m88k.s vacall-convex.s vacall-ia64.s vacall-x86_64.s vacall.man \
       vacall.h.msvc config.h.msvc vacall.h.mingw32 config.h.mingw32
 
 vacall-i386-macro.S : vacall-i386.c vacall.h.in asmi386.sh
@@ -69,6 +69,9 @@ vacall-arm.S : vacall-arm.c vacall.h.in asmarm.sh
 	(echo '#include "asmarm.h"' ; ./asmarm.sh < vacall-arm.s) > vacall-arm.S
 	$(RM) vacall-arm.s
 
+vacall-armel.s : vacall-armel.c vacall.h.in
+	$(GCC) $(GCCFLAGS) -D__arm__ -D__ARMEL__ -DHAVE_LONG_LONG -fomit-frame-pointer -S vacall-armel.c -o vacall-armel.s
+
 vacall-powerpc-aix.old.s : vacall-powerpc.c vacall.h.in
 	$(GCC) -V 2.95.2 -b rs6000 -mno-power -mno-power2 -mno-powerpc -mold-mnemonics $(GCCFLAGS) -D__powerpc__ -S vacall-powerpc.c -o vacall-powerpc-aix.old.s
 
diff --git a/vacall/Makefile.in b/vacall/Makefile.in
index 325755f..42a5ebe 100644
--- a/vacall/Makefile.in
+++ b/vacall/Makefile.in
@@ -108,6 +108,9 @@ vacall-arm.o : vacall-arm.s
 vacall-arm.s : $(srcdir)/vacall-arm.S
 	$(CPP) $(ASPFLAGS) $(srcdir)/vacall-arm.S | grep -v '^ *#line' | grep -v '^#' | sed -e 's,% ,%,g' -e 's,//,@,g' -e 's,\$$,#,g' > vacall-arm.s
 
+vacall-armel.o : vacall-armel.s
+	$(CC) @GCC_X_NONE@ -c vacall-armel.s
+
 vacall-powerpc.o : $(srcdir)/vacall-powerpc-aix.old.s $(srcdir)/vacall-powerpc-aix.new.s $(srcdir)/vacall-powerpc-sysv4.s $(srcdir)/vacall-powerpc-linux.s $(srcdir)/vacall-powerpc-macos.s
 	case "$(OS)" in \
 	  aix3*) syntax=aix.old;; \
diff --git a/vacall/configure b/vacall/configure
index c1a511a..aafaf46 100755
--- a/vacall/configure
+++ b/vacall/configure
@@ -3601,6 +3601,12 @@ case "$host_cpu" in
     ;;
   arm* )
     host_cpu_abi=arm
+    # check for armel
+    if which dpkg-architecture > /dev/null; then
+      if dpkg-architecture -iarmel; then
+        host_cpu_abi=armel
+      fi
+    fi
     ;;
   mips* )
     { $as_echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
diff --git a/vacall/tests.c b/vacall/tests.c
index c2cdd2c..877f6c6 100644
--- a/vacall/tests.c
+++ b/vacall/tests.c
@@ -9,6 +9,7 @@
  * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
  * on this software.
  */
+#include "config.h"
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/vacall/vacall-armel.c b/vacall/vacall-armel.c
new file mode 100644
index 0000000..dd81cba
--- /dev/null
+++ b/vacall/vacall-armel.c
@@ -0,0 +1,134 @@
+/* vacall function for arm CPU */
+
+/*
+ * Copyright 1995-2004 Bruno Haible, <bruno@clisp.org>
+ *
+ * This is free software distributed under the GNU General Public Licence
+ * described in the file COPYING. Contact the author if you don't have this
+ * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
+ * on this software.
+ */
+
+#ifndef REENTRANT
+#include "vacall.h.in"
+#else /* REENTRANT */
+#include "vacall_r.h.in"
+#endif
+
+#ifdef REENTRANT
+#define __vacall __vacall_r
+register struct { void (*vacall_function) (void*,va_alist); void* arg; }
+         *		env	__asm__("r12");
+#endif
+
+/* armel have only softvfp which uses generic registers */
+register __vaword	iret	__asm__("r0");
+register __vaword	iret2	__asm__("r1");
+register float		fret	__asm__("r0");
+register __vaword	dret1	__asm__("r0");
+register __vaword	dret2	__asm__("r1");
+
+void /* the return type is variable, not void! */
+__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
+          __vaword firstword)
+{
+  struct { long retaddr, sav1, sav2, sav3, sav4, arg1, arg2, arg3, arg4; } args;
+  __va_alist list;
+  /* MAGIC ALERT!
+   * This is the last struct on the stack, so that
+   * &args + 1 == &return_address == &firstword - 1.
+   * Look at the assembly code to convince yourself.
+   */
+  /* Move the arguments passed in registers to their stack locations. */
+  args.retaddr = (&firstword)[-1]; /* save the return address and saved registers */
+  args.sav1 = (&firstword)[-2];
+  args.sav2 = (&firstword)[-3];
+  args.sav3 = (&firstword)[-4];
+  args.sav4 = (&firstword)[-5];
+  args.arg1 = word1;
+  args.arg2 = word2;
+  args.arg3 = word3;
+  args.arg4 = word4;
+  (&firstword)[-4] = args.arg1;
+  (&firstword)[-3] = args.arg2;
+  (&firstword)[-2] = args.arg3;
+  (&firstword)[-1] = args.arg4;
+  /* Prepare the va_alist. */
+  list.flags = 0;
+  list.aptr = (long)(&firstword - 4);
+  list.raddr = (void*)0;
+  list.rtype = __VAvoid;
+  /* Call vacall_function. The macros do all the rest. */
+#ifndef REENTRANT
+  (*vacall_function) (&list);
+#else /* REENTRANT */
+  (*env->vacall_function) (env->arg,&list);
+#endif
+  /* Put return value into proper register. */
+  if (list.rtype == __VAvoid) {
+  } else
+  if (list.rtype == __VAchar) {
+    iret = list.tmp._char;
+  } else
+  if (list.rtype == __VAschar) {
+    iret = list.tmp._schar;
+  } else
+  if (list.rtype == __VAuchar) {
+    iret = list.tmp._uchar;
+  } else
+  if (list.rtype == __VAshort) {
+    iret = list.tmp._short;
+  } else
+  if (list.rtype == __VAushort) {
+    iret = list.tmp._ushort;
+  } else
+  if (list.rtype == __VAint) {
+    iret = list.tmp._int;
+  } else
+  if (list.rtype == __VAuint) {
+    iret = list.tmp._uint;
+  } else
+  if (list.rtype == __VAlong) {
+    iret = list.tmp._long;
+  } else
+  if (list.rtype == __VAulong) {
+    iret = list.tmp._ulong;
+  } else
+  if (list.rtype == __VAlonglong || list.rtype == __VAulonglong) {
+    iret  = ((__vaword *) &list.tmp._longlong)[0];
+    iret2 = ((__vaword *) &list.tmp._longlong)[1];
+  } else
+  if (list.rtype == __VAfloat) {
+    fret = list.tmp._float;
+  } else
+  if (list.rtype == __VAdouble) {
+      dret1 = ((__vaword *) &list.tmp._double)[0];
+      dret2 = ((__vaword *) &list.tmp._double)[1];
+  } else
+  if (list.rtype == __VAvoidp) {
+    iret = (long)list.tmp._ptr;
+  } else
+  if (list.rtype == __VAstruct) {
+    /* NB: On arm, all structure sizes are divisible by 4. */
+    if (list.flags & __VA_PCC_STRUCT_RETURN) {
+      /* pcc struct return convention */
+      iret = (long) list.raddr;
+    } else {
+      /* normal struct return convention */
+      if (list.flags & __VA_REGISTER_STRUCT_RETURN) {
+        if (list.rsize == sizeof(char)) { /* can't occur */
+          iret = *(unsigned char *) list.raddr;
+        } else
+        if (list.rsize == sizeof(short)) { /* can't occur */
+          iret = *(unsigned short *) list.raddr;
+        } else
+          iret = *(unsigned int *) list.raddr; /* struct of size 3 :) */
+      }
+    }
+  }
+  (&firstword)[-1] = args.retaddr; /* restore the return address and saved registers */
+  (&firstword)[-2] = args.sav1;
+  (&firstword)[-3] = args.sav2;
+  (&firstword)[-4] = args.sav3;
+  (&firstword)[-5] = args.sav4;
+}
diff --git a/vacall/vacall-armel.s b/vacall/vacall-armel.s
new file mode 100644
index 0000000..73f42f2
--- /dev/null
+++ b/vacall/vacall-armel.s
@@ -0,0 +1,124 @@
+	.cpu arm10tdmi
+	.fpu softvfp
+	.file	"vacall-armel.c"
+	.text
+	.align	2
+	.global	__vacall
+	.type	__vacall, %function
+__vacall:
+	@ args = 4, pretend = 0, frame = 72
+	@ frame_needed = 0, uses_anonymous_args = 0
+	stmfd	sp!, {r4, r5, r6, r7, lr}
+	sub	sp, sp, #76
+	add	r6, sp, #96
+	ldr	lr, [r6, #-4]
+	ldr	ip, [sp, #88]
+	str	lr, [sp, #32]
+	ldr	lr, [sp, #84]
+	str	ip, [sp, #36]
+	ldr	ip, [sp, #80]
+	str	lr, [sp, #40]
+	ldr	lr, [sp, #76]
+	mov	r4, #0
+	str	ip, [sp, #44]
+	add	ip, sp, #80
+	str	r0, [sp, #80]
+	str	lr, [sp, #48]
+	str	r1, [sp, #84]
+	str	r2, [sp, #88]
+	mov	r7, r0
+	str	r3, [r6, #-4]
+	str	r4, [sp, #12]
+	str	ip, [sp, #4]
+	str	r0, [sp, #52]
+	str	r3, [sp, #64]
+	str	r1, [sp, #56]
+	str	r2, [sp, #60]
+	str	r4, [sp, #0]
+	str	r4, [sp, #8]
+	mov	r0, sp
+	ldr	r3, .L42
+	mov	r5, r1
+	mov	lr, pc
+	ldr	pc, [r3, #0]
+	ldr	ip, [sp, #12]
+	cmp	ip, r4
+	beq	.L3
+	cmp	ip, #1
+	beq	.L40
+	cmp	ip, #2
+	ldreqsb	r0, [sp, #24]
+	beq	.L3
+	cmp	ip, #3
+	beq	.L40
+	cmp	ip, #4
+	ldreqsh	r0, [sp, #24]
+	beq	.L3
+	cmp	ip, #5
+	ldreqh	r0, [sp, #24]
+	beq	.L3
+	cmp	ip, #6
+	beq	.L39
+	cmp	ip, #7
+	beq	.L39
+	cmp	ip, #8
+	beq	.L39
+	cmp	ip, #9
+	beq	.L39
+	sub	r3, ip, #10
+	cmp	r3, #1
+	bls	.L38
+	cmp	ip, #12
+	ldreq	r0, [sp, #24]	@ float
+	beq	.L3
+	cmp	ip, #13
+	beq	.L38
+	cmp	ip, #14
+	beq	.L39
+	cmp	ip, #15
+	bne	.L3
+	ldr	r3, [sp, #0]
+	tst	r3, #1
+	ldrne	r0, [sp, #8]
+	bne	.L3
+	tst	r3, #1024
+	beq	.L3
+	ldr	r3, [sp, #16]
+	cmp	r3, #1
+	ldreq	r3, [sp, #8]
+	ldreqb	r0, [r3, #0]	@ zero_extendqisi2
+	beq	.L3
+	cmp	r3, #2
+	ldreq	r3, [sp, #8]
+	ldrne	r3, [sp, #8]
+	ldreqh	r0, [r3, #0]
+	ldrne	r0, [r3, #0]
+.L3:
+	ldr	r3, [sp, #32]
+	str	r3, [r6, #-4]
+	ldr	r2, [sp, #48]
+	str	r2, [r6, #-20]
+	ldr	r3, [sp, #36]
+	str	r3, [r6, #-8]
+	ldr	r2, [sp, #40]
+	str	r2, [r6, #-12]
+	ldr	r3, [sp, #44]
+	str	r3, [r6, #-16]
+	add	sp, sp, #76
+	ldmfd	sp!, {r4, r5, r6, r7, pc}
+.L40:
+	ldrb	r0, [sp, #24]	@ zero_extendqisi2
+	b	.L3
+.L39:
+	ldr	r0, [sp, #24]
+	b	.L3
+.L38:
+	ldr	r0, [sp, #24]
+	ldr	r1, [sp, #28]
+	b	.L3
+.L43:
+	.align	2
+.L42:
+	.word	vacall_function
+	.size	__vacall, .-__vacall
+	.ident	"GCC: (GNU) 3.4.4 (release) (CodeSourcery ARM 2005q3-2)"
diff --git a/vacall/vacall.h.in b/vacall/vacall.h.in
index 17f19eb..03e2a82 100644
--- a/vacall/vacall.h.in
+++ b/vacall/vacall.h.in
@@ -197,7 +197,7 @@ enum __VA_alist_flags
 #if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */
 				  __VA_PCC_STRUCT_RETURN,
 #else
-#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) /* defined through configure, see above */
+#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) || defined(__ARMEL__)/* defined through configure, see above */
 				  __VA_SMALL_STRUCT_RETURN |
 #endif
 #if defined(__GNUC__)
@@ -472,7 +472,7 @@ typedef __va_alist* va_alist;
 #define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
   ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 #endif
-#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
+#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
 #define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4		\
    || ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE)				\
@@ -484,6 +484,17 @@ typedef __va_alist* va_alist;
 #define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
   ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 #endif
+
+#if defined(__ARMEL__)
+/* structs of size 3 also will be returned in register */
+#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
+    ((TYPE_SIZE) <= 4)
+/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
+ * and the struct will actually be returned in registers.
+ */
+#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
+  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
+#endif
 #if defined(__alpha__)
 #define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8	\
@@ -704,12 +715,12 @@ typedef __va_alist* va_alist;
    (LIST)->aptr + ((-(TYPE_SIZE)) & 3)					\
   )
 #endif
-#if defined(__i386__) || defined(__alpha__) || defined(__ia64__)
+#if defined(__i386__) || defined(__alpha__) || defined(__ia64__) || defined(__ARMEL__)
 /* little endian -> small args < 1 word are adjusted to the left */
 #define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
   __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
 #endif
-#if defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
+#if defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
 /* big endian -> small args < 1 word are adjusted to the right */
 #define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
   __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
@@ -756,11 +767,11 @@ typedef __va_alist* va_alist;
 /* `long long's are passed embedded on the arg stack. */
 #define va_arg_longlong(LIST)	__va_arg_longlong(LIST,long long)
 #define va_arg_ulonglong(LIST)	__va_arg_longlong(LIST,unsigned long long)
-#if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
+#if defined(__i386__) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
 /* `long long's are (at most) word-aligned. */
 #define __va_arg_longlong(LIST,TYPE)	__va_arg(LIST,TYPE)
 #endif
-#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__)
+#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__ARMEL__)
 /* `long long's have alignment 8. */
 #define __va_arg_longlong(LIST,TYPE)					\
   ((LIST)->aptr = (((LIST)->aptr+__VA_alignof(TYPE)-1) & -(long)__VA_alignof(TYPE)), \
@@ -786,10 +797,10 @@ typedef __va_alist* va_alist;
 
 /* Floating point arguments. */
 
-#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
+#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__alpha__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
 #define __va_align_double(LIST)
 #endif
-#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) || defined(__m88k__)
+#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) || defined(__m88k__) || defined(__ARMEL__)
 /* __VA_alignof(double) > sizeof(__vaword) */
 #define __va_align_double(LIST)  \
   (LIST)->aptr = ((LIST)->aptr + sizeof(double)-1) & -(long)sizeof(double),
