diff options
author | Mark H Weaver <mhw@netris.org> | 2013-08-01 20:31:21 -0400 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2013-08-04 04:16:57 -0400 |
commit | f91a1864c365abef807714ed0b664849f099152c (patch) | |
tree | 098b81981fe2218a0e24b0e61d87bd11ba5110e4 /libguile/vm-i-scheme.c | |
parent | b2df1682df9edeb84acf7aacbb97d038aea7e501 (diff) | |
download | guile-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.c | 46 |
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) { |