aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jason Gross <jgross@mit.edu>2017-05-19 16:23:03 -0400
committerGravatar Jason Gross <jasongross9@gmail.com>2017-05-20 10:58:45 -0400
commit665b160192b2a925aa50aaad8787072f09eaa4fc (patch)
tree3a627ee9e30ad3aa42479931b67bd834123ece20 /src
parentd1821fac9cf45b4c15dde242856843e853ba7087 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/Compilers/Z/ArithmeticSimplifier.v3
-rw-r--r--src/Compilers/Z/Bounds/Interpretation.v33
-rw-r--r--src/Compilers/Z/Bounds/InterpretationLemmas/IsBoundedBy.v24
-rw-r--r--src/Compilers/Z/CommonSubexpressionElimination.v20
-rw-r--r--src/Compilers/Z/Syntax.v4
-rw-r--r--src/Compilers/Z/Syntax/Equality.v6
-rw-r--r--src/Compilers/Z/Syntax/Util.v2
-rw-r--r--src/Util/ZUtil/Definitions.v10
-rw-r--r--src/Util/ZUtil/Morphisms.v2
9 files changed, 92 insertions, 12 deletions
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.