From 665b160192b2a925aa50aaad8787072f09eaa4fc Mon Sep 17 00:00:00 2001 From: Jason Gross Date: Fri, 19 May 2017 16:23:03 -0400 Subject: Add SubWithGetBorrow to reflective machinery After | File Name | Before || Change ------------------------------------------------------------------------------------------------- 12m37.09s | Total | 12m23.52s || +0m13.56s ------------------------------------------------------------------------------------------------- 0m12.09s | Compilers/Z/Syntax/Equality | 0m06.70s || +0m05.38s 0m56.82s | Compilers/Z/Named/RewriteAddToAdcInterp | 0m54.12s || +0m02.70s 2m20.25s | Specific/IntegrationTestLadderstep | 2m18.79s || +0m01.46s 0m13.83s | Compilers/Z/ArithmeticSimplifierInterp | 0m12.56s || +0m01.26s 1m38.90s | Spec/Test/X25519 | 1m38.46s || +0m00.43s 0m53.83s | Specific/IntegrationTestLadderstep130 | 0m53.93s || -0m00.10s 0m48.70s | Compilers/Z/ArithmeticSimplifierWf | 0m49.10s || -0m00.39s 0m39.72s | Spec/Ed25519 | 0m39.65s || +0m00.07s 0m22.19s | Primitives/EdDSARepChange | 0m22.08s || +0m00.11s 0m19.69s | Compilers/Named/MapCastWf | 0m19.63s || +0m00.06s 0m15.09s | Specific/IntegrationTestFreeze | 0m15.28s || -0m00.18s 0m11.78s | Specific/IntegrationTestMul | 0m11.61s || +0m00.16s 0m10.54s | Specific/IntegrationTestSub | 0m10.48s || +0m00.05s 0m10.46s | Specific/ArithmeticSynthesisTest | 0m10.47s || -0m00.00s 0m09.30s | Util/ZUtil | 0m09.21s || +0m00.08s 0m09.15s | Compilers/Named/MapCastInterp | 0m09.19s || -0m00.03s 0m09.14s | Specific/IntegrationTestSquare | 0m09.28s || -0m00.13s 0m08.82s | Arithmetic/MontgomeryReduction/Proofs | 0m08.78s || +0m00.04s 0m08.46s | LegacyArithmetic/ArchitectureToZLikeProofs | 0m08.38s || +0m00.08s 0m08.23s | LegacyArithmetic/Double/Proofs/Multiply | 0m08.16s || +0m00.07s 0m07.80s | Arithmetic/Core | 0m07.71s || +0m00.08s 0m07.70s | LegacyArithmetic/Double/Proofs/ShiftRightDoubleWordImmediate | 0m07.78s || -0m00.08s 0m06.72s | LegacyArithmetic/Double/Proofs/SpreadLeftImmediate | 0m06.79s || -0m00.07s 0m06.37s | Util/FixedWordSizesEquality | 0m06.33s || +0m00.04s 0m06.06s | Arithmetic/Saturated | 0m05.84s || +0m00.21s 0m05.43s | LegacyArithmetic/Double/Proofs/RippleCarryAddSub | 0m05.38s || +0m00.04s 0m05.41s | LegacyArithmetic/Pow2BaseProofs | 0m05.31s || +0m00.10s 0m05.05s | Specific/ArithmeticSynthesisTest130 | 0m05.09s || -0m00.04s 0m04.98s | Compilers/Z/Bounds/InterpretationLemmas/PullCast | 0m04.80s || +0m00.18s 0m03.94s | Arithmetic/BarrettReduction/HAC | 0m03.84s || +0m00.10s 0m03.79s | Util/ForLoop/Unrolling | 0m03.80s || -0m00.00s 0m03.45s | LegacyArithmetic/InterfaceProofs | 0m03.40s || +0m00.05s 0m03.23s | Arithmetic/BarrettReduction/Generalized | 0m03.07s || +0m00.16s 0m03.02s | Specific/FancyMachine256/Montgomery | 0m03.20s || -0m00.18s 0m03.00s | Compilers/Z/RewriteAddToAdcInterp | 0m02.94s || +0m00.06s 0m02.98s | Arithmetic/ModularArithmeticTheorems | 0m03.02s || -0m00.04s 0m02.94s | LegacyArithmetic/ZBoundedZ | 0m02.88s || +0m00.06s 0m02.82s | Specific/FancyMachine256/Barrett | 0m02.82s || +0m00.00s 0m02.64s | LegacyArithmetic/Double/Proofs/ShiftLeft | 0m02.54s || +0m00.10s 0m02.63s | LegacyArithmetic/Double/Proofs/Decode | 0m02.53s || +0m00.10s 0m02.62s | LegacyArithmetic/Double/Proofs/ShiftRight | 0m02.72s || -0m00.10s 0m02.56s | Compilers/Z/Bounds/InterpretationLemmas/IsBoundedBy | 0m02.25s || +0m00.31s 0m02.34s | Compilers/Z/Bounds/Relax | 0m02.40s || -0m00.06s 0m02.26s | LegacyArithmetic/BarretReduction | 0m02.25s || +0m00.00s 0m02.21s | Compilers/Z/Bounds/Pipeline/Definition | 0m02.13s || +0m00.08s 0m02.10s | Util/WordUtil | 0m02.07s || +0m00.03s 0m02.00s | Util/ForLoop/InvariantFramework | 0m01.98s || +0m00.02s 0m01.86s | Specific/FancyMachine256/Core | 0m01.82s || +0m00.04s 0m01.82s | Util/ZUtil/AddGetCarry | 0m01.61s || +0m00.20s 0m01.60s | Arithmetic/PrimeFieldTheorems | 0m01.45s || +0m00.15s 0m01.56s | Arithmetic/BarrettReduction/Wikipedia | 0m01.50s || +0m00.06s 0m01.55s | LegacyArithmetic/MontgomeryReduction | 0m01.53s || +0m00.02s 0m01.25s | Util/NumTheoryUtil | 0m00.96s || +0m00.29s 0m01.03s | Compilers/Z/RewriteAddToAdcWf | 0m01.02s || +0m00.01s 0m00.99s | Arithmetic/Karatsuba | 0m00.81s || +0m00.17s 0m00.98s | LegacyArithmetic/Double/Proofs/BitwiseOr | 0m00.99s || -0m00.01s 0m00.98s | Util/ZUtil/Pow2Mod | 0m00.97s || +0m00.01s 0m00.90s | LegacyArithmetic/Double/Proofs/LoadImmediate | 0m00.95s || -0m00.04s 0m00.80s | LegacyArithmetic/BaseSystemProofs | 0m00.88s || -0m00.07s 0m00.80s | Util/ZUtil/Testbit | 0m00.74s || +0m00.06s 0m00.79s | Compilers/Z/Bounds/Pipeline/ReflectiveTactics | 0m00.65s || +0m00.14s 0m00.76s | Compilers/Z/CNotations | 0m00.78s || -0m00.02s 0m00.76s | Util/ZUtil/Stabilization | 0m00.64s || +0m00.12s 0m00.68s | Util/IterAssocOp | 0m00.69s || -0m00.00s 0m00.66s | Compilers/Z/Syntax/Util | 0m00.66s || +0m00.00s 0m00.66s | Compilers/MapCastByDeBruijnInterp | 0m00.78s || -0m00.12s 0m00.64s | Compilers/Z/CommonSubexpressionElimination | 0m00.58s || +0m00.06s 0m00.63s | LegacyArithmetic/Interface | 0m00.56s || +0m00.06s 0m00.62s | Compilers/Z/Bounds/Pipeline | 0m00.53s || +0m00.08s 0m00.62s | Arithmetic/MontgomeryReduction/WordByWord/Definition | 0m00.67s || -0m00.05s 0m00.62s | LegacyArithmetic/Double/Proofs/SelectConditional | 0m00.58s || +0m00.04s 0m00.55s | Compilers/MapCastByDeBruijnWf | 0m00.62s || -0m00.06s 0m00.52s | Compilers/Z/Reify | 0m00.56s || -0m00.04s 0m00.52s | Compilers/Z/JavaNotations | 0m00.50s || +0m00.02s 0m00.52s | LegacyArithmetic/ZBounded | 0m00.54s || -0m00.02s 0m00.51s | Compilers/Z/Bounds/RoundUpLemmas | 0m00.44s || +0m00.07s 0m00.51s | Compilers/Z/Bounds/Pipeline/Glue | 0m00.47s || +0m00.04s 0m00.50s | Compilers/Z/Syntax | 0m00.44s || +0m00.06s 0m00.50s | Compilers/Z/ArithmeticSimplifier | 0m00.47s || +0m00.03s 0m00.50s | LegacyArithmetic/Double/Core | 0m00.53s || -0m00.03s 0m00.49s | Compilers/Z/Bounds/MapCastByDeBruijnInterp | 0m00.48s || +0m00.01s 0m00.48s | Arithmetic/ModularArithmeticPre | 0m00.47s || +0m00.01s 0m00.47s | Util/NUtil | 0m00.51s || -0m00.04s 0m00.47s | Compilers/Z/Bounds/MapCastByDeBruijnWf | 0m00.40s || +0m00.06s 0m00.47s | Spec/EdDSA | 0m00.51s || -0m00.04s 0m00.46s | Compilers/Z/Bounds/InterpretationLemmas/Tactics | 0m00.48s || -0m00.01s 0m00.46s | Compilers/Z/Named/RewriteAddToAdc | 0m00.49s || -0m00.02s 0m00.45s | Spec/ModularArithmetic | 0m00.45s || +0m00.00s 0m00.45s | LegacyArithmetic/Double/Proofs/ShiftLeftRightTactic | 0m00.54s || -0m00.09s 0m00.44s | Arithmetic/MontgomeryReduction/Definition | 0m00.45s || -0m00.01s 0m00.44s | Util/ForLoop/Tests | 0m00.43s || +0m00.01s 0m00.44s | Compilers/Z/MapCastByDeBruijn | 0m00.49s || -0m00.04s 0m00.44s | LegacyArithmetic/ArchitectureToZLike | 0m00.44s || +0m00.00s 0m00.43s | LegacyArithmetic/BaseSystem | 0m00.41s || +0m00.02s 0m00.43s | Compilers/Z/InlineInterp | 0m00.36s || +0m00.07s 0m00.43s | Compilers/Z/MapCastByDeBruijnWf | 0m00.40s || +0m00.02s 0m00.42s | LegacyArithmetic/Pow2Base | 0m00.48s || -0m00.06s 0m00.42s | Compilers/Z/CommonSubexpressionEliminationWf | 0m00.40s || +0m00.01s 0m00.42s | Compilers/Z/Bounds/Interpretation | 0m00.46s || -0m00.04s 0m00.42s | Specific/IntegrationTestDisplayCommon | 0m00.36s || +0m00.06s 0m00.42s | Compilers/Z/RewriteAddToAdc | 0m00.41s || +0m00.01s 0m00.42s | Util/ZUtil/Morphisms | 0m00.38s || +0m00.03s 0m00.42s | Compilers/Z/InlineWf | 0m00.44s || -0m00.02s 0m00.41s | Compilers/Z/CommonSubexpressionEliminationInterp | 0m00.39s || +0m00.01s 0m00.41s | Compilers/Z/HexNotationConstants | 0m00.38s || +0m00.02s 0m00.40s | Compilers/Z/Bounds/MapCastByDeBruijn | 0m00.36s || +0m00.04s 0m00.39s | Compilers/Z/Named/DeadCodeElimination | 0m00.36s || +0m00.03s 0m00.38s | Compilers/Z/Named/DeadCodeEliminationInterp | 0m00.40s || -0m00.02s 0m00.37s | Compilers/Z/MapCastByDeBruijnInterp | 0m00.40s || -0m00.03s 0m00.36s | Compilers/Z/OpInversion | 0m00.36s || +0m00.00s 0m00.36s | Compilers/Z/FoldTypes | 0m00.36s || +0m00.00s 0m00.35s | Compilers/Z/Bounds/Pipeline/OutputType | 0m00.33s || +0m00.01s 0m00.34s | Compilers/Z/BinaryNotationConstants | 0m00.36s || -0m00.01s 0m00.34s | Compilers/Z/Inline | 0m00.41s || -0m00.06s 0m00.34s | Compilers/Z/ArithmeticSimplifierUtil | 0m00.35s || -0m00.00s 0m00.31s | Util/ZUtil/Tactics/Ztestbit | 0m00.30s || +0m00.01s 0m00.31s | Util/ZUtil/Tactics | 0m00.30s || +0m00.01s 0m00.30s | Util/ZUtil/Definitions | 0m00.27s || +0m00.02s 0m00.30s | Util/ZUtil/Zselect | 0m00.30s || +0m00.00s --- src/Compilers/Z/ArithmeticSimplifier.v | 3 ++ src/Compilers/Z/Bounds/Interpretation.v | 33 ++++++++++++++++++---- .../Z/Bounds/InterpretationLemmas/IsBoundedBy.v | 24 ++++++++++++---- src/Compilers/Z/CommonSubexpressionElimination.v | 20 +++++++++++-- src/Compilers/Z/Syntax.v | 4 +++ src/Compilers/Z/Syntax/Equality.v | 6 ++++ src/Compilers/Z/Syntax/Util.v | 2 ++ src/Util/ZUtil/Definitions.v | 10 +++++++ src/Util/ZUtil/Morphisms.v | 2 ++ 9 files changed, 92 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/Compilers/Z/ArithmeticSimplifier.v b/src/Compilers/Z/ArithmeticSimplifier.v index f0d3e19ab..7a2a73434 100644 --- a/src/Compilers/Z/ArithmeticSimplifier.v +++ b/src/Compilers/Z/ArithmeticSimplifier.v @@ -32,6 +32,7 @@ Section language. | OpConst _ z => fun _ _ => const_of _ z | Opp TZ TZ => fun _ args => neg_expr _ args | AddWithGetCarry _ _ _ _ _ _ => fun _ _ => I + | SubWithGetBorrow _ _ _ _ _ _ => fun _ _ => I | _ => fun e _ => gen_expr _ e end (Op opc args) args) | TT => Some tt @@ -187,6 +188,8 @@ Section language. | Zselect _ _ _ _ as opc | AddWithCarry _ _ _ _ as opc | AddWithGetCarry _ _ _ _ _ _ as opc + | SubWithBorrow _ _ _ _ as opc + | SubWithGetBorrow _ _ _ _ _ _ as opc => Op opc end. End with_var. diff --git a/src/Compilers/Z/Bounds/Interpretation.v b/src/Compilers/Z/Bounds/Interpretation.v index f4cbb3bbd..dc29fe654 100644 --- a/src/Compilers/Z/Bounds/Interpretation.v +++ b/src/Compilers/Z/Bounds/Interpretation.v @@ -105,6 +105,10 @@ Module Import Bounds. := t_map3' Z.add_with_carry. Definition add_with_carry : t -> t -> t -> t := t_map3 Z.add_with_carry. + Definition sub_with_borrow' : t -> t -> t -> t + := t_map3' Z.sub_with_borrow. + Definition sub_with_borrow : t -> t -> t -> t + := t_map3 Z.sub_with_borrow. Definition modulo_pow2_constant : Z -> t -> t := fun e x => let d := 2^e in @@ -116,6 +120,11 @@ Module Import Bounds. => let d := 2^e in let (l, u) := (lower x, upper x) in truncation_bounds {| lower := l / d ; upper := u / d |}. + Definition opp_div_pow2_constant : Z -> t -> t + := fun e x + => let d := 2^e in + let (l, u) := (lower x, upper x) in + truncation_bounds {| lower := -(u / d) ; upper := -(l / d) |}. Definition neg' (int_width : Z) : t -> t := fun v => let (lb, ub) := v in @@ -143,12 +152,22 @@ Module Import Bounds. := truncation_bounds (cmovle' r1 r2). End with_bitwidth. Section with_bitwidth2. - Context (bit_width1 bit_width2 : option Z). - Definition add_with_get_carry (carry_boundary_bit_width : Z) : t -> t -> t -> t * t + Context (bit_width1 bit_width2 : option Z) + (carry_boundary_bit_width : Z). + Definition get_carry : t -> t * t + := fun v => + (modulo_pow2_constant bit_width1 carry_boundary_bit_width v, + div_pow2_constant bit_width2 carry_boundary_bit_width v). + Definition get_borrow : t -> t * t + := fun v => + (modulo_pow2_constant bit_width1 carry_boundary_bit_width v, + opp_div_pow2_constant bit_width2 carry_boundary_bit_width v). + Definition add_with_get_carry : t -> t -> t -> t * t := fun c x y - => let xpy := add_with_carry' c x y in - (modulo_pow2_constant bit_width1 carry_boundary_bit_width xpy, - div_pow2_constant bit_width2 carry_boundary_bit_width xpy). + => get_carry (add_with_carry' c x y). + Definition sub_with_get_borrow : t -> t -> t -> t * t + := fun c x y + => get_borrow (sub_with_borrow' c x y). End with_bitwidth2. Module Export Notations. @@ -189,6 +208,10 @@ Module Import Bounds. | AddWithGetCarry carry_boundary_bit_width _ _ _ T1 T2 => fun cxy => let '(c, x, y) := eta3 cxy in add_with_get_carry (bit_width_of_base_type T1) (bit_width_of_base_type T2) carry_boundary_bit_width c x y + | SubWithBorrow _ _ _ T => fun cxy => let '(c, x, y) := eta3 cxy in sub_with_borrow (bit_width_of_base_type T) c x y + | SubWithGetBorrow carry_boundary_bit_width _ _ _ T1 T2 + => fun cxy => let '(c, x, y) := eta3 cxy in + sub_with_get_borrow (bit_width_of_base_type T1) (bit_width_of_base_type T2) carry_boundary_bit_width c x y end%bounds. Definition of_Z (z : Z) : t := ZToZRange z. diff --git a/src/Compilers/Z/Bounds/InterpretationLemmas/IsBoundedBy.v b/src/Compilers/Z/Bounds/InterpretationLemmas/IsBoundedBy.v index c74c319d5..68cc13d98 100644 --- a/src/Compilers/Z/Bounds/InterpretationLemmas/IsBoundedBy.v +++ b/src/Compilers/Z/Bounds/InterpretationLemmas/IsBoundedBy.v @@ -268,7 +268,7 @@ Proof. repeat (apply Z.max_case_strong || apply Zabs_ind); omega. Qed. -Local Existing Instances Z.log2_up_le_Proper Z.add_le_Proper. +Local Existing Instances Z.log2_up_le_Proper Z.add_le_Proper Z.sub_with_borrow_le_Proper. Lemma land_upper_lor_land_bounds a b : Z.abs (Z.land a b) <= Bounds.upper_lor_and_bounds (Z.abs a) (Z.abs b). Proof. @@ -324,6 +324,10 @@ Local Arguments Z.pow : simpl never. Local Arguments Z.add !_ !_. Local Existing Instances Z.add_le_Proper Z.sub_le_flip_le_Proper Z.log2_up_le_Proper Z.pow_Zpos_le_Proper Z.sub_le_eq_Proper Z.add_with_carry_le_Proper. Local Hint Extern 1 => progress cbv beta iota : typeclass_instances. +Local Ltac ibbio_do_cbv := + cbv [Bounds.interp_op Zinterp_op Z.add_with_get_carry SmartFlatTypeMapUnInterp Bounds.add_with_get_carry Bounds.sub_with_get_borrow Bounds.get_carry Bounds.get_borrow Z.get_carry cast_const]; cbn [fst snd]. +Local Ltac ibbio_prefin_by_apply := + [ > | intros; apply is_bounded_by_truncation_bounds | simpl; reflexivity ]. Lemma is_bounded_by_interp_op t tR (opc : op t tR) (bs : interp_flat_type Bounds.interp_base_type _) (v : interp_flat_type interp_base_type _) @@ -332,12 +336,17 @@ Lemma is_bounded_by_interp_op t tR (opc : op t tR) Proof. destruct opc; [ apply is_bounded_by_truncation_bounds.. - | split; - cbv [Bounds.interp_op Zinterp_op Z.add_with_get_carry SmartFlatTypeMapUnInterp Bounds.add_with_get_carry Z.get_carry cast_const]; cbn [fst snd]; + | split; ibbio_do_cbv; [ eapply is_bounded_by_compose with (T1:=TZ) (f_v := fun v => ZToInterp (v mod _)) (v:=ZToInterp _); - [ | intros; apply is_bounded_by_truncation_bounds | simpl; reflexivity ] + ibbio_prefin_by_apply | eapply is_bounded_by_compose with (T1:=TZ) (f_v := fun v => ZToInterp (v / _)) (v:=ZToInterp _); - [ | intros; apply is_bounded_by_truncation_bounds | simpl; reflexivity ] ] ]; + ibbio_prefin_by_apply ] + | apply is_bounded_by_truncation_bounds + | split; ibbio_do_cbv; + [ eapply is_bounded_by_compose with (T1:=TZ) (f_v := fun v => ZToInterp (v mod _)) (v:=ZToInterp _); + ibbio_prefin_by_apply + | eapply is_bounded_by_compose with (T1:=TZ) (f_v := fun v => ZToInterp (-(v / _))) (v:=ZToInterp _); + ibbio_prefin_by_apply ] ]; repeat first [ progress simpl in * | progress cbv [interp_op lift_op cast_const Bounds.interp_base_type Bounds.is_bounded_by' ZRange.is_bounded_by'] in * | progress destruct_head'_prod @@ -388,4 +397,9 @@ Proof. { apply Z.mod_bound_min_max; auto. } { apply (@monotone_eight_corners true true true _ _ _); split; auto. } { auto with zarith. } + { apply (@monotone_eight_corners false true false _ _ _); split; auto. } + { apply (@monotone_eight_corners false true false _ _ _); split; auto. } + { apply Z.mod_bound_min_max; auto. } + { apply (@monotone_eight_corners false true false _ _ _); split; auto. } + { auto with zarith. } Qed. diff --git a/src/Compilers/Z/CommonSubexpressionElimination.v b/src/Compilers/Z/CommonSubexpressionElimination.v index 81f6553ba..d545d9b47 100644 --- a/src/Compilers/Z/CommonSubexpressionElimination.v +++ b/src/Compilers/Z/CommonSubexpressionElimination.v @@ -23,12 +23,15 @@ Inductive symbolic_op := | SZselect | SAddWithCarry | SAddWithGetCarry (bitwidth : Z) +| SSubWithBorrow +| SSubWithGetBorrow (bitwidth : Z) . Definition symbolic_op_leb (x y : symbolic_op) : bool := match x, y with | SOpConst z1, SOpConst z2 => Z.leb z1 z2 | SAddWithGetCarry bw1, SAddWithGetCarry bw2 => Z.leb bw1 bw2 + | SSubWithGetBorrow bw1, SSubWithGetBorrow bw2 => Z.leb bw1 bw2 | SOpConst _, _ => true | _, SOpConst _ => false | SAdd, _ => true @@ -51,8 +54,12 @@ Definition symbolic_op_leb (x y : symbolic_op) : bool | _, SZselect => false | SAddWithCarry, _ => true | _, SAddWithCarry => false - (*| SAddWithGetCarry _, _ => true - | _, SAddWithGetCarry _ => false*) + | SAddWithGetCarry _, _ => true + | _, SAddWithGetCarry _ => false + | SSubWithBorrow, _ => true + | _, SSubWithBorrow => false + (*| SSubWithGetBorrow _, _ => true + | _, SSubWithGetBorrow _ => false*) end. Local Notation symbolic_expr := (@symbolic_expr base_type symbolic_op). @@ -73,6 +80,8 @@ Definition symbolize_op s d (opc : op s d) : symbolic_op | Zselect T1 T2 T3 Tout => SZselect | AddWithCarry T1 T2 T3 Tout => SAddWithCarry | AddWithGetCarry bitwidth T1 T2 T3 Tout1 Tout2 => SAddWithGetCarry bitwidth + | SubWithBorrow T1 T2 T3 Tout => SSubWithBorrow + | SubWithGetBorrow bitwidth T1 T2 T3 Tout1 Tout2 => SSubWithGetBorrow bitwidth end. Definition denote_symbolic_op s d (opc : symbolic_op) : option (op s d) @@ -90,6 +99,9 @@ Definition denote_symbolic_op s d (opc : symbolic_op) : option (op s d) | SAddWithCarry, Prod (Prod (Tbase _) (Tbase _)) (Tbase _), Tbase _ => Some (AddWithCarry _ _ _ _) | SAddWithGetCarry bitwidth, Prod (Prod (Tbase _) (Tbase _)) (Tbase _), Prod (Tbase _) (Tbase _) => Some (AddWithGetCarry bitwidth _ _ _ _ _) + | SSubWithBorrow, Prod (Prod (Tbase _) (Tbase _)) (Tbase _), Tbase _ => Some (SubWithBorrow _ _ _ _) + | SSubWithGetBorrow bitwidth, Prod (Prod (Tbase _) (Tbase _)) (Tbase _), Prod (Tbase _) (Tbase _) + => Some (SubWithGetBorrow bitwidth _ _ _ _ _) | SAdd, _, _ | SSub, _, _ | SMul, _, _ @@ -102,6 +114,8 @@ Definition denote_symbolic_op s d (opc : symbolic_op) : option (op s d) | SZselect, _, _ | SAddWithCarry, _, _ | SAddWithGetCarry _, _, _ + | SSubWithBorrow, _, _ + | SSubWithGetBorrow _, _, _ => None end. @@ -172,6 +186,8 @@ Definition normalize_symbolic_expr_mod_c (opc : symbolic_op) (args : symbolic_ex | SZselect | SAddWithCarry | SAddWithGetCarry _ + | SSubWithBorrow + | SSubWithGetBorrow _ => args end. diff --git a/src/Compilers/Z/Syntax.v b/src/Compilers/Z/Syntax.v index 7d0c84421..5bfa1168c 100644 --- a/src/Compilers/Z/Syntax.v +++ b/src/Compilers/Z/Syntax.v @@ -30,6 +30,8 @@ Inductive op : flat_type base_type -> flat_type base_type -> Type := | Zselect T1 T2 T3 Tout : op (Tbase T1 * Tbase T2 * Tbase T3) (Tbase Tout) | AddWithCarry T1 T2 T3 Tout : op (Tbase T1 * Tbase T2 * Tbase T3) (Tbase Tout) | AddWithGetCarry (bitwidth : Z) T1 T2 T3 Tout1 Tout2 : op (Tbase T1 * Tbase T2 * Tbase T3) (Tbase Tout1 * Tbase Tout2) +| SubWithBorrow T1 T2 T3 Tout : op (Tbase T1 * Tbase T2 * Tbase T3) (Tbase Tout) +| SubWithGetBorrow (bitwidth : Z) T1 T2 T3 Tout1 Tout2 : op (Tbase T1 * Tbase T2 * Tbase T3) (Tbase Tout1 * Tbase Tout2) . Definition interp_base_type (v : base_type) : Type := @@ -85,6 +87,8 @@ Definition Zinterp_op src dst (f : op src dst) | Zselect _ _ _ _ => fun ctf => let '(c, t, f) := eta3 ctf in Z.zselect c t f | AddWithCarry _ _ _ _ => fun cxy => let '(c, x, y) := eta3 cxy in Z.add_with_carry c x y | AddWithGetCarry bitwidth _ _ _ _ _ => fun cxy => let '(c, x, y) := eta3 cxy in Z.add_with_get_carry bitwidth c x y + | SubWithBorrow _ _ _ _ => fun cxy => let '(c, x, y) := eta3 cxy in Z.sub_with_borrow c x y + | SubWithGetBorrow bitwidth _ _ _ _ _ => fun cxy => let '(c, x, y) := eta3 cxy in Z.sub_with_get_borrow bitwidth c x y end%Z. Definition interp_op src dst (f : op src dst) : interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst diff --git a/src/Compilers/Z/Syntax/Equality.v b/src/Compilers/Z/Syntax/Equality.v index b2075c49c..a9003d354 100644 --- a/src/Compilers/Z/Syntax/Equality.v +++ b/src/Compilers/Z/Syntax/Equality.v @@ -47,6 +47,10 @@ Definition op_beq_hetero {t1 tR t1' tR'} (f : op t1 tR) (g : op t1' tR') : bool => base_type_beq T1 T1' && base_type_beq T2 T2' && base_type_beq T3 T3' && base_type_beq Tout Tout' | AddWithGetCarry bitwidth T1 T2 T3 Tout1 Tout2, AddWithGetCarry bitwidth' T1' T2' T3' Tout1' Tout2' => Z.eqb bitwidth bitwidth' && base_type_beq T1 T1' && base_type_beq T2 T2' && base_type_beq T3 T3' && base_type_beq Tout1 Tout1' && base_type_beq Tout2 Tout2' + | SubWithBorrow T1 T2 T3 Tout, SubWithBorrow T1' T2' T3' Tout' + => base_type_beq T1 T1' && base_type_beq T2 T2' && base_type_beq T3 T3' && base_type_beq Tout Tout' + | SubWithGetBorrow bitwidth T1 T2 T3 Tout1 Tout2, SubWithGetBorrow bitwidth' T1' T2' T3' Tout1' Tout2' + => Z.eqb bitwidth bitwidth' && base_type_beq T1 T1' && base_type_beq T2 T2' && base_type_beq T3 T3' && base_type_beq Tout1 Tout1' && base_type_beq Tout2 Tout2' | OpConst _ _, _ | Add _ _ _, _ | Sub _ _ _, _ @@ -59,6 +63,8 @@ Definition op_beq_hetero {t1 tR t1' tR'} (f : op t1 tR) (g : op t1' tR') : bool | Zselect _ _ _ _, _ | AddWithCarry _ _ _ _, _ | AddWithGetCarry _ _ _ _ _ _, _ + | SubWithBorrow _ _ _ _, _ + | SubWithGetBorrow _ _ _ _ _ _, _ => false end%bool. diff --git a/src/Compilers/Z/Syntax/Util.v b/src/Compilers/Z/Syntax/Util.v index daf3d65be..2338efc48 100644 --- a/src/Compilers/Z/Syntax/Util.v +++ b/src/Compilers/Z/Syntax/Util.v @@ -71,6 +71,8 @@ Definition genericize_op {var' src dst} (opc : op src dst) {f} | Zselect _ _ _ _ => fun _ _ => Zselect _ _ _ _ | AddWithCarry _ _ _ _ => fun _ _ => AddWithCarry _ _ _ _ | AddWithGetCarry bitwidth _ _ _ _ _ => fun _ _ => AddWithGetCarry bitwidth _ _ _ _ _ + | SubWithBorrow _ _ _ _ => fun _ _ => SubWithBorrow _ _ _ _ + | SubWithGetBorrow bitwidth _ _ _ _ _ => fun _ _ => SubWithGetBorrow bitwidth _ _ _ _ _ end. Lemma cast_const_id {t} v diff --git a/src/Util/ZUtil/Definitions.v b/src/Util/ZUtil/Definitions.v index 4a5d3a0ab..6fc969dfd 100644 --- a/src/Util/ZUtil/Definitions.v +++ b/src/Util/ZUtil/Definitions.v @@ -18,6 +18,16 @@ Module Z. Definition add_get_carry (bitwidth : Z) (x y : Z) : Z * Z := add_with_get_carry bitwidth 0 x y. + Definition get_borrow (bitwidth : Z) (v : Z) : Z * Z + := let '(v, c) := get_carry bitwidth v in + (v, -c). + Definition sub_with_borrow (c : Z) (x y : Z) : Z + := add_with_carry (-c) x (-y). + Definition sub_with_get_borrow (bitwidth : Z) (c : Z) (x y : Z) : Z * Z + := get_borrow bitwidth (sub_with_borrow c x y). + Definition sub_get_borrow (bitwidth : Z) (x y : Z) : Z * Z + := sub_with_get_borrow bitwidth 0 x y. + (* splits at [bound], not [2^bitwidth]; wrapper to make add_getcarry work if input is not known to be a power of 2 *) Definition add_get_carry_full (bound : Z) (x y : Z) : Z * Z diff --git a/src/Util/ZUtil/Morphisms.v b/src/Util/ZUtil/Morphisms.v index e0ab179a8..285fa5261 100644 --- a/src/Util/ZUtil/Morphisms.v +++ b/src/Util/ZUtil/Morphisms.v @@ -46,4 +46,6 @@ Module Z. Proof. intros ???; apply Z.pow_le_mono_r; try reflexivity; try assumption. Qed. Lemma add_with_carry_le_Proper : Proper (Z.le ==> Z.le ==> Z.le ==> Z.le) Z.add_with_carry. Proof. unfold Z.add_with_carry; repeat (omega || intro). Qed. + Lemma sub_with_borrow_le_Proper : Proper (Basics.flip Z.le ==> Z.le ==> Basics.flip Z.le ==> Z.le) Z.sub_with_borrow. + Proof. unfold Z.sub_with_borrow, Z.add_with_carry, Basics.flip; repeat (omega || intro). Qed. End Z. -- cgit v1.2.3