diff --git a/avcall/Makefile.devel b/avcall/Makefile.devel
index a125a15..7602d34 100644
--- a/avcall/Makefile.devel
+++ b/avcall/Makefile.devel
@@ -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 asmarmel.sh
+	$(GCC) $(GCCFLAGS) -D__arm__ -S avcall-arm.c -o avcall-armel.s
+	(echo '#include "asmarm.h"' ; ./asmarmel.sh < 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 f954cb4..6e96a49 100644
--- a/avcall/Makefile.in
+++ b/avcall/Makefile.in
@@ -116,6 +116,9 @@ 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.c
+	$(LIBTOOL_COMPILE) $(CC) $(CFLAGS) -fomit-frame-pointer -DHAVE_LONG_LONG -D__armel__ -c avcall-armel.c
+
 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;; \
@@ -222,7 +225,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/asmarmel.sh b/avcall/asmarmel.sh
new file mode 100755
index 0000000..c453eff
--- /dev/null
+++ b/avcall/asmarmel.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+# Translate the assembler syntax of arm assembler programs
+# Usage: asmarm < riscix-asm-file > portable-asm-file
+# The portable-asm-file has to be
+#   1. preprocessed,
+#   2. grep -v '^ *#line' | grep -v '^#'
+#   3. sed -e 's,% ,%,g' -e 's,//,@,g' -e 's,\$,#,g'
+cat
\ No newline at end of file
diff --git a/avcall/avcall-armel.S b/avcall/avcall-armel.S
new file mode 100644
index 0000000..ffc7a47
--- /dev/null
+++ b/avcall/avcall-armel.S
@@ -0,0 +1,150 @@
+#include "asmarm.h"
+	.cpu arm10tdmi
+	.fpu softvfp
+	.file	"avcall-arm.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
+	ldreq	r2, [r4, #8]
+	ldreq	r3, [lr, #0]
+	streq	r3, [r2, #0]
+	beq	.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..691e1f7
--- /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)) {
+        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)) { /* structs of size 3 also returned in register */
+          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 9be599f..0b077f6 100644
--- a/avcall/avcall.h.in
+++ b/avcall/avcall.h.in
@@ -538,7 +538,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)				\
@@ -550,6 +550,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	\
@@ -745,11 +753,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__)
@@ -796,6 +811,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)				\
@@ -804,6 +830,7 @@ typedef struct
      (LIST).aptr[-2] = (LIST).tmp.words[0],				\
      (LIST).aptr[-1] = (LIST).tmp.words[1],				\
      0))
+#endif
 
 #endif
 
@@ -1108,14 +1135,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__)
+#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__armel__)
 #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)))\
@@ -1256,7 +1283,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 ff51369..8b0d0a7 100755
--- a/avcall/configure
+++ b/avcall/configure
@@ -3709,7 +3709,14 @@ case "$host_cpu" in
     host_cpu_abi=convex
     ;;
   arm* )
-    host_cpu_abi=arm
+        host_cpu_abi=arm
+        # check for armel
+        if which dpkg-architecture > /dev/null; then
+            if dpkg-architecture -iarmel; then
+                host_cpu_abi=armel
+                CFLAGS="$CFLAGS -D__armel__ -D__arm__"
+            fi
+        fi
     ;;
   mips* )
     { echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
diff --git a/callback/configure b/callback/configure
index aea7872..2946a09 100755
--- a/callback/configure
+++ b/callback/configure
@@ -3689,7 +3689,14 @@ case "$host_cpu" in
     host_cpu_abi=convex
     ;;
   arm* )
