aboutsummaryrefslogtreecommitdiff
path: root/src/LegacyArithmetic/Interface.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/LegacyArithmetic/Interface.v')
-rw-r--r--src/LegacyArithmetic/Interface.v451
1 files changed, 0 insertions, 451 deletions
diff --git a/src/LegacyArithmetic/Interface.v b/src/LegacyArithmetic/Interface.v
deleted file mode 100644
index 9a652bbd4..000000000
--- a/src/LegacyArithmetic/Interface.v
+++ /dev/null
@@ -1,451 +0,0 @@
-(*** Interface for bounded arithmetic *)
-Require Import Coq.ZArith.ZArith.
-Require Import Crypto.Util.ZUtil.Notations.
-
-Require Import Crypto.Util.Tuple.
-Require Import Crypto.Util.AutoRewrite.
-Require Import Crypto.Util.Notations.
-
-Local Open Scope type_scope.
-Local Open Scope Z_scope.
-
-Class decoder (n : Z) W :=
- { decode : W -> Z }.
-Coercion decode : decoder >-> Funclass.
-Global Arguments decode {n W _} _.
-
-Class is_decode {n W} (decode : decoder n W) :=
- decode_range : forall x, 0 <= decode x < 2^n.
-
-Class bounded_in_range_cls (x y z : Z) := is_bounded_in_range : x <= y < z.
-Ltac bounded_solver_tac :=
- solve [ eassumption | typeclasses eauto | omega ].
-Hint Extern 0 (bounded_in_range_cls _ _ _) => unfold bounded_in_range_cls; bounded_solver_tac : typeclass_instances.
-Global Arguments bounded_in_range_cls / _ _ _.
-Global Instance decode_range_bound {n W} {decode : decoder n W} {H : is_decode decode}
- : forall x, bounded_in_range_cls 0 (decode x) (2^n)
- := H.
-
-Class bounded_le_cls (x y : Z) := is_bounded_le : x <= y.
-Hint Extern 0 (bounded_le_cls _ _) => unfold bounded_le_cls; bounded_solver_tac : typeclass_instances.
-Global Arguments bounded_le_cls / _ _.
-
-Inductive bounded_decode_pusher_tag := decode_tag.
-
-Ltac push_decode_step :=
- match goal with
- | [ |- context[@decode ?n ?W ?decoder ?w] ]
- => tc_rewrite (decode_tag) (@decode n W decoder w) ->
- | [ |- context[match @fst ?A ?B ?x with true => 1 | false => 0 end] ]
- => tc_rewrite (decode_tag) (match @fst A B x with true => 1 | false => 0 end) ->
- | [ |- context[@fst bool ?B ?x] ]
- => tc_rewrite (decode_tag) (@fst bool B x) ->
- end.
-Ltac push_decode := repeat push_decode_step.
-Ltac pull_decode_step :=
- match goal with
- | [ |- context[?E] ]
- => lazymatch type of E with
- | Z => idtac
- | bool => idtac
- end;
- tc_rewrite (decode_tag) <- E
- end.
-Ltac pull_decode := repeat pull_decode_step.
-
-Delimit Scope bounded_rewrite_scope with bounded_rewrite.
-
-Infix "<~=~>" := (rewrite_eq decode_tag) : bounded_rewrite_scope.
-Infix "=~>" := (rewrite_left_to_right_eq decode_tag) : bounded_rewrite_scope.
-Infix "<~=" := (rewrite_right_to_left_eq decode_tag) : bounded_rewrite_scope.
-Notation "x <= y" := (bounded_le_cls x y) : bounded_rewrite_scope.
-Notation "x <= y < z" := (bounded_in_range_cls x y z) : bounded_rewrite_scope.
-
-Module Import BoundedRewriteNotations.
- Infix "<~=~>" := (rewrite_eq decode_tag) : type_scope.
- Infix "=~>" := (rewrite_left_to_right_eq decode_tag) : type_scope.
- Infix "<~=" := (rewrite_right_to_left_eq decode_tag) : type_scope.
- Open Scope bounded_rewrite_scope.
-End BoundedRewriteNotations.
-
-(** This is required for typeclass resolution to be fast. *)
-Typeclasses Opaque decode.
-
-Section InstructionGallery.
- Context (n : Z) (* bit-width of width of [W] *)
- {W : Type} (* bounded type, [W] for word *)
- (Wdecoder : decoder n W).
- Local Notation imm := Z (only parsing). (* immediate (compile-time) argument *)
-
- Class load_immediate := { ldi : imm -> W }.
- Global Coercion ldi : load_immediate >-> Funclass.
-
- Class is_load_immediate {ldi : load_immediate} :=
- decode_load_immediate :> forall x, 0 <= x < 2^n -> decode (ldi x) =~> x.
-
- Class shift_right_doubleword_immediate := { shrd : W -> W -> imm -> W }.
- Global Coercion shrd : shift_right_doubleword_immediate >-> Funclass.
-
- Class is_shift_right_doubleword_immediate (shrd : shift_right_doubleword_immediate) :=
- decode_shift_right_doubleword :>
- forall high low count,
- 0 <= count < n
- -> decode (shrd high low count) <~=~> (((decode high << n) + decode low) >> count) mod 2^n.
-
- (** Quoting http://www.felixcloutier.com/x86/SHRD.html:
-
- If the count is 1 or greater, the CF flag is filled with the
- last bit shifted out of the destination operand and the SF, ZF,
- and PF flags are set according to the value of the result. For a
- 1-bit shift, the OF flag is set if a sign change occurred;
- otherwise, it is cleared. For shifts greater than 1 bit, the OF
- flag is undefined. If a shift occurs, the AF flag is
- unde-fined. If the count operand is 0, the flags are not
- affected. If the count is greater than the operand size, the
- flags are undefined.
-
- We ignore the CF in the specification; we only have it so that
- we can ensure that the CF flag gets appropriately clobbered. *)
- Class shift_right_doubleword_immediate_with_CF := { shrdf : W -> W -> imm -> bool * W }.
- Global Coercion shrdf : shift_right_doubleword_immediate_with_CF >-> Funclass.
-
- Class is_shift_right_doubleword_immediate_with_CF (shrdf : shift_right_doubleword_immediate_with_CF) :=
- decode_snd_shift_right_doubleword_with_CF :>
- forall high low count,
- 0 <= count < n
- -> decode (snd (shrdf high low count)) <~=~> (((decode high << n) + decode low) >> count) mod 2^n.
-
- Class shift_left_immediate := { shl : W -> imm -> W }.
- Global Coercion shl : shift_left_immediate >-> Funclass.
-
- Class is_shift_left_immediate (shl : shift_left_immediate) :=
- decode_shift_left_immediate :>
- forall r count, 0 <= count < n -> decode (shl r count) <~=~> (decode r << count) mod 2^n.
-
- (** Quoting http://www.felixcloutier.com/x86/SAL:SAR:SHL:SHR.html:
-
- The CF flag contains the value of the last bit shifted out of
- the destination operand; it is undefined for SHL and SHR
- instructions where the count is greater than or equal to the
- size (in bits) of the destination operand. The OF flag is
- affected only for 1-bit shifts (see “Description” above);
- otherwise, it is undefined. The SF, ZF, and PF flags are set
- according to the result. If the count is 0, the flags are not
- affected. For a non-zero count, the AF flag is undefined.
-
- We ignore the CF in the specification; we only have it so that
- we can ensure that the CF flag gets appropriately clobbered. *)
- Class shift_left_immediate_with_CF := { shlf : W -> imm -> bool * W }.
- Global Coercion shlf : shift_left_immediate_with_CF >-> Funclass.
-
- Class is_shift_left_immediate_with_CF (shlf : shift_left_immediate_with_CF) :=
- decode_shift_left_immediate_with_CF :>
- forall r count, 0 <= count < n -> decode (snd (shlf r count)) <~=~> (decode r << count) mod 2^n.
-
- Class shift_right_immediate := { shr : W -> imm -> W }.
- Global Coercion shr : shift_right_immediate >-> Funclass.
-
- Class is_shift_right_immediate (shr : shift_right_immediate) :=
- decode_shift_right_immediate :>
- forall r count, 0 <= count < n -> decode (shr r count) <~=~> (decode r >> count).
-
- Class shift_right_immediate_with_CF := { shrf : W -> imm -> bool * W }.
- Global Coercion shrf : shift_right_immediate_with_CF >-> Funclass.
-
- Class is_shift_right_immediate_with_CF (shrf : shift_right_immediate_with_CF) :=
- decode_shift_right_immediate_with_CF :>
- forall r count, 0 <= count < n -> decode (snd (shrf r count)) <~=~> (decode r >> count).
-
- Class spread_left_immediate := { sprl : W -> imm -> tuple W 2 (* [(low, high)] *) }.
- Global Coercion sprl : spread_left_immediate >-> Funclass.
-
- Class is_spread_left_immediate (sprl : spread_left_immediate) :=
- {
- decode_fst_spread_left_immediate :> forall r count,
- 0 <= count < n
- -> decode (fst (sprl r count)) =~> (decode r << count) mod 2^n;
- decode_snd_spread_left_immediate :> forall r count,
- 0 <= count < n
- -> decode (snd (sprl r count)) =~> (decode r << count) >> n
-
- }.
-
- Class mask_keep_low := { mkl :> W -> imm -> W }.
- Global Coercion mkl : mask_keep_low >-> Funclass.
-
- Class is_mask_keep_low (mkl : mask_keep_low) :=
- decode_mask_keep_low :> forall r count,
- 0 <= count < n -> decode (mkl r count) <~=~> decode r mod 2^count.
-
- Class bitwise_and := { and : W -> W -> W }.
- Global Coercion and : bitwise_and >-> Funclass.
-
- Class is_bitwise_and (and : bitwise_and) :=
- {
- decode_bitwise_and :> forall x y, decode (and x y) <~=~> Z.land (decode x) (decode y)
- }.
-
- (** Quoting http://www.felixcloutier.com/x86/AND.html:
-
- The OF and CF flags are cleared; the SF, ZF, and PF flags are set
- according to the result. The state of the AF flag is
- undefined. *)
- Class bitwise_and_with_CF := { andf : W -> W -> bool * W }.
- Global Coercion andf : bitwise_and_with_CF >-> Funclass.
-
- Class is_bitwise_and_with_CF (andf : bitwise_and_with_CF) :=
- {
- decode_snd_bitwise_and_with_CF :> forall x y, decode (snd (andf x y)) <~=~> Z.land (decode x) (decode y);
- fst_bitwise_and_with_CF :> forall x y, fst (andf x y) =~> false
- }.
-
- Class bitwise_or := { or : W -> W -> W }.
- Global Coercion or : bitwise_or >-> Funclass.
-
- Class is_bitwise_or (or : bitwise_or) :=
- {
- decode_bitwise_or :> forall x y, decode (or x y) <~=~> Z.lor (decode x) (decode y)
- }.
-
- (** Quoting http://www.felixcloutier.com/x86/OR.html:
-
- The OF or CF flags are cleared; the SF, ZF, or PF flags are set
- according to the result. The state of the AF flag is
- undefined. *)
- Class bitwise_or_with_CF := { orf : W -> W -> bool * W }.
- Global Coercion orf : bitwise_or_with_CF >-> Funclass.
-
- Class is_bitwise_or_with_CF (orf : bitwise_or_with_CF) :=
- {
- decode_snd_bitwise_or_with_CF :> forall x y, decode (snd (orf x y)) <~=~> Z.lor (decode x) (decode y);
- fst_bitwise_or_with_CF :> forall x y, fst (orf x y) =~> false
- }.
-
- Local Notation bit b := (if b then 1 else 0).
-
- Class add_with_carry := { adc : W -> W -> bool -> bool * W }.
- Global Coercion adc : add_with_carry >-> Funclass.
-
- Class is_add_with_carry (adc : add_with_carry) :=
- {
- bit_fst_add_with_carry :> forall x y c, bit (fst (adc x y c)) <~=~> (decode x + decode y + bit c) >> n;
- decode_snd_add_with_carry :> forall x y c, decode (snd (adc x y c)) <~=~> (decode x + decode y + bit c) mod (2^n)
- }.
-
- Class sub_with_carry := { subc : W -> W -> bool -> bool * W }.
- Global Coercion subc : sub_with_carry >-> Funclass.
-
- Class is_sub_with_carry (subc:W->W->bool->bool*W) :=
- {
- fst_sub_with_carry :> forall x y c, fst (subc x y c) <~=~> ((decode x - decode y - bit c) <? 0);
- decode_snd_sub_with_carry :> forall x y c, decode (snd (subc x y c)) <~=~> (decode x - decode y - bit c) mod 2^n
- }.
-
- Class multiply := { mul : W -> W -> W }.
- Global Coercion mul : multiply >-> Funclass.
-
- Class is_mul (mul : multiply) :=
- decode_mul :> forall x y, decode (mul x y) <~=~> (decode x * decode y).
-
- Class multiply_low_low := { mulhwll : W -> W -> W }.
- Global Coercion mulhwll : multiply_low_low >-> Funclass.
- Class multiply_high_low := { mulhwhl : W -> W -> W }.
- Global Coercion mulhwhl : multiply_high_low >-> Funclass.
- Class multiply_high_high := { mulhwhh : W -> W -> W }.
- Global Coercion mulhwhh : multiply_high_high >-> Funclass.
- Class multiply_double := { muldw : W -> W -> tuple W 2 }.
- Global Coercion muldw : multiply_double >-> Funclass.
- (** Quoting http://www.felixcloutier.com/x86/MUL.html:
-
- The OF and CF flags are set to 0 if the upper half of the result
- is 0; otherwise, they are set to 1. The SF, ZF, AF, and PF flags
- are undefined.
-
- We ignore the CF in the specification; we only have it so that
- we can ensure that the CF flag gets appropriately clobbered. *)
- Class multiply_double_with_CF := { muldwf : W -> W -> bool * tuple W 2 }.
- Global Coercion muldwf : multiply_double_with_CF >-> Funclass.
-
- Class is_mul_low_low (w:Z) (mulhwll : multiply_low_low) :=
- decode_mul_low_low :>
- forall x y, decode (mulhwll x y) <~=~> ((decode x mod 2^w) * (decode y mod 2^w)) mod 2^n.
- Class is_mul_high_low (w:Z) (mulhwhl : multiply_high_low) :=
- decode_mul_high_low :>
- forall x y, decode (mulhwhl x y) <~=~> ((decode x >> w) * (decode y mod 2^w)) mod 2^n.
- Class is_mul_high_high (w:Z) (mulhwhh : multiply_high_high) :=
- decode_mul_high_high :>
- forall x y, decode (mulhwhh x y) <~=~> ((decode x >> w) * (decode y >> w)) mod 2^n.
- Class is_mul_double (muldw : multiply_double) :=
- {
- decode_fst_mul_double :>
- forall x y, decode (fst (muldw x y)) =~> (decode x * decode y) mod 2^n;
- decode_snd_mul_double :>
- forall x y, decode (snd (muldw x y)) =~> (decode x * decode y) >> n
- }.
-
- Class is_mul_double_with_CF (muldwf : multiply_double_with_CF) :=
- {
- decode_fst_mul_double_with_CF :>
- forall x y, decode (fst (snd (muldwf x y))) =~> (decode x * decode y) mod 2^n;
- decode_snd_mul_double_with_CF :>
- forall x y, decode (snd (snd (muldwf x y))) =~> (decode x * decode y) >> n
- }.
-
- Class select_conditional := { selc : bool -> W -> W -> W }.
- Global Coercion selc : select_conditional >-> Funclass.
-
- Class is_select_conditional (selc : select_conditional) :=
- decode_select_conditional :> forall b x y,
- decode (selc b x y) <~=~> if b then decode x else decode y.
-
- Class add_modulo := { addm : W -> W -> W (* modulus *) -> W }.
- Global Coercion addm : add_modulo >-> Funclass.
-
- Class is_add_modulo (addm : add_modulo) :=
- decode_add_modulo :> forall x y modulus,
- decode (addm x y modulus) <~=~> (if (decode x + decode y) <? decode modulus
- then (decode x + decode y)
- else (decode x + decode y) - decode modulus).
-End InstructionGallery.
-
-Global Arguments load_immediate : clear implicits.
-Global Arguments shift_right_doubleword_immediate : clear implicits.
-Global Arguments shift_right_doubleword_immediate_with_CF : clear implicits.
-Global Arguments shift_left_immediate : clear implicits.
-Global Arguments shift_left_immediate_with_CF : clear implicits.
-Global Arguments shift_right_immediate : clear implicits.
-Global Arguments shift_right_immediate_with_CF : clear implicits.
-Global Arguments spread_left_immediate : clear implicits.
-Global Arguments mask_keep_low : clear implicits.
-Global Arguments bitwise_and : clear implicits.
-Global Arguments bitwise_and_with_CF : clear implicits.
-Global Arguments bitwise_or : clear implicits.
-Global Arguments bitwise_or_with_CF : clear implicits.
-Global Arguments add_with_carry : clear implicits.
-Global Arguments sub_with_carry : clear implicits.
-Global Arguments multiply : clear implicits.
-Global Arguments multiply_low_low : clear implicits.
-Global Arguments multiply_high_low : clear implicits.
-Global Arguments multiply_high_high : clear implicits.
-Global Arguments multiply_double : clear implicits.
-Global Arguments multiply_double_with_CF : clear implicits.
-Global Arguments select_conditional : clear implicits.
-Global Arguments add_modulo : clear implicits.
-Global Arguments ldi {_ _} _.
-Global Arguments shrdf {_ _} _ _ _.
-Global Arguments shrd {_ _} _ _ _.
-Global Arguments shl {_ _} _ _.
-Global Arguments shlf {_ _} _ _.
-Global Arguments shr {_ _} _ _.
-Global Arguments shrf {_ _} _ _.
-Global Arguments sprl {_ _} _ _.
-Global Arguments mkl {_ _} _ _.
-Global Arguments and {_ _} _ _.
-Global Arguments andf {_ _} _ _.
-Global Arguments or {_ _} _ _.
-Global Arguments orf {_ _} _ _.
-Global Arguments adc {_ _} _ _ _.
-Global Arguments subc {_ _} _ _ _.
-Global Arguments mul {_ _} _ _.
-Global Arguments mulhwll {_ _} _ _.
-Global Arguments mulhwhl {_ _} _ _.
-Global Arguments mulhwhh {_ _} _ _.
-Global Arguments muldw {_ _} _ _.
-Global Arguments muldwf {_ _} _ _.
-Global Arguments selc {_ _} _ _ _.
-Global Arguments addm {_ _} _ _ _.
-
-Global Arguments is_decode {_ _} _.
-Global Arguments is_load_immediate {_ _ _} _.
-Global Arguments is_shift_right_doubleword_immediate {_ _ _} _.
-Global Arguments is_shift_right_doubleword_immediate_with_CF {_ _ _} _.
-Global Arguments is_shift_left_immediate {_ _ _} _.
-Global Arguments is_shift_left_immediate_with_CF {_ _ _} _.
-Global Arguments is_shift_right_immediate {_ _ _} _.
-Global Arguments is_shift_right_immediate_with_CF {_ _ _} _.
-Global Arguments is_spread_left_immediate {_ _ _} _.
-Global Arguments is_mask_keep_low {_ _ _} _.
-Global Arguments is_bitwise_and {_ _ _} _.
-Global Arguments is_bitwise_and_with_CF {_ _ _} _.
-Global Arguments is_bitwise_or {_ _ _} _.
-Global Arguments is_bitwise_or_with_CF {_ _ _} _.
-Global Arguments is_add_with_carry {_ _ _} _.
-Global Arguments is_sub_with_carry {_ _ _} _.
-Global Arguments is_mul {_ _ _} _.
-Global Arguments is_mul_low_low {_ _ _} _ _.
-Global Arguments is_mul_high_low {_ _ _} _ _.
-Global Arguments is_mul_high_high {_ _ _} _ _.
-Global Arguments is_mul_double {_ _ _} _.
-Global Arguments is_mul_double_with_CF {_ _ _} _.
-Global Arguments is_select_conditional {_ _ _} _.
-Global Arguments is_add_modulo {_ _ _} _.
-
-Module fancy_machine.
- Local Notation imm := Z (only parsing).
-
- Class instructions (n : Z) :=
- {
- W : Type (* [n]-bit word *);
- decode :> decoder n W;
- ldi :> load_immediate W;
- shrd :> shift_right_doubleword_immediate W;
- shl :> shift_left_immediate W;
- shr :> shift_right_immediate W;
- adc :> add_with_carry W;
- subc :> sub_with_carry W;
- mulhwll :> multiply_low_low W;
- mulhwhl :> multiply_high_low W;
- mulhwhh :> multiply_high_high W;
- selc :> select_conditional W;
- addm :> add_modulo W
- }.
-
- Class arithmetic {n_over_two} (ops:instructions (2 * n_over_two)) :=
- {
- decode_range :> is_decode decode;
- load_immediate :> is_load_immediate ldi;
- shift_right_doubleword_immediate :> is_shift_right_doubleword_immediate shrd;
- shift_left_immediate :> is_shift_left_immediate shl;
- shift_right_immediate :> is_shift_right_immediate shr;
- add_with_carry :> is_add_with_carry adc;
- sub_with_carry :> is_sub_with_carry subc;
- multiply_low_low :> is_mul_low_low n_over_two mulhwll;
- multiply_high_low :> is_mul_high_low n_over_two mulhwhl;
- multiply_high_high :> is_mul_high_high n_over_two mulhwhh;
- select_conditional :> is_select_conditional selc;
- add_modulo :> is_add_modulo addm
- }.
-End fancy_machine.
-
-Module x86.
- Local Notation imm := Z (only parsing).
-
- Class instructions (n : Z) :=
- {
- W : Type (* [n]-bit word *);
- decode :> decoder n W;
- ldi :> load_immediate W;
- shrdf :> shift_right_doubleword_immediate_with_CF W;
- shlf :> shift_left_immediate_with_CF W;
- shrf :> shift_right_immediate_with_CF W;
- adc :> add_with_carry W;
- subc :> sub_with_carry W;
- muldwf :> multiply_double_with_CF W;
- selc :> select_conditional W;
- orf :> bitwise_or_with_CF W
- }.
-
- Class arithmetic {n} (ops:instructions n) :=
- {
- decode_range :> is_decode decode;
- load_immediate :> is_load_immediate ldi;
- shift_right_doubleword_immediate_with_CF :> is_shift_right_doubleword_immediate_with_CF shrdf;
- shift_left_immediate_with_CF :> is_shift_left_immediate_with_CF shlf;
- shift_right_immediate_with_CF :> is_shift_right_immediate_with_CF shrf;
- add_with_carry :> is_add_with_carry adc;
- sub_with_carry :> is_sub_with_carry subc;
- multiply_double_with_CF :> is_mul_double_with_CF muldwf;
- select_conditional :> is_select_conditional selc;
- bitwise_or_with_CF :> is_bitwise_or_with_CF orf
- }.
-End x86.