Properly inline the int63 impl on 64 bit platforms.
authorRichard W.M. Jones <rjones@redhat.com>
Thu, 1 May 2008 18:28:42 +0000 (19:28 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Thu, 1 May 2008 18:28:42 +0000 (19:28 +0100)
.hgignore
lib/Makefile.in
lib/int63_on_32.mli [new file with mode: 0644]
lib/int63_on_64.mli [moved from lib/int63.mli with 93% similarity]

index 8fdb314..2d3d217 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -37,6 +37,7 @@ lib/diskimage_lvm2_lexer.ml
 lib/diskimage_lvm2_parser.ml
 lib/diskimage_lvm2_parser.mli
 lib/int63.ml
+lib/int63.mli
 *.img
 *.annot
 gmon.out
index befbac9..c16dbae 100644 (file)
@@ -87,16 +87,20 @@ diskimage_lvm2_parser.cmo: diskimage_lvm2_parser.cmi
 diskimage_lvm2_parser.cmx: diskimage_lvm2_parser.cmi
 diskimage_lvm2_parser.cmi: diskimage_lvm2_parser.mli
 
-# Int63 module implementation is defined differently on
-# 32 and 64 bit platforms.
+# Int63 module is defined differently on 32 and 64 bit platforms.
 int63.ml: int63_on_$(OCAML_WORD_SIZE).ml Makefile
        rm -f $@
        echo "(* WARNING: THIS FILE IS GENERATED FROM $< *)" | \
        cat - $< > $@
 
+int63.mli: int63_on_$(OCAML_WORD_SIZE).mli Makefile
+       rm -f $@
+       echo "(* WARNING: THIS FILE IS GENERATED FROM $< *)" | \
+       cat - $< > $@
+
 int63.cmo: int63.cmi
 int63.cmx: int63.cmi
-int63.cmi: int63.ml
+int63.cmi: int63.ml int63.mli
 
 #test_int63.opt: int63.cmx test_int63.cmx
 #      $(OCAMLFIND) ocamlopt $^ -o $@
diff --git a/lib/int63_on_32.mli b/lib/int63_on_32.mli
new file mode 100644 (file)
index 0000000..13226d9
--- /dev/null
@@ -0,0 +1,161 @@
+(** 63 bit signed integer type *)
+(* (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *)
+
+(** This module deals with creating an efficient 63 bit signed integer
+    type.
+
+    In OCaml, the basic [int] type is fast because it is unboxed, but
+    it has a different size on 32 and 64 bit platforms (31 and 63 bits
+    respectively).  If we want a large integer type we can use the
+    OCaml [int64] type, but that is boxed and hence operations are
+    slow, even on 64 bit platforms.
+
+    This type gives us a large integer (up to 63 bits, therefore fine
+    for things involving eg. large disk file sizes), but retains
+    efficiency.  On 64 bit platforms it degenerates into just a normal
+    [int], hence unboxed and fast.  On 32 bit platforms it degenerates
+    to a kind of [int64], which is boxed and slow but hey 32 bit
+    platforms are going the way of all things anyway.
+
+    The implementation of this type is in the files [int63_on_32.ml]
+    or [int63_on_64.ml] for 32 bit and 64 bit platforms respectively.
+    The appropriate implementation is copied by the Makefile to
+    [int63.ml].
+*)
+
+(** {2 Type Int63.t} *)
+
+type t
+
+(** {2 Operators}
+
+    It is recommended to do:
+
+{[
+open Int63.Operators
+]}
+
+    in your code so that you get the operators [+^], [-^] .. and the
+    type [int63] directly, and can still use the less frequent
+    functions such as {!Int63.abs} etc.
+*)
+
+module Operators : sig
+  type int63 = t
+
+  (* For the gory details of the rules of operators, see:
+   * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html
+   *)
+
+  val ( +^ ) : t -> t -> t
+  val ( -^ ) : t -> t -> t
+  val ( *^ ) : t -> t -> t
+  val ( /^ ) : t -> t -> t
+  val ( %^ ) : t -> t -> t
+    (** Infix arithmetic operators. eg. [a +^ b -^ c] *)
+
+  val ( <^< ) : t -> int -> t
+  val ( >^> ) : t -> int -> t
+    (** Infix shift left and logical shift right.
+       eg. [~^1 <^< 62]
+
+       NB: We cannot use two less-than signs or two greater-than signs
+       in a row because that clashes with the symbols used for
+       camlp4 quotations. *)
+
+  val ( &^ ) : t -> t -> t
+  val ( |^ ) : t -> t -> t
+  val ( ^^ ) : t -> t -> t
+    (** Infix logical and, or and xor operators.
+       eg. [bits &^ mask] *)
+
+  val ( ~^ ) : int -> t
+    (** Small integer constants,
+       eg. [~^0] is the constant zero and [~^1] is the constant one. *)
+  val ( ~^~ ) : int -> t
+    (** Small negative integer constants,
+       eg. [~^~1] is the constant minus one. *)
+end
+
+(** {2 Functions}
+
+    These functions are analogous to the similarly named
+    functions available in the standard library [Int32] and
+    [Int64] modules. *)
+
+val zero : t
+val one : t
+val minus_one : t
+  (** Some constants. *)
+
+val neg : t -> t
+  (** Negate. *)
+
+val add : t -> t -> t
+val sub : t -> t -> t
+val mul : t -> t -> t
+val div : t -> t -> t
+val rem : t -> t -> t
+  (** Arithmetic. *)
+
+val succ : t -> t
+  (** Successor. *)
+val pred : t -> t
+  (** Predecessor. *)
+
+val abs : t -> t
+  (** Absolute value. *)
+
+val max_int : t
+  (** The constant 2{^62}-1. *)
+val min_int : t
+  (** The constant -2{^62}. *)
+
+val logand : t -> t -> t
+val logor : t -> t -> t
+val logxor : t -> t -> t
+val lognot : t -> t
+  (** Bitwise logical and, or, xor and not. *)
+
+val shift_left : t -> int -> t
+  (** Shift the number left by the integer number of bits. *)
+val shift_right : t -> int -> t
+  (** Arithmetic shift the number right by the integer number of bits.
+      The sign bit is replicated into the vacated bits. *)
+val shift_right_logical : t -> int -> t
+  (** Logical shift the number right by the integer number of bits.
+      The vacated bits are filled with bit [0] regardless of sign. *)
+
+val of_int : int -> t
+val to_int : t -> int
+val of_float : float -> t
+val to_float : t -> float
+val of_int32 : int32 -> t
+val to_int32 : t -> int32
+val of_int64 : int64 -> t
+val to_int64 : t -> int64
+val of_nativeint : nativeint -> t
+val to_nativeint : t -> nativeint
+  (** Convert between t and various standard types. *)
+
+val of_string : string -> t
+val to_string : t -> string
+  (** Convert between string. *)
+
+val compare : t -> t -> int
+  (** Compare two numbers. *)
similarity index 93%
rename from lib/int63.mli
rename to lib/int63_on_64.mli
index 6ba9270..762db61 100644 (file)
 
 (** {2 Type Int63.t}
 
-    OCaml cross-module inlining means that the compiler gets to
-    inline [int] operations directly and efficiently on 64 bit
-    platforms.  However we still need to hide the actual type
-    to prevent people from writing code that accidentally depends
-    on 32/64-bit platform differences.
+    For reasons not fully understood, we need to declare this
+    type explicitly in order to get properly optimized operations.
+    This means the user of a 64 bit platform must be careful not to
+    accidentally write code which depends on [t] being an [int],
+    but should treat this as an opaque type.
 *)
 
-type t
+type t = int
 
 (** {2 Operators}