Skip to content

Commit c8d4e0e

Browse files
committed
Semantics for shift operations
1 parent be5444f commit c8d4e0e

8 files changed

+137
-20
lines changed

Graph/IRNodeHierarchy.thy

+7-4
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ fun is_VirtualState :: "IRNode \<Rightarrow> bool" where
2929
fun is_BinaryArithmeticNode :: "IRNode \<Rightarrow> bool" where
3030
"is_BinaryArithmeticNode n = ((is_AddNode n) \<or> (is_AndNode n) \<or> (is_MulNode n) \<or> (is_OrNode n) \<or> (is_SubNode n) \<or> (is_XorNode n))"
3131

32+
fun is_ShiftNode :: "IRNode \<Rightarrow> bool" where
33+
"is_ShiftNode n = ((is_LeftShiftNode n) \<or> (is_RightShiftNode n) \<or> (is_UnsignedRightShiftNode n))"
34+
3235
fun is_BinaryNode :: "IRNode \<Rightarrow> bool" where
33-
"is_BinaryNode n = ((is_BinaryArithmeticNode n))"
36+
"is_BinaryNode n = ((is_BinaryArithmeticNode n) \<or> (is_ShiftNode n))"
3437

3538
fun is_AbstractLocalNode :: "IRNode \<Rightarrow> bool" where
3639
"is_AbstractLocalNode n = ((is_ParameterNode n))"
@@ -135,7 +138,7 @@ fun is_MemoryKill :: "IRNode \<Rightarrow> bool" where
135138
"is_MemoryKill n = ((is_AbstractMemoryCheckpoint n))"
136139

137140
fun is_NarrowableArithmeticNode :: "IRNode \<Rightarrow> bool" where
138-
"is_NarrowableArithmeticNode n = ((is_AbsNode n) \<or> (is_AddNode n) \<or> (is_AndNode n) \<or> (is_MulNode n) \<or> (is_NegateNode n) \<or> (is_NotNode n) \<or> (is_OrNode n) \<or> (is_SubNode n) \<or> (is_XorNode n))"
141+
"is_NarrowableArithmeticNode n = ((is_AbsNode n) \<or> (is_AddNode n) \<or> (is_AndNode n) \<or> (is_MulNode n) \<or> (is_NegateNode n) \<or> (is_NotNode n) \<or> (is_OrNode n) \<or> (is_ShiftNode n) \<or> (is_SubNode n) \<or> (is_XorNode n))"
139142

140143
fun is_AnchoringNode :: "IRNode \<Rightarrow> bool" where
141144
"is_AnchoringNode n = ((is_AbstractBeginNode n))"
@@ -180,7 +183,7 @@ fun is_GuardedNode :: "IRNode \<Rightarrow> bool" where
180183
"is_GuardedNode n = ((is_FloatingGuardedNode n))"
181184

182185
fun is_ArithmeticLIRLowerable :: "IRNode \<Rightarrow> bool" where
183-
"is_ArithmeticLIRLowerable n = ((is_AbsNode n) \<or> (is_BinaryArithmeticNode n) \<or> (is_IntegerConvertNode n) \<or> (is_NotNode n) \<or> (is_UnaryArithmeticNode n))"
186+
"is_ArithmeticLIRLowerable n = ((is_AbsNode n) \<or> (is_BinaryArithmeticNode n) \<or> (is_IntegerConvertNode n) \<or> (is_NotNode n) \<or> (is_ShiftNode n) \<or> (is_UnaryArithmeticNode n))"
184187

185188
fun is_SwitchFoldable :: "IRNode \<Rightarrow> bool" where
186189
"is_SwitchFoldable n = ((is_IfNode n))"
@@ -207,7 +210,7 @@ fun is_Binary :: "IRNode \<Rightarrow> bool" where
207210
"is_Binary n = ((is_BinaryArithmeticNode n) \<or> (is_BinaryNode n) \<or> (is_BinaryOpLogicNode n) \<or> (is_CompareNode n) \<or> (is_FixedBinaryNode n) \<or> (is_ShortCircuitOrNode n))"
208211