-    host_cpu_abi=arm
+        host_cpu_abi=arm
+        # check for armel
+        if which dpkg-architecture > /dev/null; then
+            if dpkg-architecture -iarmel; then
+                host_cpu_abi=armel
+                CFLAGS="$CFLAGS -D__armel__ -D__arm__"
+            fi
+        fi
     ;;
   mips* )
     { echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
diff --git a/callback/trampoline_r/cache-arm.c b/callback/trampoline_r/cache-arm.c
index 73b320c..6205fe5 100644
--- a/callback/trampoline_r/cache-arm.c
+++ b/callback/trampoline_r/cache-arm.c
@@ -12,5 +12,8 @@
 
 void __TR_clear_cache (char *first_addr, char *last_addr)
 {
-  asm volatile ("swi %0" : : "i" (__ARM_NR_cacheflush));
+    register unsigned long _beg __asm ("r0") = first_addr;
+    register unsigned long _end __asm ("r1") = last_addr;
+    register unsigned long _flg __asm ("r2") = 0; 
+    __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
 }
diff --git a/callback/trampoline_r/cache-arm.s b/callback/trampoline_r/cache-arm.s
index 2d217e3..ddc81fb 100644
--- a/callback/trampoline_r/cache-arm.s
+++ b/callback/trampoline_r/cache-arm.s
@@ -1,3 +1,5 @@
+	.cpu arm10tdmi
+	.fpu softvfp
 	.file	"cache-arm.c"
 	.text
 	.align	2
@@ -8,8 +10,9 @@ __TR_clear_cache:
 	@ frame_needed = 0, uses_anonymous_args = 0
 	@ link register save eliminated.
 	@ lr needed for prologue
+	mov	r2, #0
 #APP
-	swi #10420226
-	mov	pc, lr
+	swi 0x9f0002
+	bx	lr
 	.size	__TR_clear_cache, .-__TR_clear_cache
-	.ident	"GCC: (GNU) 3.4.0 (Debian 20040516)"
+	.ident	"GCC: (GNU) 3.4.4 (release) (CodeSourcery ARM 2005q3-2)"
diff --git a/callback/trampoline_r/trampoline.c b/callback/trampoline_r/trampoline.c
index 5e5311b..e77091f 100644
--- a/callback/trampoline_r/trampoline.c
+++ b/callback/trampoline_r/trampoline.c
@@ -766,8 +766,8 @@ __TR_function alloc_trampoline_r (__TR_function address, void* data0, void* data
     ((long *) function)[3] = (long) address;
   }
 #define is_tramp(function)  \
-  ((long *) function)[0] == 0xE28FC004 && \
-  ((long *) function)[1] == 0xE51FF004
+  ((long *) function)[0] == 0xE28FC008 && \
+  ((long *) function)[1] == 0xE59FF000
 #define tramp_address(function)  \
   ((long *) function)[3]
 #define tramp_data(function)  \
diff --git a/callback/vacall_r/Makefile.devel b/callback/vacall_r/Makefile.devel
index d592fb0..1097821 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,11 @@ 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 asmarmel.sh
+	$(GCC) $(GCCFLAGS) -D__arm__ -S vacall-armel.c -o vacall-armel.s
+	(echo '#include "asmarm.h"' ; ./asmarmel.sh < vacall-armel.s) > vacall-armel.S
+	$(RM) 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 eb909e2..d6944bb 100644
--- a/callback/vacall_r/Makefile.in
+++ b/callback/vacall_r/Makefile.in
@@ -120,6 +120,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.c
+	$(LIBTOOL_COMPILE) $(CC) $(CFLAGS) -fomit-frame-pointer -DHAVE_LONG_LONG -c vacall-armel.c
+
 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;; \
@@ -204,7 +207,7 @@ mostlyclean : clean
 
 clean : force
 	$(RM) *.o *.lo *.a libvacall.* core
-	$(RM) vacall-i386.s vacall-sparc.s vacall-sparc64.s vacall-m68k.s vacall-mips.s vacall-mipsn32.s vacall-mips64.s vacall-arm.s
+	$(RM) vacall-i386.s vacall-sparc.s vacall-sparc64.s vacall-m68k.s vacall-mips.s vacall-mipsn32.s vacall-mips64.s vacall-arm.s vacall-armel.s
 	$(RM) -r .libs _libs
 
 distclean : clean
diff --git a/callback/vacall_r/asmarmel.sh b/callback/vacall_r/asmarmel.sh
new file mode 100755
index 0000000..c453eff
--- /dev/null
+++ b/callback/vacall_r/asmarmel.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+# Translate the assembler syntax of arm assembler programs
+# Usage: asmarm < riscix-asm-file > portable-asm-file
+# The portable-asm-file has to be
+#   1. preprocessed,
+#   2. grep -v '^ *#line' | grep -v '^#'
+#   3. sed -e 's,% ,%,g' -e 's,//,@,g' -e 's,\$,#,g'
+cat
\ No newline at end of file
diff --git a/callback/vacall_r/configure b/callback/vacall_r/configure
index a8c1976..d46ada4 100755
--- a/callback/vacall_r/configure
+++ b/callback/vacall_r/configure
@@ -3709,7 +3709,14 @@ case "$host_cpu" in
     host_cpu_abi=convex
     ;;
   arm* )
