summaryrefslogtreecommitdiff
path: root/libraries/ghc-prim/cbits/longlong.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ghc-prim/cbits/longlong.c')
-rw-r--r--libraries/ghc-prim/cbits/longlong.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/libraries/ghc-prim/cbits/longlong.c b/libraries/ghc-prim/cbits/longlong.c
new file mode 100644
index 0000000000..7f3554b930
--- /dev/null
+++ b/libraries/ghc-prim/cbits/longlong.c
@@ -0,0 +1,89 @@
+/* -----------------------------------------------------------------------------
+ * $Id: longlong.c,v 1.4 2002/12/13 14:23:42 simonmar Exp $
+ *
+ * (c) The GHC Team, 1998-1999
+ *
+ * Primitive operations over (64-bit) long longs
+ * (only used on 32-bit platforms.)
+ *
+ * ---------------------------------------------------------------------------*/
+
+
+/*
+Miscellaneous primitive operations on HsInt64 and HsWord64s.
+N.B. These are not primops!
+
+Instead of going the normal (boring) route of making the list
+of primitive operations even longer to cope with operations
+over 64-bit entities, we implement them instead 'out-of-line'.
+
+The primitive ops get their own routine (in C) that implements
+the operation, requiring the caller to _ccall_ out. This has
+performance implications of course, but we currently don't
+expect intensive use of either Int64 or Word64 types.
+
+The exceptions to the rule are primops that cast to and from
+64-bit entities (these are defined in PrimOps.h)
+*/
+
+#include "Rts.h"
+
+#if WORD_SIZE_IN_BITS < 64
+
+/* Relational operators */
+
+HsInt hs_gtWord64 (HsWord64 a, HsWord64 b) {return a > b;}
+HsInt hs_geWord64 (HsWord64 a, HsWord64 b) {return a >= b;}
+HsInt hs_eqWord64 (HsWord64 a, HsWord64 b) {return a == b;}
+HsInt hs_neWord64 (HsWord64 a, HsWord64 b) {return a != b;}
+HsInt hs_ltWord64 (HsWord64 a, HsWord64 b) {return a < b;}
+HsInt hs_leWord64 (HsWord64 a, HsWord64 b) {return a <= b;}
+
+HsInt hs_gtInt64 (HsInt64 a, HsInt64 b) {return a > b;}
+HsInt hs_geInt64 (HsInt64 a, HsInt64 b) {return a >= b;}
+HsInt hs_eqInt64 (HsInt64 a, HsInt64 b) {return a == b;}
+HsInt hs_neInt64 (HsInt64 a, HsInt64 b) {return a != b;}
+HsInt hs_ltInt64 (HsInt64 a, HsInt64 b) {return a < b;}
+HsInt hs_leInt64 (HsInt64 a, HsInt64 b) {return a <= b;}
+
+/* Arithmetic operators */
+
+HsWord64 hs_remWord64 (HsWord64 a, HsWord64 b) {return a % b;}
+HsWord64 hs_quotWord64 (HsWord64 a, HsWord64 b) {return a / b;}
+
+HsInt64 hs_remInt64 (HsInt64 a, HsInt64 b) {return a % b;}
+HsInt64 hs_quotInt64 (HsInt64 a, HsInt64 b) {return a / b;}
+HsInt64 hs_negateInt64 (HsInt64 a) {return -a;}
+HsInt64 hs_plusInt64 (HsInt64 a, HsInt64 b) {return a + b;}
+HsInt64 hs_minusInt64 (HsInt64 a, HsInt64 b) {return a - b;}
+HsInt64 hs_timesInt64 (HsInt64 a, HsInt64 b) {return a * b;}
+
+/* Logical operators: */
+
+HsWord64 hs_and64 (HsWord64 a, HsWord64 b) {return a & b;}
+HsWord64 hs_or64 (HsWord64 a, HsWord64 b) {return a | b;}
+HsWord64 hs_xor64 (HsWord64 a, HsWord64 b) {return a ^ b;}
+HsWord64 hs_not64 (HsWord64 a) {return ~a;}
+
+HsWord64 hs_uncheckedShiftL64 (HsWord64 a, HsInt b) {return a << b;}
+HsWord64 hs_uncheckedShiftRL64 (HsWord64 a, HsInt b) {return a >> b;}
+/* Right shifting of signed quantities is not portable in C, so
+ the behaviour you'll get from using these primops depends
+ on the whatever your C compiler is doing. ToDo: fix. -- sof 8/98
+*/
+HsInt64 hs_uncheckedIShiftL64 (HsInt64 a, HsInt b) {return a << b;}
+HsInt64 hs_uncheckedIShiftRA64 (HsInt64 a, HsInt b) {return a >> b;}
+HsInt64 hs_uncheckedIShiftRL64 (HsInt64 a, HsInt b)
+ {return (HsInt64) ((HsWord64) a >> b);}
+
+/* Casting between longs and longer longs.
+*/
+
+HsInt64 hs_intToInt64 (HsInt i) {return (HsInt64) i;}
+HsInt hs_int64ToInt (HsInt64 i) {return (HsInt) i;}
+HsWord64 hs_int64ToWord64 (HsInt64 i) {return (HsWord64) i;}
+HsWord64 hs_wordToWord64 (HsWord w) {return (HsWord64) w;}
+HsWord hs_word64ToWord (HsWord64 w) {return (HsWord) w;}
+HsInt64 hs_word64ToInt64 (HsWord64 w) {return (HsInt64) w;}
+
+#endif /* SUPPORT_LONG_LONGS */