-
Notifications
You must be signed in to change notification settings - Fork 11
/
Lowering.v
148 lines (132 loc) · 6.05 KB
/
Lowering.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
(*! Language | Compilation from typed ASTs to lowered ASTs !*)
Require Import Koika.Syntax Koika.TypedSyntaxFunctions Koika.SyntaxMacros.
Require Export Koika.Common Koika.Environments.
Require Koika.SyntaxMacros Koika.TypedSyntax Koika.LoweredSyntax.
Import PrimTyped CircuitSignatures.
Section Lowering.
Context {pos_t var_t fn_name_t rule_name_t reg_t ext_fn_t: Type}.
Context {R: reg_t -> type}.
Context {Sigma: ext_fn_t -> ExternalSignature}.
Context {REnv: Env reg_t}.
Definition lower_R idx :=
type_sz (R idx).
Notation lR := lower_R.
Definition lower_Sigma fn :=
CSig_of_Sig (Sigma fn).
Notation lSigma := lower_Sigma.
Definition lower_r (r: REnv.(env_t) R)
: REnv.(env_t) (fun idx => bits (lR idx)) :=
map REnv (fun idx v => bits_of_value v) r.
Definition lower_sigma (sigma: forall f, Sig_denote (Sigma f))
: forall f, CSig_denote (lSigma f) :=
fun f => fun bs => bits_of_value (sigma f (value_of_bits bs)).
Notation typed_action := (TypedSyntax.action pos_t var_t fn_name_t R Sigma).
Notation low_action := (LoweredSyntax.action pos_t var_t lR lSigma).
Section Action.
Definition lower_unop {sig} (fn: fn1)
(a: low_action sig (type_sz (PrimSignatures.Sigma1 fn).(arg1Sig))):
low_action sig (type_sz (PrimSignatures.Sigma1 fn).(retSig)) :=
let lArg1 fn := low_action sig (type_sz (PrimSignatures.Sigma1 fn).(arg1Sig)) in
let lRet fn := low_action sig (type_sz (PrimSignatures.Sigma1 fn).(retSig)) in
match fn return lArg1 fn -> lRet fn with
| Display fn => fun a => LoweredSyntax.Unop (Lowered (DisplayBits fn)) a
| Conv tau fn => fun a =>
match fn return lArg1 (Conv tau fn) -> lRet (Conv tau fn) with
| Pack => fun a => a
| Unpack => fun a => a
| Ignore => fun a => LoweredSyntax.Unop (Lowered (IgnoreBits _)) a
end a
| Bits1 fn => fun a => LoweredSyntax.Unop fn a
| Struct1 fn sig f => fun a =>
match fn return lArg1 (Struct1 fn sig f) -> lRet (Struct1 fn sig f) with
| GetField => fun a =>
LoweredSyntax.Unop (GetFieldBits sig f) a
end a
| Array1 fn sig idx => fun a =>
match fn return lArg1 (Array1 fn sig idx) -> lRet (Array1 fn sig idx) with
| GetElement => fun a =>
LoweredSyntax.Unop (GetElementBits sig idx) a
end a
end a.
Definition lower_binop {sig} (fn: fn2)
(a1: low_action sig (type_sz (PrimSignatures.Sigma2 fn).(arg1Sig)))
(a2: low_action sig (type_sz (PrimSignatures.Sigma2 fn).(arg2Sig))):
low_action sig (type_sz (PrimSignatures.Sigma2 fn).(retSig)) :=
let lArg1 fn := low_action sig (type_sz (PrimSignatures.Sigma2 fn).(arg1Sig)) in
let lArg2 fn := low_action sig (type_sz (PrimSignatures.Sigma2 fn).(arg2Sig)) in
let lRet fn := low_action sig (type_sz (PrimSignatures.Sigma2 fn).(retSig)) in
match fn return lArg1 fn -> lArg2 fn -> lRet fn with
| Eq tau negate => fun a1 a2 => LoweredSyntax.Binop (EqBits (type_sz tau) negate) a1 a2
| Bits2 fn => fun a1 a2 => LoweredSyntax.Binop fn a1 a2
| Struct2 fn sig f => fun a1 a2 =>
match fn return lArg1 (Struct2 fn sig f) -> lArg2 (Struct2 fn sig f) -> lRet (Struct2 fn sig f) with
| SubstField => fun a1 a2 =>
LoweredSyntax.Binop (SubstFieldBits sig f) a1 a2
end a1 a2
| Array2 fn sig idx => fun a1 a2 =>
match fn return lArg1 (Array2 fn sig idx) -> lArg2 (Array2 fn sig idx) -> lRet (Array2 fn sig idx) with
| SubstElement => fun a1 a2 =>
LoweredSyntax.Binop (SubstElementBits sig idx) a1 a2
end a1 a2
end a1 a2.
Definition lower_member
{k: var_t} {tau: type} {sig}
(m: member (k, tau) sig) :
member (type_sz tau) (lsig_of_tsig sig) :=
member_map _ m.
Section Args.
Context (lower_action:
forall {sig: tsig var_t} {tau}
(a: typed_action sig tau),
low_action (lsig_of_tsig sig) (type_sz tau)).
Definition lower_args' {sig argspec}
(args: context (fun k_tau => typed_action sig (snd k_tau)) argspec) :=
cmap (V' := fun sz => (var_t * low_action _ sz)%type)
(fun k_tau => type_sz (snd k_tau))
(fun k_tau a => ((fst k_tau), lower_action _ _ a))
args.
End Args.
Fixpoint lower_action
{sig: tsig var_t} {tau}
(a: typed_action sig tau):
low_action (lsig_of_tsig sig) (type_sz tau) :=
let l {sig tau} a := @lower_action sig tau a in
match a with
| TypedSyntax.Fail tau =>
LoweredSyntax.Fail (type_sz tau)
| @TypedSyntax.Var _ _ _ _ _ _ _ _ k _ m =>
LoweredSyntax.Var k (lower_member m)
| TypedSyntax.Const cst =>
LoweredSyntax.Const (bits_of_value cst)
| TypedSyntax.Seq r1 r2 =>
LoweredSyntax.Seq (l r1) (l r2)
| @TypedSyntax.Assign _ _ _ _ _ _ _ _ k _ m ex =>
LoweredSyntax.Assign k (lower_member m) (l ex)
| TypedSyntax.Bind var ex body =>
LoweredSyntax.Bind var (l ex) (l body)
| TypedSyntax.If cond tbranch fbranch =>
LoweredSyntax.If (l cond) (l tbranch) (l fbranch)
| TypedSyntax.Read p idx =>
LoweredSyntax.Read p idx
| TypedSyntax.Write p idx val =>
LoweredSyntax.Write p idx (l val)
| TypedSyntax.Unop fn a =>
lower_unop fn (l a)
| TypedSyntax.Binop fn a1 a2 =>
lower_binop fn (l a1) (l a2)
| TypedSyntax.ExternalCall fn a =>
LoweredSyntax.ExternalCall fn (l a)
| TypedSyntax.InternalCall fn args body =>
SyntaxMacros.InternalCall
(lower_args' (@lower_action) args)
(l body)
| TypedSyntax.APos p a =>
LoweredSyntax.APos p (l a)
end.
End Action.
End Lowering.
Notation lower_args args := (lower_args' (@lower_action _ _ _ _ _ _ _) args).
Arguments lower_R {reg_t} R idx : assert.
Arguments lower_Sigma {ext_fn_t} Sigma fn : assert.
Arguments lower_r {reg_t} {R} {REnv} r : assert.
Arguments lower_sigma {ext_fn_t} {Sigma} sigma f a : assert.