36
36
37
37
let (>>> ) = Caml_nativeint_extern. shift_right_logical
38
38
let (>> ) = Caml_nativeint_extern. shift_right
39
+ let (|~ ) = Caml_nativeint_extern. logor
39
40
let ( +~ ) = Caml_nativeint_extern. add
40
41
let ( *~ ) = Caml_nativeint_extern. mul
41
42
let ( & ) = Caml_nativeint_extern. logand
@@ -71,17 +72,34 @@ let neg_one = mk ~lo:(-1n) ~hi:(-1n)
71
72
72
73
let neg_signed x = (x & 0x8000_0000n ) <> 0n
73
74
74
- let add
75
- (Int64 {lo = this_low_ ; hi = this_high_ } : t )
76
- (Int64 {lo = other_low_ ; hi = other_high_ } : t ) =
77
- let lo = ( this_low_ +~ other_low_) & 0xffff_ffffn in
75
+ let neg (Int64 {lo;hi} ) =
76
+ let other_lo = (lognot lo +~ 1n ) & 0xffff_ffffn in
77
+ mk ~lo: other_lo
78
+ ~hi: ((lognot hi +~ if other_lo = 0n then 1n else 0n ) & 0xffff_ffffn )
79
+
80
+
81
+
82
+
83
+
84
+
85
+ let add_aux
86
+ (Int64 {lo = x_lo ; hi = x_hi } : t )
87
+ ~y_lo ~y_hi =
88
+ let lo = ( x_lo +~ y_lo) & 0xffff_ffffn in
78
89
let overflow =
79
- if (neg_signed this_low_ && (neg_signed other_low_ || not (neg_signed lo)))
80
- || (neg_signed other_low_ && not (neg_signed lo))
90
+ if (neg_signed x_lo && (neg_signed y_lo || not (neg_signed lo)))
91
+ || (neg_signed y_lo && not (neg_signed lo))
81
92
then 1n
82
93
else 0n
83
94
in
84
- mk ~lo ~hi: (( this_high_ +~ other_high_ +~ overflow) & 0xffff_ffffn )
95
+ mk ~lo ~hi: (( x_hi +~ y_hi +~ overflow) & 0xffff_ffffn )
96
+
97
+ (* * [add_lo self y_lo] === [add self (mk ~lo:y_lo ~hi:0n)] *)
98
+ let add_lo self lo = add_aux self ~y_lo: (to_unsigned lo) ~y_hi: 0n
99
+ let add
100
+ (self : t )
101
+ (Int64 {lo = y_lo ; hi = y_hi } : t ) =
102
+ add_aux self ~y_lo ~y_hi
85
103
86
104
87
105
let not (Int64 {lo; hi } ) = mk ~lo: (lognot lo) ~hi: (lognot hi)
@@ -101,14 +119,16 @@ let equal_nullable x y =
101
119
| None -> false
102
120
| Some y -> eq x y
103
121
104
- let neg x =
105
- if eq x min_int then
106
- min_int
107
- else add (not x) one
108
122
109
123
110
- let sub x y =
111
- add x (neg y)
124
+ (* when [lo] is unsigned integer, [lognot lo] is still an unsigned integer *)
125
+ let sub_aux x ~lo ~hi =
126
+ let neg_lo = to_unsigned ((lognot lo +~ 1n ) & 0xffff_ffffn ) in
127
+ let neg_hi = ((lognot hi +~ if neg_lo = 0n then 1n else 0n ) & 0xffff_ffffn ) in
128
+ add_aux x ~y_lo: neg_lo ~y_hi: neg_hi
129
+
130
+ let sub self (Int64{lo;hi} )= sub_aux self ~lo ~hi
131
+ let sub_lo self lo = sub_aux self ~lo ~hi: 0n
112
132
113
133
let lsl_ (Int64 {lo; hi} as x ) numBits =
114
134
if numBits = 0 then
@@ -118,9 +138,9 @@ let lsl_ (Int64 {lo; hi} as x) numBits =
118
138
else
119
139
mk ~lo: (Caml_nativeint_extern. shift_left lo numBits)
120
140
~hi:
121
- (Caml_nativeint_extern. logor
122
- ( lo >>> (32 - numBits))
123
- (Caml_nativeint_extern. shift_left hi numBits))
141
+ (
142
+ ( lo >>> (32 - numBits)) |~
143
+ ( hi << numBits))
124
144
125
145
126
146
let lsr_ (Int64 {lo; hi} as x ) numBits =
0 commit comments