summaryrefslogtreecommitdiff
path: root/libguile/intrinsics.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2018-05-01 07:00:37 +0200
committerAndy Wingo <wingo@pobox.com>2018-05-01 07:02:45 +0200
commit1532b570e583cdc07734300d29c9e00022ba8ffd (patch)
tree73feec984a25d0382ebceb0a5ea96d5f845043ac /libguile/intrinsics.c
parente014bf3fc5578e3e0d4a0964ae5b4e8cb5c633c9 (diff)
downloadguile-1532b570e583cdc07734300d29c9e00022ba8ffd.tar.gz
lsh, rsh etc are intrinsics
* libguile/intrinsics.c (lsh, rsh, lsh_immediate, rsh_immediate): New intrinsics. (scm_bootstrap_intrinsics): Wire up the intrinsics. * libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Add new intrinsics. * libguile/vm-engine.c (call-scm<-scm-u64): New intrinsic caller. (lsh, rsh, lsh/immediate, rsh/immediate): Disable. * module/language/cps/reify-primitives.scm (compute-known-primitives): Add new intrinsics. * module/system/vm/assembler.scm: Adapt assemblers for new intrinsics.
Diffstat (limited to 'libguile/intrinsics.c')
-rw-r--r--libguile/intrinsics.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/libguile/intrinsics.c b/libguile/intrinsics.c
index 4395148af..75a70fa3a 100644
--- a/libguile/intrinsics.c
+++ b/libguile/intrinsics.c
@@ -162,6 +162,47 @@ pop_dynamic_state (scm_i_thread *thread)
thread->dynamic_state);
}
+static SCM
+lsh (SCM a, scm_t_uint64 b)
+{
+ if (SCM_LIKELY (SCM_I_INUMP (a))
+ && b < (scm_t_uint64) (SCM_I_FIXNUM_BIT - 1)
+ && ((scm_t_bits)
+ (SCM_SRS (SCM_I_INUM (a), (SCM_I_FIXNUM_BIT-1 - b)) + 1)
+ <= 1))
+ {
+ scm_t_signed_bits nn = SCM_I_INUM (a);
+ return SCM_I_MAKINUM (nn < 0 ? -(-nn << b) : (nn << b));
+ }
+ else
+ return scm_ash (a, scm_from_uint64 (b));
+}
+
+static SCM
+rsh (SCM a, scm_t_uint64 b)
+{
+ if (SCM_LIKELY (SCM_I_INUMP (a)))
+ {
+ if (b > (scm_t_uint64) (SCM_I_FIXNUM_BIT - 1))
+ b = SCM_I_FIXNUM_BIT - 1;
+ return SCM_I_MAKINUM (SCM_SRS (SCM_I_INUM (a), b));
+ }
+ else
+ return scm_ash (a, scm_difference (SCM_INUM0, scm_from_uint64 (b)));
+}
+
+static SCM
+lsh_immediate (SCM a, scm_t_uint8 b)
+{
+ return lsh (a, b);
+}
+
+static SCM
+rsh_immediate (SCM a, scm_t_uint8 b)
+{
+ return rsh (a, b);
+}
+
void
scm_bootstrap_intrinsics (void)
{
@@ -197,6 +238,10 @@ scm_bootstrap_intrinsics (void)
scm_vm_intrinsics.fluid_set_x = fluid_set_x;
scm_vm_intrinsics.push_dynamic_state = push_dynamic_state;
scm_vm_intrinsics.pop_dynamic_state = pop_dynamic_state;
+ scm_vm_intrinsics.lsh = lsh;
+ scm_vm_intrinsics.rsh = rsh;
+ scm_vm_intrinsics.lsh_immediate = lsh_immediate;
+ scm_vm_intrinsics.rsh_immediate = rsh_immediate;
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
"scm_init_intrinsics",