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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
defpackage firrtl/primops :
import core
import verse
import firrtl/ir2
import firrtl/ir-utils
import firrtl/passes
public defn set-primop-type (e:DoPrim) -> DoPrim :
;println-all(["Inferencing primop type: " e])
defn PLUS (w1:Width,w2:Width) -> Width : PlusWidth(w1,w2)
defn MAX (w1:Width,w2:Width) -> Width : MaxWidth(list(w1,w2))
defn MINUS (w1:Width,w2:Width) -> Width : MinusWidth(w1,w2)
defn POW (w1:Width) -> Width : ExpWidth(w1)
val o = op(e)
val a = args(e)
val c = consts(e)
defn t1 () : type(a[0])
defn t2 () : type(a[1])
defn t3 () : type(a[2])
defn w1 () : width!(type(a[0]))
defn w2 () : width!(type(a[1]))
defn w3 () : width!(type(a[2]))
defn c1 () : IntWidth(c[0])
defn c2 () : IntWidth(c[1])
switch {op(e) == _} :
ADD-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:UIntType, t2:SIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:SIntType, t2:UIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:SIntType, t2:SIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1, t2) : UnknownType()
SUB-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:UIntType, t2:SIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:SIntType, t2:UIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:SIntType, t2:SIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1, t2) : UnknownType()
ADD-WRAP-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(MAX(w1(),w2()))
(t1:UIntType, t2:SIntType) : SIntType(MAX(w1(),w2()))
(t1:SIntType, t2:UIntType) : SIntType(MAX(w1(),w2()))
(t1:SIntType, t2:SIntType) : SIntType(MAX(w1(),w2()))
(t1, t2) : UnknownType()
SUB-WRAP-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(MAX(w1(),w2()))
(t1:UIntType, t2:SIntType) : SIntType(MAX(w1(),w2()))
(t1:SIntType, t2:UIntType) : SIntType(MAX(w1(),w2()))
(t1:SIntType, t2:SIntType) : SIntType(MAX(w1(),w2()))
(t1, t2) : UnknownType()
MUL-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(PLUS(w1(),w2()))
(t1:UIntType, t2:SIntType) : SIntType(PLUS(w1(),w2()))
(t1:SIntType, t2:UIntType) : SIntType(PLUS(w1(),w2()))
(t1:SIntType, t2:SIntType) : SIntType(PLUS(w1(),w2()))
(t1, t2) : UnknownType()
DIV-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(w1())
(t1:UIntType, t2:SIntType) : SIntType(PLUS(w1(),w2()))
(t1:SIntType, t2:UIntType) : SIntType(w1())
(t1:SIntType, t2:SIntType) : SIntType(PLUS(w1(),w2()))
(t1, t2) : UnknownType()
MOD-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(w2())
(t1:UIntType, t2:SIntType) : UIntType(w2())
(t1:SIntType, t2:UIntType) : SIntType(PLUS(w2(),ONE))
(t1:SIntType, t2:SIntType) : SIntType(w2())
(t1, t2) : UnknownType()
QUO-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(PLUS(w1(),ONE))
(t1:UIntType, t2:SIntType) : SIntType(w1())
(t1:SIntType, t2:UIntType) : SIntType(PLUS(w1(),ONE))
(t1:SIntType, t2:SIntType) : SIntType(w1())
(t1, t2) : UnknownType()
REM-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(w2())
(t1:UIntType, t2:SIntType) : SIntType(w2())
(t1:SIntType, t2:UIntType) : UIntType(PLUS(w2(),ONE))
(t1:SIntType, t2:SIntType) : SIntType(w2())
(t1, t2) : UnknownType()
LESS-OP : DoPrim(o,a,c,BoolType())
LESS-EQ-OP : DoPrim(o,a,c,BoolType())
GREATER-OP : DoPrim(o,a,c,BoolType())
GREATER-EQ-OP : DoPrim(o,a,c,BoolType())
EQUAL-OP : DoPrim(o,a,c,BoolType())
NEQUAL-OP : DoPrim(o,a,c,BoolType())
EQUIV-OP : DoPrim(o,a,c,BoolType())
NEQUIV-OP : DoPrim(o,a,c,BoolType())
;MUX-OP : DoPrim{o,a,c,_} $
; match(t2(),t3()) :
; (t2:UIntType, t3:UIntType) : UIntType(MAX(w2(),w3()))
; (t2:SIntType, t3:SIntType) : SIntType(MAX(w2(),w3()))
; (t2, t3) : UnknownType()
PAD-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(c1())
(t1:SIntType) : SIntType(c1())
(t1) : UnknownType()
AS-UINT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(w1())
(t1:SIntType) : UIntType(w1())
(t1) : UnknownType()
AS-SINT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : SIntType(w1())
(t1:SIntType) : SIntType(w1())
(t1) : UnknownType()
SHIFT-LEFT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(PLUS(w1(),c1()))
(t1:SIntType) : SIntType(PLUS(w1(),c1()))
(t1) : UnknownType()
SHIFT-RIGHT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(MINUS(w1(),c1()))
(t1:SIntType) : SIntType(MINUS(w1(),c1()))
(t1) : UnknownType()
DYN-SHIFT-LEFT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(PLUS(w1(),POW(w2())))
(t1:SIntType) : SIntType(PLUS(w1(),POW(w2())))
(t1) : UnknownType()
DYN-SHIFT-RIGHT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(w1())
(t1:SIntType) : SIntType(w1())
(t1) : UnknownType()
CONVERT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : SIntType(PLUS(w1(),ONE))
(t1:SIntType) : SIntType(w1())
(t1) : UnknownType()
NEG-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : SIntType(PLUS(w1(),ONE))
(t1:SIntType) : SIntType(w1())
(t1) : UnknownType()
BIT-NOT-OP : DoPrim(o,a,c,t1())
BIT-AND-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(MAX(w1(),w2()))
(t1:SIntType) : SIntType(MAX(w1(),w2()))
(t1) : UnknownType()
BIT-OR-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(MAX(w1(),w2()))
(t1:SIntType) : SIntType(MAX(w1(),w2()))
(t1) : UnknownType()
BIT-XOR-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(MAX(w1(),w2()))
(t1:SIntType) : SIntType(MAX(w1(),w2()))
(t1) : UnknownType()
BIT-AND-REDUCE-OP : DoPrim(o,a,c,BoolType())
BIT-OR-REDUCE-OP : DoPrim(o,a,c,BoolType())
BIT-XOR-REDUCE-OP : DoPrim(o,a,c,BoolType())
CONCAT-OP : DoPrim(o,a,c,UIntType(PLUS(w1(),w2())))
BIT-SELECT-OP : DoPrim(o,a,c,BoolType())
BITS-SELECT-OP : DoPrim(o,a,c,UIntType(PLUS(MINUS(c1(),c2()),ONE)))
;public defn primop-gen-constraints (e:DoPrim,v:Vector<WGeq>) -> Type :
; defn get-max (i0:Int,i1:Int) -> Width : get-max(list(i0,i1))
; defn get-max (ls:List<Int>) -> Width :
; MaxWidth $ for i in ls map : width!(args(e)[i])
; defn all-max () -> Width :
; MaxWidth $ for x in args(e) map : width!(x)
;
; println-all-debug(["Looking at " op(e) " with inputs " args(e)])
; val w* = switch {op(e) == _} :
; ADD-OP : PlusWidth(get-max(0,1),IntWidth(1))
; SUB-OP : PlusWidth(get-max(0,1),IntWidth(1))
; MUL-OP : PlusWidth(get-max(0,1),get-max(0,1))
; DIV-OP :
; match(type(args(e)[0]),type(args(e)[1])) :
; (t0:UIntType,t1:SIntType) : PlusWidth(width!(args(e)[0]),IntWidth(1))
; (t0:SIntType,t1:SIntType) : PlusWidth(width!(args(e)[0]),IntWidth(1))
; (t0,t1) : width!(args(e)[0])
; MOD-OP :
; match(type(args(e)[0]),type(args(e)[1])) :
; (t0:SIntType,t1:UIntType) : PlusWidth(width!(args(e)[1]),IntWidth(1))
; (t0,t1) : width!(args(e)[1])
; QUO-OP :
; match(type(args(e)[0]),type(args(e)[1])) :
; (t0:UIntType,t1:SIntType) : PlusWidth(width!(args(e)[0]),IntWidth(1))
; (t0:SIntType,t1:SIntType) : PlusWidth(width!(args(e)[0]),IntWidth(1))
; (t0,t1) : width!(args(e)[0])
; REM-OP :
; match(type(args(e)[0]),type(args(e)[1])) :
; (t0:SIntType,t1:UIntType) : PlusWidth(width!(args(e)[1]),IntWidth(1))
; (t0,t1) : width!(args(e)[1])
; ADD-WRAP-OP : get-max(0,1)
; SUB-WRAP-OP : get-max(0,1)
; LESS-OP : IntWidth(1)
; LESS-EQ-OP : IntWidth(1)
; GREATER-OP : IntWidth(1)
; GREATER-EQ-OP : IntWidth(1)
; EQUAL-OP : IntWidth(1)
; NEQUAL-OP : IntWidth(1)
; EQUIV-OP : IntWidth(1)
; NEQUIV-OP : IntWidth(1)
; MUX-OP :
; add(v,WGeq(IntWidth(1),width!(args(e)[0])))
; add(v,WGeq(width!(args(e)[0]),IntWidth(1)))
; get-max(1,2)
; PAD-OP : IntWidth(consts(e)[0])
; AS-UINT-OP : width!(args(e)[0])
; AS-SINT-OP : width!(args(e)[0])
; SHIFT-LEFT-OP : PlusWidth(width!(args(e)[0]),IntWidth(consts(e)[0]))
; SHIFT-RIGHT-OP : MinusWidth(width!(args(e)[0]),IntWidth(consts(e)[0]))
; DYN-SHIFT-LEFT-OP : PlusWidth(width!(args(e)[0]),ExpWidth(width!(args(e)[1])))
; DYN-SHIFT-RIGHT-OP : width!(args(e)[0])
; CONVERT-OP :
; match(type(args(e)[0])) :
; (t0:UIntType) : PlusWidth(width!(args(e)[0]),IntWidth(1))
; (t0:SIntType) : width!(args(e)[0])
; NEG-OP : PlusWidth(width!(args(e)[0]),IntWidth(1))
; BIT-NOT-OP : width!(args(e)[0])
; BIT-AND-OP : get-max(0,1)
; BIT-OR-OP : get-max(0,1)
; BIT-XOR-OP : get-max(0,1)
; BIT-AND-REDUCE-OP : all-max()
; BIT-OR-REDUCE-OP : all-max()
; BIT-XOR-REDUCE-OP : all-max()
; CONCAT-OP : PlusWidth(width!(args(e)[0]),width!(args(e)[1]))
; BIT-SELECT-OP : IntWidth(1)
; BITS-SELECT-OP : IntWidth(consts(e)[0] - consts(e)[1] + 1)
;
; match(type(e)) :
; (t:UIntType) : UIntType(w*)
; (t:SIntType) : SIntType(w*)
; (t) : error("Shouldn't be here")
;
|