summaryrefslogtreecommitdiff
path: root/libguile/vm-i-scheme.c
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2013-08-01 20:31:21 -0400
committerMark H Weaver <mhw@netris.org>2013-08-04 04:16:57 -0400
commitf91a1864c365abef807714ed0b664849f099152c (patch)
tree098b81981fe2218a0e24b0e61d87bd11ba5110e4 /libguile/vm-i-scheme.c
parentb2df1682df9edeb84acf7aacbb97d038aea7e501 (diff)
downloadguile-f91a1864c365abef807714ed0b664849f099152c.tar.gz
VM: Implement ASM_ADD, ASM_SUB, and ASM_MUL for ARM processors.
* libguile/vm-i-scheme.c (ASM_ADD, ASM_SUB, ASM_MUL): Implement for ARM.
Diffstat (limited to 'libguile/vm-i-scheme.c')
-rw-r--r--libguile/vm-i-scheme.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/libguile/vm-i-scheme.c b/libguile/vm-i-scheme.c
index d459e3e1f..a703aed1d 100644
--- a/libguile/vm-i-scheme.c
+++ b/libguile/vm-i-scheme.c
@@ -309,6 +309,52 @@ VM_DEFINE_FUNCTION (149, ge, "ge?", 2)
#endif
+#if SCM_GNUC_PREREQ (4, 5) && defined __arm__
+
+# define ASM_ADD(x, y) \
+ if (SCM_LIKELY (SCM_I_INUMP (x) && SCM_I_INUMP (y))) \
+ { \
+ asm volatile goto ("adds r0, %0, %1; bvs %l[slow_add]; " \
+ "str r0, [%[vsp]]\n" \
+ : /* no outputs */ \
+ : "r" (x), "r" (y - scm_tc2_int), \
+ [vsp] "r" (sp) \
+ : "r0", "memory", "cc" \
+ : slow_add); \
+ NEXT; \
+ } \
+ slow_add: \
+ do { } while (0)
+
+# define ASM_SUB(x, y) \
+ if (SCM_LIKELY (SCM_I_INUMP (x) && SCM_I_INUMP (y))) \
+ { \
+ asm volatile goto ("subs r0, %0, %1; bvs %l[slow_sub]; " \
+ "str r0, [%[vsp]]\n" \
+ : /* no outputs */ \
+ : "r" (x), "r" (y - scm_tc2_int), \
+ [vsp] "r" (sp) \
+ : "r0", "memory", "cc" \
+ : slow_sub); \
+ NEXT; \
+ } \
+ slow_sub: \
+ do { } while (0)
+
+# define ASM_MUL(x, y) \
+ if (SCM_LIKELY (SCM_I_INUMP (x) && SCM_I_INUMP (y))) \
+ { \
+ scm_t_signed_bits rlo, rhi; \
+ asm ("smull %0, %1, %2, %3\n" \
+ : "=r" (rlo), "=r" (rhi) \
+ : "r" (SCM_UNPACK (x) - scm_tc2_int), \
+ "r" (SCM_I_INUM (y))); \
+ if (SCM_LIKELY (SCM_SRS (rlo, 31) == rhi)) \
+ RETURN (SCM_PACK (rlo + scm_tc2_int)); \
+ } \
+ do { } while (0)
+
+#endif
VM_DEFINE_FUNCTION (150, add, "add", 2)
{