diff options
author | Fabrice Le Fessant <Fabrice.Le_fessant@inria.fr> | 2012-11-29 09:55:00 +0000 |
---|---|---|
committer | Fabrice Le Fessant <Fabrice.Le_fessant@inria.fr> | 2012-11-29 09:55:00 +0000 |
commit | 89bdc103505183125f7bf759c27302a34757af9b (patch) | |
tree | ec9ec9c519d08f8ce9e515e0d10a21dac83bb63f /byterun | |
parent | f80d01e968bf899aaa36882840eddc11ce428f94 (diff) | |
download | ocaml-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.h | 14 | ||||
-rw-r--r-- | byterun/int64_native.h | 9 | ||||
-rw-r--r-- | byterun/ints.c | 65 | ||||
-rw-r--r-- | byterun/sys.c | 29 |
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 */ |