-    host_cpu_abi=arm
+        host_cpu_abi=arm
+        # check for armel
+        if which dpkg-architecture > /dev/null; then
+            if dpkg-architecture -iarmel; then
+                host_cpu_abi=armel
+                CFLAGS="$CFLAGS -D__armel__ -D__arm__ -DREENTRANT"
+            fi
+        fi
     ;;
   mips* )
     { echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
diff --git a/callback/vacall_r/vacall-armel.S b/callback/vacall_r/vacall-armel.S
new file mode 100644
index 0000000..7043a78
--- /dev/null
+++ b/callback/vacall_r/vacall-armel.S
@@ -0,0 +1,109 @@
+#include "asmarm.h"
+	.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 = 56
+	@ frame_needed = 0, uses_anonymous_args = 0
+	stmfd	sp!, {r4, r5, r6, lr}
+	sub	sp, sp, #56
+	add	r6, sp, #72
+	ldr	r4, [r6, #-4]
+	mov	lr, #0
+	str	r0, [sp, #56]
+	str	r1, [sp, #60]
+	str	lr, [sp, #8]
+	str	r4, [sp, #32]
+	str	r2, [sp, #64]
+	str	r3, [r6, #-4]
+	add	r3, sp, #56
+	str	lr, [sp, #12]
+	str	r3, [sp, #4]
+	str	lr, [sp, #0]
+	ldr	r0, [ip, #4]
+	mov	r1, sp
+	mov	lr, pc
+	ldr	pc, [ip, #0]
+	ldr	r5, [sp, #12]
+	cmp	r5, #0
+	beq	.L3
+	cmp	r5, #1
+	beq	.L43
+	cmp	r5, #2
+	ldreqsb	r0, [sp, #24]
+	beq	.L3
+	cmp	r5, #3
+	beq	.L43
+	cmp	r5, #4
+	ldreqsh	r0, [sp, #24]
+	beq	.L3
+	cmp	r5, #5
+	ldreqh	r0, [sp, #24]
+	beq	.L3
+	cmp	r5, #6
+	beq	.L42
+	cmp	r5, #7
+	beq	.L42
+	cmp	r5, #8
+	beq	.L42
+	cmp	r5, #9
+	beq	.L42
+	sub	r3, r5, #10
+	cmp	r3, #1
+	ldrls	r0, [sp, #24]
+	ldrls	r1, [sp, #28]
+	bls	.L3
+	cmp	r5, #12
+	ldreq	r0, [sp, #24]	@ float
+	beq	.L3
+	cmp	r5, #13
+	beq	.L45
+	cmp	r5, #14
+	beq	.L42
+	cmp	r5, #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]
+	ldreqh	r0, [r3, #0]
+	beq	.L3
+	cmp	r3, #4
+	ldreq	r3, [sp, #8]
+	beq	.L41
+	cmp	r3, #8
+	bne	.L3
+	ldr	r3, [sp, #8]
+	ldr	r1, [r3, #4]
+.L41:
+	ldr	r0, [r3, #0]
+.L3:
+	ldr	r3, [sp, #32]
+	str	r3, [r6, #-4]
+	add	sp, sp, #56
+	ldmfd	sp!, {r4, r5, r6, pc}
+.L43:
+	ldrb	r0, [sp, #24]	@ zero_extendqisi2
+	b	.L3
+.L42:
+	ldr	r0, [sp, #24]
+	b	.L3
+.L45:
+	add	r3, sp, #24
+	ldmia	r3, {r0-r1}
+	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-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_r.h.in b/callback/vacall_r/vacall_r.h.in
index befe44f..5b6bb8a 100644
--- a/callback/vacall_r/vacall_r.h.in
+++ b/callback/vacall_r/vacall_r.h.in
@@ -468,7 +468,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)				\
@@ -480,6 +480,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	\
@@ -700,12 +711,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(__mipsn32__) || defined(__mips64__)) && defined(_MIPSEL)) || 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(_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)
@@ -758,11 +769,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)), \
@@ -788,10 +799,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/trampoline/cache-arm.c b/trampoline/cache-arm.c
index 73b320c..c3dd520 100644
--- a/trampoline/cache-arm.c
+++ b/trampoline/cache-arm.c
@@ -12,5 +12,8 @@
 
 void __TR_clear_cache (char *first_addr, char *last_addr)
 {
-  asm volatile ("swi %0" : : "i" (__ARM_NR_cacheflush));
+    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/vacall/Makefile.devel b/vacall/Makefile.devel
index 86f4265..2ce46a3 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,11 @@ 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 asmarmel.sh
+	$(GCC) $(GCCFLAGS) -D__arm__ -S vacall-armel.c -o vacall-armel.s
+	(echo '#include "asmarm.h"' ; ./asmarm.sh < vacall-armel.s) > vacall-armel.S
+	$(RM) 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 95c5072..573953a 100644
--- a/vacall/Makefile.in
+++ b/vacall/Makefile.in
@@ -107,6 +107,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.c
+	$(CC) $(CFLAGS) -fomit-frame-pointer -DHAVE_LONG_LONG -c vacall-armel.c
+
 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;; \
@@ -206,7 +209,7 @@ mostlyclean : clean
 
 clean : force
 	$(RM) *.o *.a core
-	$(RM) vacall-i386.s vacall-sparc.s vacall-sparc64.s vacall-m68k.s vacall-mips.s vacall-mipsn32.s vacall-mips64.s vacall-arm.s
+	$(RM) vacall-i386.s vacall-sparc.s vacall-sparc64.s vacall-m68k.s vacall-mips.s vacall-mipsn32.s vacall-mips64.s vacall-arm.s vacall-armel.s
 	$(RM) minitests.o minitests.s minitests minitests.out
 	$(RM) tests.o tests.s tests tests.out
 
diff --git a/vacall/asmarmel.sh b/vacall/asmarmel.sh
new file mode 100755
index 0000000..c453eff
--- /dev/null
+++ b/vacall/asmarmel.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+# Translate the assembler syntax of arm assembler programs
+# Usage: asmarm < riscix-asm-file > portable-asm-file
+# The portable-asm-file has to be
+#   1. preprocessed,
+#   2. grep -v '^ *#line' | grep -v '^#'
+#   3. sed -e 's,% ,%,g' -e 's,//,@,g' -e 's,\$,#,g'
+cat
\ No newline at end of file
diff --git a/vacall/configure b/vacall/configure
index 6d82c2e..2e2fe0f 100755
--- a/vacall/configure
+++ b/vacall/configure
@@ -3515,7 +3515,14 @@ case "$host_cpu" in
     host_cpu_abi=convex
     ;;
   arm* )
-    host_cpu_abi=arm
+        host_cpu_abi=arm
+        # check for armel
+        if which dpkg-architecture > /dev/null; then
+            if dpkg-architecture -iarmel; then
+                host_cpu_abi=armel
+                CFLAGS="$CFLAGS -D__armel__ -D__arm__"
+            fi
+        fi
     ;;
   mips* )
     { echo "$as_me:$LINENO: checking for 64-bit MIPS" >&5
diff --git a/vacall/vacall-armel.S b/vacall/vacall-armel.S
new file mode 100644
index 0000000..882179f
--- /dev/null
+++ b/vacall/vacall-armel.S
@@ -0,0 +1,112 @@
+	.cpu arm10tdmi
+	.fpu softvfp
+	.file	"vacall-armel.c"
+	.text
+	.align	2
+	.global	__vacall
+	.type	__vacall, %function
+__vacall:
+	@ args = 4, pretend = 0, frame = 56
+	@ frame_needed = 0, uses_anonymous_args = 0
+	stmfd	sp!, {r4, r5, lr}
+	sub	sp, sp, #60
+	add	r5, sp, #72
+	ldr	lr, [r5, #-4]
+	mov	ip, #0
+	str	r0, [sp, #56]
+	str	lr, [sp, #32]
+	str	r2, [sp, #64]
+	str	r3, [r5, #-4]
+	add	r3, sp, #56
+	str	r3, [sp, #4]
+	str	ip, [sp, #12]
+	str	r1, [sp, #60]
+	str	ip, [sp, #0]
+	str	ip, [sp, #8]
+	mov	r0, sp
+	ldr	r3, .L46
+	mov	lr, pc
+	ldr	pc, [r3, #0]
+	ldr	r4, [sp, #12]
+	cmp	r4, #0
+	beq	.L3
+	cmp	r4, #1
+	beq	.L43
+	cmp	r4, #2
+	ldreqsb	r0, [sp, #24]
+	beq	.L3
+	cmp	r4, #3
+	beq	.L43
+	cmp	r4, #4
+	ldreqsh	r0, [sp, #24]
+	beq	.L3
+	cmp	r4, #5
+	ldreqh	r0, [sp, #24]
+	beq	.L3
+	cmp	r4, #6
+	beq	.L42
+	cmp	r4, #7
+	beq	.L42
+	cmp	r4, #8
+	beq	.L42
+	cmp	r4, #9
+	beq	.L42
+	sub	r3, r4, #10
+	cmp	r3, #1
+	ldrls	r0, [sp, #24]
+	ldrls	r1, [sp, #28]
+	bls	.L3
+	cmp	r4, #12
+	ldreq	r0, [sp, #24]	@ float
+	beq	.L3
+	cmp	r4, #13
+	beq	.L45
+	cmp	r4, #14
+	beq	.L42
+	cmp	r4, #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]
+	ldreqh	r0, [r3, #0]
+	beq	.L3
+	cmp	r3, #4
+	ldreq	r3, [sp, #8]
+	beq	.L41
+	cmp	r3, #8
+	bne	.L3
+	ldr	r3, [sp, #8]
+	ldr	r1, [r3, #4]
+.L41:
+	ldr	r0, [r3, #0]
+.L3:
+	ldr	r3, [sp, #32]
+	str	r3, [r5, #-4]
+	add	sp, sp, #60
+	ldmfd	sp!, {r4, r5, pc}
+.L43:
+	ldrb	r0, [sp, #24]	@ zero_extendqisi2
+	b	.L3
+.L42:
+	ldr	r0, [sp, #24]
+	b	.L3
+.L45:
+	add	r3, sp, #24
+	ldmia	r3, {r0-r1}
+	b	.L3
+.L47:
+	.align	2
+.L46:
+	.word	vacall_function
+	.size	__vacall, .-__vacall
+	.ident	"GCC: (GNU) 3.4.4 (release) (CodeSourcery ARM 2005q3-2)"
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.h.in b/vacall/vacall.h.in
index e545d40..b34adbb 100644
--- a/vacall/vacall.h.in
+++ b/vacall/vacall.h.in
@@ -469,7 +469,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)				\
@@ -481,6 +481,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	\
@@ -701,12 +712,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)
@@ -753,11 +764,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)), \
@@ -783,10 +794,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),
