aboutsummaryrefslogtreecommitdiff
path: root/src/main/stanza/primop.stanza
blob: 4b8d0cbc7ff5a5efddeddaaf51977ff61976c1e8 (plain)
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")
;