209212
fun is_ArithmeticOperation :: "IRNode \<Rightarrow> bool" where
210-
"is_ArithmeticOperation n = ((is_BinaryArithmeticNode n) \<or> (is_IntegerConvertNode n) \<or> (is_UnaryArithmeticNode n))"
213+
"is_ArithmeticOperation n = ((is_BinaryArithmeticNode n) \<or> (is_IntegerConvertNode n) \<or> (is_ShiftNode n) \<or> (is_UnaryArithmeticNode n))"
211214

212215
fun is_ValueNumberable :: "IRNode \<Rightarrow> bool" where
213216
"is_ValueNumberable n = ((is_FloatingNode n) \<or> (is_ProxyNode n))"

Graph/IRNodes.thy

+15
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ datatype (discs_sels) IRNode =
5656
| InvokeWithExceptionNode (ir_nid: ID) (ir_callTarget: "INPUT_EXT") (ir_classInit_opt: "INPUT option") (ir_stateDuring_opt: "INPUT_STATE option") (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC") (ir_exceptionEdge: "SUCC")
5757
| IsNullNode (ir_value: "INPUT")
5858
| KillingBeginNode (ir_next: "SUCC")
59+
| LeftShiftNode (ir_x: "INPUT") (ir_y: "INPUT")
5960
| LoadFieldNode (ir_nid: ID) (ir_field: string) (ir_object_opt: "INPUT option") (ir_next: "SUCC")
6061
| LogicNegationNode (ir_value: "INPUT_COND")
6162
| LoopBeginNode (ir_ends: "INPUT_ASSOC list") (ir_overflowGuard_opt: "INPUT_GUARD option") (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC")
@@ -73,13 +74,15 @@ datatype (discs_sels) IRNode =
7374
| ParameterNode (ir_index: nat)
7475
| PiNode (ir_object: "INPUT") (ir_guard_opt: "INPUT_GUARD option")
7576
| ReturnNode (ir_result_opt: "INPUT option") (ir_memoryMap_opt: "INPUT_EXT option")
77+
| RightShiftNode (ir_x: "INPUT") (ir_y: "INPUT")
7678
| ShortCircuitOrNode (ir_x: "INPUT_COND") (ir_y: "INPUT_COND")
7779
| SignExtendNode (ir_inputBits: nat) (ir_resultBits: nat) (ir_value: "INPUT")
7880
| SignedDivNode (ir_nid: ID) (ir_x: "INPUT") (ir_y: "INPUT") (ir_zeroCheck_opt: "INPUT_GUARD option") (ir_stateBefore_opt: "INPUT_STATE option") (ir_next: "SUCC")
7981
| SignedRemNode (ir_nid: ID) (ir_x: "INPUT") (ir_y: "INPUT") (ir_zeroCheck_opt: "INPUT_GUARD option") (ir_stateBefore_opt: "INPUT_STATE option") (ir_next: "SUCC")
8082
| StartNode (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC")
8183
| StoreFieldNode (ir_nid: ID) (ir_field: string) (ir_value: "INPUT") (ir_stateAfter_opt: "INPUT_STATE option") (ir_object_opt: "INPUT option") (ir_next: "SUCC")
8284
| SubNode (ir_x: "INPUT") (ir_y: "INPUT")
85+
| UnsignedRightShiftNode (ir_x: "INPUT") (ir_y: "INPUT")
8386
| UnwindNode (ir_exception: "INPUT")
8487
| ValuePhiNode (ir_nid: ID) (ir_values: "INPUT list") (ir_merge: "INPUT_ASSOC")
8588
| ValueProxyNode (ir_value: "INPUT") (ir_loopExit: "INPUT_ASSOC")
@@ -146,6 +149,8 @@ fun inputs_of :: "IRNode \<Rightarrow> ID list" where
146149
"inputs_of (IsNullNode value) = [value]" |
147150
inputs_of_KillingBeginNode:
148151
"inputs_of (KillingBeginNode next) = []" |
152+
inputs_of_LeftShiftNode:
153+
"inputs_of (LeftShiftNode x y) = [x, y]" |
149154
inputs_of_LoadFieldNode:
150155
"inputs_of (LoadFieldNode nid0 field object next) = (opt_to_list object)" |
151156
inputs_of_LogicNegationNode:
@@ -180,6 +185,8 @@ fun inputs_of :: "IRNode \<Rightarrow> ID list" where
180185
"inputs_of (PiNode object guard) = object # (opt_to_list guard)" |
181186
inputs_of_ReturnNode:
182187
"inputs_of (ReturnNode result memoryMap) = (opt_to_list result) @ (opt_to_list memoryMap)" |
188+
inputs_of_RightShiftNode:
189+
"inputs_of (RightShiftNode x y) = [x, y]" |
183190
inputs_of_ShortCircuitOrNode:
184191
"inputs_of (ShortCircuitOrNode x y) = [x, y]" |
185192
inputs_of_SignExtendNode:
@@ -194,6 +201,8 @@ fun inputs_of :: "IRNode \<Rightarrow> ID list" where
194201
"inputs_of (StoreFieldNode nid0 field value stateAfter object next) = value # (opt_to_list stateAfter) @ (opt_to_list object)" |
195202
inputs_of_SubNode:
196203
"inputs_of (SubNode x y) = [x, y]" |
204+
inputs_of_UnsignedRightShiftNode:
205+
"inputs_of (UnsignedRightShiftNode x y) = [x, y]" |
197206
inputs_of_UnwindNode:
198207
"inputs_of (UnwindNode exception) = [exception]" |
199208
inputs_of_ValuePhiNode:
@@ -249,6 +258,8 @@ fun successors_of :: "IRNode \<Rightarrow> ID list" where
249258
"successors_of (IsNullNode value) = []" |
250259
successors_of_KillingBeginNode:
251260
"successors_of (KillingBeginNode next) = [next]" |
261+
successors_of_LeftShiftNode:
262+
"successors_of (LeftShiftNode x y) = []" |
252263
successors_of_LoadFieldNode:
253264
"successors_of (LoadFieldNode nid0 field object next) = [next]" |
254265
successors_of_LogicNegationNode:
@@ -283,6 +294,8 @@ fun successors_of :: "IRNode \<Rightarrow> ID list" where
283294
"successors_of (PiNode object guard) = []" |
284295
successors_of_ReturnNode:
285296
"successors_of (ReturnNode result memoryMap) = []" |
297+
successors_of_RightShiftNode:
298+
"successors_of (RightShiftNode x y) = []" |
286299
successors_of_ShortCircuitOrNode:
287300
"successors_of (ShortCircuitOrNode x y) = []" |
288301
successors_of_SignExtendNode:
@@ -297,6 +310,8 @@ fun successors_of :: "IRNode \<Rightarrow> ID list" where
297310
"successors_of (StoreFieldNode nid0 field value stateAfter object next) = [next]" |
298311
successors_of_SubNode:
299312
"successors_of (SubNode x y) = []" |
313+
successors_of_UnsignedRightShiftNode:
314+
"successors_of (UnsignedRightShiftNode x y) = []" |
300315
successors_of_UnwindNode:
301316
"successors_of (UnwindNode exception) = []" |
302317
successors_of_ValuePhiNode:

Graph/Values.thy

+58
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,64 @@ fun intval_abs :: "Value \<Rightarrow> Value" where
235235
"intval_abs (IntVal64 v) = (if (v) <s 0 then (IntVal64 (- v)) else (IntVal64 v))" |
236236
"intval_abs _ = UndefVal"
237237

238+
lemma [code]: "shiftl1 n = n * 2"
239+
by (simp add: shiftl1_eq_mult_2)
240+
241+
lemma [code]: "shiftr1 n = n div 2"
242+
by (simp add: shiftr1_eq_div_2)
243+
244+
lemma [code]: "sshiftr1 n = word_of_int (sint n div 2)"
245+
using sshiftr1_eq by blast
246+
247+
definition shiftl (infix "<<" 75) where
248+
"shiftl w n = (shiftl1 ^^ n) w"
249+
250+
lemma shiftl_power[simp]: "(x::('a::len) word) * (2 ^ j) = x << j"
251+
unfolding shiftl_def apply (induction j)
252+
apply simp unfolding funpow_Suc_right
253+
by (metis (no_types, lifting) comp_def funpow_swap1 mult.left_commute power_Suc shiftl1_eq_mult_2)
254+
255+
lemma "(x::('a::len) word) * ((2 ^ j) + 1) = x << j + x"
256+
by (simp add: distrib_left)
257+
258+
lemma "(x::('a::len) word) * ((2 ^ j) - 1) = x << j - x"
259+
by (simp add: right_diff_distrib)
260+
261+
lemma "(x::('a::len) word) * ((2^j) + (2^k)) = x << j + x << k"
262+
by (simp add: distrib_left)
263+
264+
lemma "(x::('a::len) word) * ((2^j) - (2^k)) = x << j - x << k"
265+
by (simp add: right_diff_distrib)
266+
267+
268+
definition signed_shiftr (infix ">>" 75) where
269+
"signed_shiftr w n = (sshiftr1 ^^ n) w"
270+
271+
definition shiftr (infix ">>>" 75) where
272+
"shiftr w n = (shiftr1 ^^ n) w"
273+
274+
lemma shiftr_power[simp]: "(x::('a::len) word) div (2 ^ j) = x >>> j"
275+
unfolding shiftr_def apply (induction j)
276+
apply simp unfolding funpow_Suc_right
277+
by (metis (no_types, lifting) comp_apply div_exp_eq funpow_swap1 power_Suc2 power_add power_one_right shiftr1_eq_div_2)
278+
279+
280+
281+
fun intval_left_shift :: "Value \<Rightarrow> Value \<Rightarrow> Value" where
282+
"intval_left_shift (IntVal32 v1) (IntVal32 v2) = IntVal32 (v1 << unat (v2 mod 32))" |
283+
"intval_left_shift (IntVal64 v1) (IntVal64 v2) = IntVal64 (v1 << unat (v2 mod 64))" |
284+
"intval_left_shift _ _ = UndefVal"
285+
286+
fun intval_right_shift :: "Value \<Rightarrow> Value \<Rightarrow> Value" where
287+
"intval_right_shift (IntVal32 v1) (IntVal32 v2) = IntVal32 (v1 >> unat (v2 mod 32))" |
288+
"intval_right_shift (IntVal64 v1) (IntVal64 v2) = IntVal64 (v1 >> unat (v2 mod 64))" |
289+
"intval_right_shift _ _ = UndefVal"
290+
291+
fun intval_uright_shift :: "Value \<Rightarrow> Value \<Rightarrow> Value" where
292+
"intval_uright_shift (IntVal32 v1) (IntVal32 v2) = IntVal32 (v1 >>> unat (v2 mod 32))" |
293+
"intval_uright_shift (IntVal64 v1) (IntVal64 v2) = IntVal64 (v1 >>> unat (v2 mod 64))" |
294+
"intval_uright_shift _ _ = UndefVal"
295+
238296
(*
239297
end
240298
*)

Optimizations/CanonicalizationTreeProofs.thy

+3-5
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ next
790790
apply (cases "intval_equals xval yval")
791791
using IRTreeEval.val_to_bool.simps(2) apply presburger sorry
792792
then have "res = yval"
793-
by (smt (verit) ConditionalExprE BinaryExprE xeval yeval evalDet bin_eval.simps(7) cond_eq.hyps(1) cond_eq.prems(1))
793+
by (smt (verit, ccfv_threshold) BinaryExprE ConditionalExprE bin_eval.simps(10) cond_eq.hyps(1) cond_eq.prems(1) evalDet xeval yeval)
794794
then show ?thesis
795795
using cond_eq.prems(1) cond_eq.prems(2) xeval yeval evalDet by auto
796796
qed
@@ -803,8 +803,7 @@ next
803803
then show ?case proof (cases "val_to_bool(intval_less_than xval yval)")
804804
case True
805805
then show ?thesis
806-
by (smt (verit, best) xeval yeval evalDet ConditionalExprE BinaryExprE bin_eval.simps(8)
807-
condition_bounds_x.hyps(1) condition_bounds_x.prems(1) condition_bounds_x.prems(2))
806+
by (smt (verit, best) BinaryExprE ConditionalExprE bin_eval.simps(11) condition_bounds_x.hyps(1) condition_bounds_x.prems(1) condition_bounds_x.prems(2) evalDet xeval yeval)
808807
next
809808
case False
810809
then have "stpi_upper stampx = stpi_lower stampy"
@@ -828,8 +827,7 @@ next
828827
then show ?case proof (cases "val_to_bool(intval_less_than xval yval)")
829828
case True
830829
then show ?thesis
831-
by (smt (verit, best) xeval yeval evalDet ConditionalExprE BinaryExprE bin_eval.simps(8)
832-
condition_bounds_y.hyps(1) condition_bounds_y.prems(1) condition_bounds_y.prems(2))
830+
by (smt (verit, best) BinaryExprE ConditionalExprE bin_eval.simps(11) condition_bounds_y.hyps(1) condition_bounds_y.prems(1) condition_bounds_y.prems(2) evalDet xeval yeval)
833831
next
834832
case False
835833
have "stpi_upper stampx = stpi_lower stampy"

Semantics/IRTreeEval.thy

+6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ datatype IRBinaryOp =
6565
| BinAnd
6666
| BinOr
6767
| BinXor
68+
| BinLeftShift
69+
| BinRightShift
70+
| BinURightShift
6871
| BinIntegerEquals
6972
| BinIntegerLessThan
7073
| BinIntegerBelow
@@ -121,6 +124,9 @@ fun bin_eval :: "IRBinaryOp \<Rightarrow> Value \<Rightarrow> Value \<Rightarrow
121124
"bin_eval BinAnd v1 v2 = intval_and v1 v2" |
122125
"bin_eval BinOr v1 v2 = intval_or v1 v2" |
123126
"bin_eval BinXor v1 v2 = intval_xor v1 v2" |
127+
"bin_eval BinLeftShift v1 v2 = intval_left_shift v1 v2" |
128+
"bin_eval BinRightShift v1 v2 = intval_right_shift v1 v2" |
129+
"bin_eval BinURightShift v1 v2 = intval_uright_shift v1 v2" |
124130
"bin_eval BinIntegerEquals v1 v2 = intval_equals v1 v2" |
125131
"bin_eval BinIntegerLessThan v1 v2 = intval_less_than v1 v2" |
126132
"bin_eval BinIntegerBelow v1 v2 = intval_below v1 v2"

Semantics/IRTreeEvalThms.thy

+10-10
Original file line numberDiff line numberDiff line change
@@ -177,39 +177,39 @@ next
177177
next
178178
case (NotNode n x xe)
179179
then show ?case
180-
by (metis IRNode.inject(31) NotNodeE rep_not)
180+
by (metis IRNode.inject(32) NotNodeE rep_not)
181181
next
182182
case (NegateNode n x xe)
183183
then show ?case
184-
by (metis IRNode.inject(28) NegateNodeE rep_negate)
184+
by (metis IRNode.inject(29) NegateNodeE rep_negate)
185185
next
186186
case (LogicNegationNode n x xe)
187187
then show ?case
188-
by (metis IRNode.inject(20) LogicNegationNodeE rep_logicnegation)
188+
by (metis IRNode.inject(21) LogicNegationNodeE rep_logicnegation)
189189
next
190190
case (AddNode n x y xe ye)
191191
then show ?case
192192
by (metis AddNodeE IRNode.inject(2) rep_add)
193193
next
194194
case (MulNode n x y xe ye)
195195
then show ?case
196-
by (metis IRNode.inject(26) MulNodeE rep_mul)
196+
by (metis IRNode.inject(27) MulNodeE rep_mul)
197197
next
198198
case (SubNode n x y xe ye)
199199
then show ?case
200-
by (metis IRNode.inject(42) SubNodeE rep_sub)
200+
by (metis IRNode.inject(44) SubNodeE rep_sub)
201201
next
202202
case (AndNode n x y xe ye)
203203
then show ?case
204204
by (metis AndNodeE IRNode.inject(3) rep_and)
205205
next
206206
case (OrNode n x y xe ye)
207207
then show ?case
208-
by (metis IRNode.inject(32) OrNodeE rep_or)
208+
by (metis IRNode.inject(33) OrNodeE rep_or)
209209
next
210210
case (XorNode n x y xe ye)
211211
then show ?case
212-
by (metis IRNode.inject(46) XorNodeE rep_xor)
212+
by (metis IRNode.inject(49) XorNodeE rep_xor)
213213
next
214214
case (IntegerBelowNode n x y xe ye)
215215
then show ?case
@@ -225,15 +225,15 @@ next
225225
next
226226
case (NarrowNode n x xe)
227227
then show ?case
228-
by (metis IRNode.inject(27) NarrowNodeE rep_narrow)
228+
by (metis IRNode.inject(28) NarrowNodeE rep_narrow)
229229
next
230230
case (SignExtendNode n x xe)
231231
then show ?case
232-
by (metis IRNode.inject(37) SignExtendNodeE rep_sign_extend)
232+
by (metis IRNode.inject(39) SignExtendNodeE rep_sign_extend)
233233
next
234234
case (ZeroExtendNode n x xe)
235235
then show ?case
236-
by (metis IRNode.inject(47) ZeroExtendNodeE rep_zero_extend)
236+
by (metis IRNode.inject(50) ZeroExtendNodeE rep_zero_extend)
237237
next
238238
case (LeafNode n s)
239239
then show ?case using rep_load_field LeafNodeE by blast

Semantics/TreeToGraph.thy

+3
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,9 @@ fun bin_node :: "IRBinaryOp \<Rightarrow> ID \<Rightarrow> ID \<Rightarrow> IRNo
283283
"bin_node BinAnd x y = AndNode x y" |
284284
"bin_node BinOr x y = OrNode x y" |
285285
"bin_node BinXor x y = XorNode x y" |
286+
"bin_node BinLeftShift x y = LeftShiftNode x y" |
287+
"bin_node BinRightShift x y = RightShiftNode x y" |
288+
"bin_node BinURightShift x y = UnsignedRightShiftNode x y" |
286289
"bin_node BinIntegerEquals x y = IntegerEqualsNode x y" |
287290
"bin_node BinIntegerLessThan x y = IntegerLessThanNode x y" |
288291
"bin_node BinIntegerBelow x y = IntegerBelowNode x y"

TheoryTesting.thy

+35-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,40 @@ lemma
4444
using assms unfolding valid_number.simps
4545
apply (simp add: Abs_IntegerHole_inverse)
4646
by (metis (no_types, hide_lams) bit.conj_disj_distrib2 bit.disj_cancel_left or.left_neutral word_ao_absorbs(2) word_oa_dist)
47-
47+
48+
49+
definition shiftl (infix "<<" 75) where
50+
"shiftl w n = (shiftl1 ^^ n) w"
51+
52+
lemma shiftl_power[simp]: "(x::('a::len) word) * (2 ^ j) = x << j"
53+
unfolding shiftl_def apply (induction j)
54+
apply simp unfolding funpow_Suc_right
55+
by (metis (no_types, lifting) comp_def funpow_swap1 mult.left_commute power_Suc shiftl1_eq_mult_2)
56+
57+
lemma "(x::('a::len) word) * ((2 ^ j) + 1) = x << j + x"
58+
by (simp add: distrib_left)
59+
60+
lemma "(x::('a::len) word) * ((2 ^ j) - 1) = x << j - x"
61+
by (simp add: right_diff_distrib)
62+
63+
lemma "(x::('a::len) word) * ((2^j) + (2^k)) = x << j + x << k"
64+
by (simp add: distrib_left)
65+
66+
lemma "(x::('a::len) word) * ((2^j) - (2^k)) = x << j - x << k"
67+
by (simp add: right_diff_distrib)
68+
69+
70+
definition signed_shiftr (infix ">>" 75) where
71+
"signed_shiftr w n = (sshiftr1 ^^ n) w"
72+
73+
definition shiftr (infix ">>>" 75) where
74+
"shiftr w n = (shiftr1 ^^ n) w"
75+
76+
lemma shiftr_power[simp]: "(x::('a::len) word) div (2 ^ j) = x >>> j"
77+
unfolding shiftr_def apply (induction j)
78+
apply simp unfolding funpow_Suc_right
79+
by (metis (no_types, lifting) comp_apply div_exp_eq funpow_swap1 power_Suc2 power_add power_one_right shiftr1_eq_div_2)
80+
81+
4882

4983
end

0 commit comments

Comments
 (0)