summaryrefslogtreecommitdiff
path: root/byterun
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
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')
-rw-r--r--byterun/int64_emul.h14
-rw-r--r--byterun/int64_native.h9
-rw-r--r--byterun/ints.c65
-rw-r--r--byterun/sys.c29
4 files changed, 117 insertions, 0 deletions
diff --git a/byterun/int64_emul.h b/byterun/int64_emul.h
index e9f5d85020..ba7904a4fe 100644
--- a/byterun/int64_emul.h
+++ b/byterun/int64_emul.h
@@ -270,4 +270,18 @@ static int64 I64_of_double(double f)
return res;
}
+static int64 I64_bswap(int64 x)
+{
+ int64 res;
+ res.h = (((x.l & 0x000000FF) << 24) |
+ ((x.l & 0x0000FF00) << 8) |
+ ((x.l & 0x00FF0000) >> 8) |
+ ((x.l & 0xFF000000) >> 24));
+ res.l = (((x.h & 0x000000FF) << 24) |
+ ((x.h & 0x0000FF00) << 8) |
+ ((x.h & 0x00FF0000) >> 8) |
+ ((x.h & 0xFF000000) >> 24));
+ return res;
+}
+
#endif /* CAML_INT64_EMUL_H */
diff --git a/byterun/int64_native.h b/byterun/int64_native.h
index 5e84dda61d..09b5d65e89 100644
--- a/byterun/int64_native.h
+++ b/byterun/int64_native.h
@@ -49,4 +49,13 @@
#define I64_to_double(x) ((double)(x))
#define I64_of_double(x) ((int64)(x))
+#define I64_bswap(x) ((((x) & 0x00000000000000FF) << 56) | \
+ (((x) & 0x000000000000FF00) << 40) | \
+ (((x) & 0x0000000000FF0000) << 24) | \
+ (((x) & 0x00000000FF000000) << 8) | \
+ (((x) & 0x000000FF00000000) >> 8) | \
+ (((x) & 0x0000FF0000000000) >> 24) | \
+ (((x) & 0x00FF000000000000) >> 40) | \
+ (((x) & 0xFF00000000000000) >> 56))
+
#endif /* CAML_INT64_NATIVE_H */
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)); }
diff --git a/byterun/sys.c b/byterun/sys.c
index 574a4ecb41..332887b138 100644
--- a/byterun/sys.c
+++ b/byterun/sys.c
@@ -334,6 +334,35 @@ CAMLprim value caml_sys_random_seed (value unit)
return res;
}
+CAMLprim value caml_sys_const_big_endian(value unit)
+{
+#ifdef ARCH_BIG_ENDIAN
+ return Val_true;
+#else
+ return Val_false;
+#endif
+}
+
+CAMLprim value caml_sys_const_word_size(value unit)
+{
+ return Val_long(8 * sizeof(value));
+}
+
+CAMLprim value caml_sys_const_ostype_unix(value unit)
+{
+ return Val_long(0 == strcmp(OCAML_OS_TYPE,"Unix"));
+}
+
+CAMLprim value caml_sys_const_ostype_win32(value unit)
+{
+ return Val_long(0 == strcmp(OCAML_OS_TYPE,"Win32"));
+}
+
+CAMLprim value caml_sys_const_ostype_cygwin(value unit)
+{
+ return Val_long(0 == strcmp(OCAML_OS_TYPE,"Cygwin"));
+}
+
CAMLprim value caml_sys_get_config(value unit)
{
CAMLparam0 (); /* unit is unused */