-
Notifications
You must be signed in to change notification settings - Fork 0
/
Compare.v
91 lines (72 loc) · 3.2 KB
/
Compare.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
Require Import Kami.AllNotations.
Require Import FpuKami.Definitions.
Section Definitions.
Variable expWidthMinus2 sigWidthMinus2: nat.
Local Notation expWidthMinus1 := (expWidthMinus2 + 1).
Local Notation expWidth := (expWidthMinus1 + 1).
Local Notation sigWidthMinus1 := (sigWidthMinus2 + 1).
Local Notation sigWidth := (sigWidthMinus1 + 1).
Section Ty.
Variable ty: Kind -> Type.
Definition Compare_Output :=
STRUCT_TYPE {
"gt" :: Bool;
"eq" :: Bool;
"lt" :: Bool;
"exceptionFlags" :: ExceptionFlags
}.
Section Compare.
Variable a: NF expWidthMinus2 sigWidthMinus2 @# ty.
Variable b: NF expWidthMinus2 sigWidthMinus2 @# ty.
Open Scope kami_expr.
Definition signA := a @% "sign".
Definition expA := a @% "sExp".
Definition sigA := a @% "sig".
Definition signB := b @% "sign".
Definition expB := b @% "sExp".
Definition sigB := b @% "sig".
Open Scope kami_action.
Definition Compare_expr
: Compare_Output ## ty
:= LETC invalid <- a @% "isNaN" || b @% "isNaN";
LETC bothInfs <- a @% "isInf" && b @% "isInf";
LETC bothZeros <- a @% "isZero" && b @% "isZero";
LETC eitherZero <- a@% "isZero" || b @% "isZero";
LETC eqExp <- expA == expB;
LETC eqSign <- signA == signB;
LETC eqSig <- sigA == sigB;
LETC eqMags <- #eqExp && #eqSig;
LETC ltMags_common <- (b@%"isInf") || ((!(a@%"isInf")) && ((expA <s expB) || (#eqExp && (sigA < sigB))));
LETC ltMags <- (signA && !signB)
|| (!signA && !signB && #ltMags_common)
|| (signA && signB && !#ltMags_common && !#eqMags);
LETC zLtPos <- a @% "isZero" && !signB;
LETC aLtInf <- !(a @% "isInf") && !signB && (b @% "isInf");
LETC ltSign <- signA && !signB;
LETC negLtZero <- (signA && b @% "isZero");
LETC eq <- #bothZeros || (!#eitherZero && #eqSign && (#bothInfs || #eqMags));
LETC lt <-
!#bothZeros
&& (#ltSign
|| (!#bothInfs && (#zLtPos || #aLtInf || #negLtZero || #ltMags)));
LETC gt <- !#lt && !#eq;
LETC flags: ExceptionFlags <- STRUCT {
"invalid" ::= #invalid;
"infinite" ::= $$false;
"overflow" ::= $$false;
"underflow" ::= $$false;
"inexact" ::= $$false
};
LETC Compare: Compare_Output <- STRUCT {
"gt" ::= !#invalid && #gt;
"eq" ::= !#invalid && #eq;
"lt" ::= !#invalid && #lt;
"exceptionFlags" ::= #flags
};
RetE #Compare.
Definition Compare_action
: ActionT ty (Compare_Output)
:= convertLetExprSyntax_ActionT Compare_expr.
End Compare.
End Ty.
End Definitions.