File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -89,6 +89,13 @@ val shift_arithmetic_right (a:t) (s:UInt32.t) : Pure t
8989 (requires (UInt32.v s < n))
9090 (ensures (fun c -> FStar.Int.shift_arithmetic_right (v a) (UInt32.v s) = v c))
9191
92+ (** Shift left on the two's complement representation.
93+ Unlike [shift_left], this operates on any signed integer (including negative values).
94+ This matches the semantics of [<<] on signed integers in C++ and Rust. *)
95+ val shift_arithmetic_left (a:t) (s:UInt32.t) : Pure t
96+ (requires (UInt32.v s < n))
97+ (ensures (fun c -> FStar.Int.shift_arithmetic_left (v a) (UInt32.v s) = v c))
98+
9299(* Rotate operators *)
93100
94101(** Rotate right.
@@ -125,6 +132,7 @@ inline_for_extraction unfold let ( |^ ) = logor
125132inline_for_extraction unfold let ( <<^ ) = shift_left
126133inline_for_extraction unfold let ( >>^ ) = shift_right
127134inline_for_extraction unfold let ( >>>^) = shift_arithmetic_right
135+ inline_for_extraction unfold let ( <<<^) = shift_arithmetic_left
128136inline_for_extraction unfold let ( =^ ) = eq
129137inline_for_extraction unfold let ( <>^ ) = ne
130138inline_for_extraction unfold let ( >^ ) = gt
Original file line number Diff line number Diff line change @@ -51,6 +51,8 @@ let shift_left a s = Mk (shift_left (v a) (UInt32.v s))
5151
5252let shift_arithmetic_right a s = Mk (shift_arithmetic_right (v a) (UInt32.v s))
5353
54+ let shift_arithmetic_left a s = Mk (shift_arithmetic_left (v a) (UInt32.v s))
55+
5456let rotate_right a s = Mk (rotate_right (v a) (UInt32.v s))
5557
5658let rotate_left a s = Mk (rotate_left (v a) (UInt32.v s))
Original file line number Diff line number Diff line change @@ -187,6 +187,10 @@ let shift_arithmetic_right_lemma_1 #n a s i = ()
187187
188188let shift_arithmetic_right_lemma_2 # n a s i = ()
189189
190+ let shift_arithmetic_left_lemma_1 # n a s i = ()
191+
192+ let shift_arithmetic_left_lemma_2 # n a s i = ()
193+
190194(* Rotate operators lemmas *)
191195
192196let rotate_left_lemma # n a s i = ()
Original file line number Diff line number Diff line change @@ -399,6 +399,13 @@ let shift_right (#n:pos) (a:int_t n{0 <= a}) (s:nat) : Tot (int_t n) =
399399let shift_arithmetic_right (# n :pos) ( a : int_t n ) ( s :nat) : Tot ( int_t n ) =
400400 from_vec ( shift_arithmetic_right_vec # n ( to_vec # n a ) s )
401401
402+ (* * Shift left on the two's complement representation.
403+ Unlike [shift_left], this operates on any signed integer (including negative values).
404+ The result is the same bitwise operation: shift bits left and fill with zeroes.
405+ This matches the semantics of [<<] on signed integers in C++ and Rust. *)
406+ let shift_arithmetic_left (# n :pos) ( a : int_t n ) ( s :nat) : Tot ( int_t n ) =
407+ from_vec ( shift_left_vec # n ( to_vec # n a ) s )
408+
402409(* Rotate operators *)
403410
404411(* * Rotate left.
@@ -449,6 +456,16 @@ val shift_arithmetic_right_lemma_2: #n:pos -> a:int_t n -> s:nat -> i:nat{i < n
449456 ( ensures ( nth ( shift_arithmetic_right # n a s ) i = nth # n a ( i - s )))
450457 [ SMTPat ( nth ( shift_arithmetic_right # n a s ) i )]
451458
459+ val shift_arithmetic_left_lemma_1 : # n :pos -> a : int_t n -> s :nat -> i :nat{ i < n && i >= n - s } ->
460+ Lemma ( requires True )
461+ ( ensures ( nth ( shift_arithmetic_left # n a s ) i = false ))
462+ [ SMTPat ( nth ( shift_arithmetic_left # n a s ) i )]
463+
464+ val shift_arithmetic_left_lemma_2 : # n :pos -> a : int_t n -> s :nat -> i :nat{ i < n && i < n - s } ->
465+ Lemma ( requires True )
466+ ( ensures ( nth ( shift_arithmetic_left # n a s ) i = nth # n a ( i + s )))
467+ [ SMTPat ( nth ( shift_arithmetic_left # n a s ) i )]
468+
452469(* Rotate operators lemmas *)
453470val rotate_left_lemma : # n :pos -> a : int_t n -> s :nat -> i :nat{ i < n } ->
454471 Lemma ( requires True )
Original file line number Diff line number Diff line change @@ -70,6 +70,8 @@ let shift_left a s = Mk (shift_left (v a) (UInt32.v s))
7070
7171let shift_arithmetic_right a s = Mk ( shift_arithmetic_right ( v a ) ( UInt32. v s ))
7272
73+ let shift_arithmetic_left a s = Mk ( shift_arithmetic_left ( v a ) ( UInt32. v s ))
74+
7375let rotate_right a s = Mk ( rotate_right ( v a ) ( UInt32. v s ))
7476
7577let rotate_left a s = Mk ( rotate_left ( v a ) ( UInt32. v s ))
Original file line number Diff line number Diff line change @@ -110,6 +110,13 @@ val shift_arithmetic_right (a:t) (s:UInt32.t) : Pure t
110110 ( requires ( UInt32. v s < n ))
111111 ( ensures ( fun c -> FStar.Int. shift_arithmetic_right ( v a ) ( UInt32. v s ) = v c ))
112112
113+ (* * Shift left on the two's complement representation.
114+ Unlike [shift_left], this operates on any signed integer (including negative values).
115+ This matches the semantics of [<<] on signed integers in C++ and Rust. *)
116+ val shift_arithmetic_left ( a : t ) ( s : UInt32. t ) : Pure t
117+ ( requires ( UInt32. v s < n ))
118+ ( ensures ( fun c -> FStar.Int. shift_arithmetic_left ( v a ) ( UInt32. v s ) = v c ))
119+
113120(* Rotate operators *)
114121
115122(* * Rotate right for non-negative values *)
@@ -142,6 +149,7 @@ inline_for_extraction unfold let ( |^ ) = logor
142149inline_for_extraction unfold let ( <<^ ) = shift_left
143150inline_for_extraction unfold let ( >>^ ) = shift_right
144151inline_for_extraction unfold let ( >>>^) = shift_arithmetic_right
152+ inline_for_extraction unfold let ( <<<^) = shift_arithmetic_left
145153inline_for_extraction unfold let ( =^ ) = eq
146154inline_for_extraction unfold let ( <>^ ) = ne
147155inline_for_extraction unfold let ( >^ ) = gt
Original file line number Diff line number Diff line change @@ -70,6 +70,8 @@ let shift_left a s = Mk (shift_left (v a) (UInt32.v s))
7070
7171let shift_arithmetic_right a s = Mk ( shift_arithmetic_right ( v a ) ( UInt32. v s ))
7272
73+ let shift_arithmetic_left a s = Mk ( shift_arithmetic_left ( v a ) ( UInt32. v s ))
74+
7375let rotate_right a s = Mk ( rotate_right ( v a ) ( UInt32. v s ))
7476
7577let rotate_left a s = Mk ( rotate_left ( v a ) ( UInt32. v s ))
Original file line number Diff line number Diff line change @@ -110,6 +110,13 @@ val shift_arithmetic_right (a:t) (s:UInt32.t) : Pure t
110110 ( requires ( UInt32. v s < n ))
111111 ( ensures ( fun c -> FStar.Int. shift_arithmetic_right ( v a ) ( UInt32. v s ) = v c ))
112112
113+ (* * Shift left on the two's complement representation.
114+ Unlike [shift_left], this operates on any signed integer (including negative values).
115+ This matches the semantics of [<<] on signed integers in C++ and Rust. *)
116+ val shift_arithmetic_left ( a : t ) ( s : UInt32. t ) : Pure t
117+ ( requires ( UInt32. v s < n ))
118+ ( ensures ( fun c -> FStar.Int. shift_arithmetic_left ( v a ) ( UInt32. v s ) = v c ))
119+
113120(* Rotate operators *)
114121
115122(* * Rotate right.
@@ -146,6 +153,7 @@ inline_for_extraction unfold let ( |^ ) = logor
146153inline_for_extraction unfold let ( <<^ ) = shift_left
147154inline_for_extraction unfold let ( >>^ ) = shift_right
148155inline_for_extraction unfold let ( >>>^) = shift_arithmetic_right
156+ inline_for_extraction unfold let ( <<<^) = shift_arithmetic_left
149157inline_for_extraction unfold let ( =^ ) = eq
150158inline_for_extraction unfold let ( <>^ ) = ne
151159inline_for_extraction unfold let ( >^ ) = gt
Original file line number Diff line number Diff line change @@ -70,6 +70,8 @@ let shift_left a s = Mk (shift_left (v a) (UInt32.v s))
7070
7171let shift_arithmetic_right a s = Mk ( shift_arithmetic_right ( v a ) ( UInt32. v s ))
7272
73+ let shift_arithmetic_left a s = Mk ( shift_arithmetic_left ( v a ) ( UInt32. v s ))
74+
7375let rotate_right a s = Mk ( rotate_right ( v a ) ( UInt32. v s ))
7476
7577let rotate_left a s = Mk ( rotate_left ( v a ) ( UInt32. v s ))
Original file line number Diff line number Diff line change @@ -110,6 +110,13 @@ val shift_arithmetic_right (a:t) (s:UInt32.t) : Pure t
110110 ( requires ( UInt32. v s < n ))
111111 ( ensures ( fun c -> FStar.Int. shift_arithmetic_right ( v a ) ( UInt32. v s ) = v c ))
112112
113+ (* * Shift left on the two's complement representation.
114+ Unlike [shift_left], this operates on any signed integer (including negative values).
115+ This matches the semantics of [<<] on signed integers in C++ and Rust. *)
116+ val shift_arithmetic_left ( a : t ) ( s : UInt32. t ) : Pure t
117+ ( requires ( UInt32. v s < n ))
118+ ( ensures ( fun c -> FStar.Int. shift_arithmetic_left ( v a ) ( UInt32. v s ) = v c ))
119+
113120(* Rotate operators *)
114121
115122(* * Rotate right.
@@ -146,6 +153,7 @@ inline_for_extraction unfold let ( |^ ) = logor
146153inline_for_extraction unfold let ( <<^ ) = shift_left
147154inline_for_extraction unfold let ( >>^ ) = shift_right
148155inline_for_extraction unfold let ( >>>^) = shift_arithmetic_right
156+ inline_for_extraction unfold let ( <<<^) = shift_arithmetic_left
149157inline_for_extraction unfold let ( =^ ) = eq
150158inline_for_extraction unfold let ( <>^ ) = ne
151159inline_for_extraction unfold let ( >^ ) = gt
You can’t perform that action at this time.
0 commit comments