summaryrefslogtreecommitdiff
path: root/byterun/ints.c
diff options
context:
space:
mode:
authorFabrice Le Fessant <Fabrice.Le_fessant@inria.fr>2012-11-29 09:55:00 +0000
committerFabrice Le Fessant <Fabrice.Le_fessant@inria.fr>2012-11-29 09:55:00 +0000
commit89bdc103505183125f7bf759c27302a34757af9b (patch)
treeec9ec9c519d08f8ce9e515e0d10a21dac83bb63f /byterun/ints.c
parentf80d01e968bf899aaa36882840eddc11ce428f94 (diff)
downloadocaml-89bdc103505183125f7bf759c27302a34757af9b.tar.gz
PR#5774: Add bswap primitives for amd64
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@13106 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'byterun/ints.c')
-rw-r--r--byterun/ints.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/byterun/ints.c b/byterun/ints.c
index f8491b1df7..ffeac81521 100644
--- a/byterun/ints.c
+++ b/byterun/ints.c
@@ -114,6 +114,19 @@ intnat caml_safe_mod(intnat p, intnat q)
}
#endif
+CAMLprim value caml_bswap16_direct(value x)
+{
+ return ((((x & 0x00FF) << 8) |
+ ((x & 0xFF00) >> 8)));
+}
+
+CAMLprim value caml_bswap16(value v)
+{
+ intnat x = Int_val(v);
+ return (Val_int ((((x & 0x00FF) << 8) |
+ ((x & 0xFF00) >> 8))));
+}
+
/* Tagged integers */
CAMLprim value caml_int_compare(value v1, value v2)
@@ -296,6 +309,20 @@ CAMLprim value caml_int32_shift_right(value v1, value v2)
CAMLprim value caml_int32_shift_right_unsigned(value v1, value v2)
{ return caml_copy_int32((uint32)Int32_val(v1) >> Int_val(v2)); }
+static int32 swap32(int32 x)
+{
+ return (((x & 0x000000FF) << 24) |
+ ((x & 0x0000FF00) << 8) |
+ ((x & 0x00FF0000) >> 8) |
+ ((x & 0xFF000000) >> 24));
+}
+
+CAMLprim value caml_int32_direct_bswap(value v)
+{ return swap32(v); }
+
+CAMLprim value caml_int32_bswap(value v)
+{ return caml_copy_int32(swap32(Int32_val(v))); }
+
CAMLprim value caml_int32_of_int(value v)
{ return caml_copy_int32(Long_val(v)); }
@@ -486,6 +513,26 @@ CAMLprim value caml_int64_shift_right(value v1, value v2)
CAMLprim value caml_int64_shift_right_unsigned(value v1, value v2)
{ return caml_copy_int64(I64_lsr(Int64_val(v1), Int_val(v2))); }
+#ifdef ARCH_SIXTYFOUR
+static value swap64(value x)
+{
+ return (((((x) & 0x00000000000000FF) << 56) |
+ (((x) & 0x000000000000FF00) << 40) |
+ (((x) & 0x0000000000FF0000) << 24) |
+ (((x) & 0x00000000FF000000) << 8) |
+ (((x) & 0x000000FF00000000) >> 8) |
+ (((x) & 0x0000FF0000000000) >> 24) |
+ (((x) & 0x00FF000000000000) >> 40) |
+ (((x) & 0xFF00000000000000) >> 56)));
+}
+
+CAMLprim value caml_int64_direct_bswap(value v)
+{ return swap64(v); }
+#endif
+
+CAMLprim value caml_int64_bswap(value v)
+{ return caml_copy_int64(I64_bswap(Int64_val(v))); }
+
CAMLprim value caml_int64_of_int(value v)
{ return caml_copy_int64(I64_of_intnat(Long_val(v))); }
@@ -738,6 +785,24 @@ CAMLprim value caml_nativeint_shift_right(value v1, value v2)
CAMLprim value caml_nativeint_shift_right_unsigned(value v1, value v2)
{ return caml_copy_nativeint((uintnat)Nativeint_val(v1) >> Int_val(v2)); }
+CAMLprim value caml_nativeint_direct_bswap(value v)
+{
+#ifdef ARCH_SIXTYFOUR
+ return swap64(v);
+#else
+ return swap32(v);
+#endif
+}
+
+CAMLprim value caml_nativeint_bswap(value v)
+{
+#ifdef ARCH_SIXTYFOUR
+ return caml_copy_nativeint(swap64(Nativeint_val(v)));
+#else
+ return caml_copy_nativeint(swap32(Nativeint_val(v)));
+#endif
+}
+
CAMLprim value caml_nativeint_of_int(value v)
{ return caml_copy_nativeint(Long_val(v)); }