Merge pull request #2081 from YosysHQ/eddie/blackbox_ast
[yosys.git] / kernel / calc.cc
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20 // [[CITE]] Power-Modulus Algorithm
21 // Schneier, Bruce (1996). Applied Cryptography: Protocols, Algorithms, and Source Code in C,
22 // Second Edition (2nd ed.). Wiley. ISBN 978-0-471-11709-4, page 244
23
24 #include "kernel/yosys.h"
25 #include "libs/bigint/BigIntegerLibrary.hh"
26
27 YOSYS_NAMESPACE_BEGIN
28
29 static void extend_u0(RTLIL::Const &arg, int width, bool is_signed)
30 {
31 RTLIL::State padding = RTLIL::State::S0;
32
33 if (arg.bits.size() > 0 && is_signed)
34 padding = arg.bits.back();
35
36 while (int(arg.bits.size()) < width)
37 arg.bits.push_back(padding);
38
39 arg.bits.resize(width);
40 }
41
42 static BigInteger const2big(const RTLIL::Const &val, bool as_signed, int &undef_bit_pos)
43 {
44 BigUnsigned mag;
45
46 BigInteger::Sign sign = BigInteger::positive;
47 State inv_sign_bit = RTLIL::State::S1;
48 size_t num_bits = val.bits.size();
49
50 if (as_signed && num_bits && val.bits[num_bits-1] == RTLIL::State::S1) {
51 inv_sign_bit = RTLIL::State::S0;
52 sign = BigInteger::negative;
53 num_bits--;
54 }
55
56 for (size_t i = 0; i < num_bits; i++)
57 if (val.bits[i] == RTLIL::State::S0 || val.bits[i] == RTLIL::State::S1)
58 mag.setBit(i, val.bits[i] == inv_sign_bit);
59 else if (undef_bit_pos < 0)
60 undef_bit_pos = i;
61
62 if (sign == BigInteger::negative)
63 mag += 1;
64
65 return BigInteger(mag, sign);
66 }
67
68 static RTLIL::Const big2const(const BigInteger &val, int result_len, int undef_bit_pos)
69 {
70 if (undef_bit_pos >= 0)
71 return RTLIL::Const(RTLIL::State::Sx, result_len);
72
73 BigUnsigned mag = val.getMagnitude();
74 RTLIL::Const result(0, result_len);
75
76 if (!mag.isZero())
77 {
78 if (val.getSign() < 0)
79 {
80 mag--;
81 for (int i = 0; i < result_len; i++)
82 result.bits[i] = mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1;
83 }
84 else
85 {
86 for (int i = 0; i < result_len; i++)
87 result.bits[i] = mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0;
88 }
89 }
90
91 #if 0
92 if (undef_bit_pos >= 0)
93 for (int i = undef_bit_pos; i < result_len; i++)
94 result.bits[i] = RTLIL::State::Sx;
95 #endif
96
97 return result;
98 }
99
100 static RTLIL::State logic_and(RTLIL::State a, RTLIL::State b)
101 {
102 if (a == RTLIL::State::S0) return RTLIL::State::S0;
103 if (b == RTLIL::State::S0) return RTLIL::State::S0;
104 if (a != RTLIL::State::S1) return RTLIL::State::Sx;
105 if (b != RTLIL::State::S1) return RTLIL::State::Sx;
106 return RTLIL::State::S1;
107 }
108
109 static RTLIL::State logic_or(RTLIL::State a, RTLIL::State b)
110 {
111 if (a == RTLIL::State::S1) return RTLIL::State::S1;
112 if (b == RTLIL::State::S1) return RTLIL::State::S1;
113 if (a != RTLIL::State::S0) return RTLIL::State::Sx;
114 if (b != RTLIL::State::S0) return RTLIL::State::Sx;
115 return RTLIL::State::S0;
116 }
117
118 static RTLIL::State logic_xor(RTLIL::State a, RTLIL::State b)
119 {
120 if (a != RTLIL::State::S0 && a != RTLIL::State::S1) return RTLIL::State::Sx;
121 if (b != RTLIL::State::S0 && b != RTLIL::State::S1) return RTLIL::State::Sx;
122 return a != b ? RTLIL::State::S1 : RTLIL::State::S0;
123 }
124
125 static RTLIL::State logic_xnor(RTLIL::State a, RTLIL::State b)
126 {
127 if (a != RTLIL::State::S0 && a != RTLIL::State::S1) return RTLIL::State::Sx;
128 if (b != RTLIL::State::S0 && b != RTLIL::State::S1) return RTLIL::State::Sx;
129 return a == b ? RTLIL::State::S1 : RTLIL::State::S0;
130 }
131
132 RTLIL::Const RTLIL::const_not(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
133 {
134 if (result_len < 0)
135 result_len = arg1.bits.size();
136
137 RTLIL::Const arg1_ext = arg1;
138 extend_u0(arg1_ext, result_len, signed1);
139
140 RTLIL::Const result(RTLIL::State::Sx, result_len);
141 for (size_t i = 0; i < size_t(result_len); i++) {
142 if (i >= arg1_ext.bits.size())
143 result.bits[i] = RTLIL::State::S0;
144 else if (arg1_ext.bits[i] == RTLIL::State::S0)
145 result.bits[i] = RTLIL::State::S1;
146 else if (arg1_ext.bits[i] == RTLIL::State::S1)
147 result.bits[i] = RTLIL::State::S0;
148 }
149
150 return result;
151 }
152
153 static RTLIL::Const logic_wrapper(RTLIL::State(*logic_func)(RTLIL::State, RTLIL::State),
154 RTLIL::Const arg1, RTLIL::Const arg2, bool signed1, bool signed2, int result_len = -1)
155 {
156 if (result_len < 0)
157 result_len = max(arg1.bits.size(), arg2.bits.size());
158
159 extend_u0(arg1, result_len, signed1);
160 extend_u0(arg2, result_len, signed2);
161
162 RTLIL::Const result(RTLIL::State::Sx, result_len);
163 for (size_t i = 0; i < size_t(result_len); i++) {
164 RTLIL::State a = i < arg1.bits.size() ? arg1.bits[i] : RTLIL::State::S0;
165 RTLIL::State b = i < arg2.bits.size() ? arg2.bits[i] : RTLIL::State::S0;
166 result.bits[i] = logic_func(a, b);
167 }
168
169 return result;
170 }
171
172 RTLIL::Const RTLIL::const_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
173 {
174 return logic_wrapper(logic_and, arg1, arg2, signed1, signed2, result_len);
175 }
176
177 RTLIL::Const RTLIL::const_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
178 {
179 return logic_wrapper(logic_or, arg1, arg2, signed1, signed2, result_len);
180 }
181
182 RTLIL::Const RTLIL::const_xor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
183 {
184 return logic_wrapper(logic_xor, arg1, arg2, signed1, signed2, result_len);
185 }
186
187 RTLIL::Const RTLIL::const_xnor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
188 {
189 return logic_wrapper(logic_xnor, arg1, arg2, signed1, signed2, result_len);
190 }
191
192 static RTLIL::Const logic_reduce_wrapper(RTLIL::State initial, RTLIL::State(*logic_func)(RTLIL::State, RTLIL::State), const RTLIL::Const &arg1, int result_len)
193 {
194 RTLIL::State temp = initial;
195
196 for (size_t i = 0; i < arg1.bits.size(); i++)
197 temp = logic_func(temp, arg1.bits[i]);
198
199 RTLIL::Const result(temp);
200 while (int(result.bits.size()) < result_len)
201 result.bits.push_back(RTLIL::State::S0);
202 return result;
203 }
204
205 RTLIL::Const RTLIL::const_reduce_and(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
206 {
207 return logic_reduce_wrapper(RTLIL::State::S1, logic_and, arg1, result_len);
208 }
209
210 RTLIL::Const RTLIL::const_reduce_or(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
211 {
212 return logic_reduce_wrapper(RTLIL::State::S0, logic_or, arg1, result_len);
213 }
214
215 RTLIL::Const RTLIL::const_reduce_xor(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
216 {
217 return logic_reduce_wrapper(RTLIL::State::S0, logic_xor, arg1, result_len);
218 }
219
220 RTLIL::Const RTLIL::const_reduce_xnor(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
221 {
222 RTLIL::Const buffer = logic_reduce_wrapper(RTLIL::State::S0, logic_xor, arg1, result_len);
223 if (!buffer.bits.empty()) {
224 if (buffer.bits.front() == RTLIL::State::S0)
225 buffer.bits.front() = RTLIL::State::S1;
226 else if (buffer.bits.front() == RTLIL::State::S1)
227 buffer.bits.front() = RTLIL::State::S0;
228 }
229 return buffer;
230 }
231
232 RTLIL::Const RTLIL::const_reduce_bool(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
233 {
234 return logic_reduce_wrapper(RTLIL::State::S0, logic_or, arg1, result_len);
235 }
236
237 RTLIL::Const RTLIL::const_logic_not(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
238 {
239 int undef_bit_pos_a = -1;
240 BigInteger a = const2big(arg1, signed1, undef_bit_pos_a);
241 RTLIL::Const result(a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S1 : RTLIL::State::S0);
242
243 while (int(result.bits.size()) < result_len)
244 result.bits.push_back(RTLIL::State::S0);
245 return result;
246 }
247
248 RTLIL::Const RTLIL::const_logic_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
249 {
250 int undef_bit_pos_a = -1, undef_bit_pos_b = -1;
251 BigInteger a = const2big(arg1, signed1, undef_bit_pos_a);
252 BigInteger b = const2big(arg2, signed2, undef_bit_pos_b);
253
254 RTLIL::State bit_a = a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
255 RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
256 RTLIL::Const result(logic_and(bit_a, bit_b));
257
258 while (int(result.bits.size()) < result_len)
259 result.bits.push_back(RTLIL::State::S0);
260 return result;
261 }
262
263 RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
264 {
265 int undef_bit_pos_a = -1, undef_bit_pos_b = -1;
266 BigInteger a = const2big(arg1, signed1, undef_bit_pos_a);
267 BigInteger b = const2big(arg2, signed2, undef_bit_pos_b);
268
269 RTLIL::State bit_a = a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
270 RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
271 RTLIL::Const result(logic_or(bit_a, bit_b));
272
273 while (int(result.bits.size()) < result_len)
274 result.bits.push_back(RTLIL::State::S0);
275 return result;
276 }
277
278 static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool sign_ext, int direction, int result_len)
279 {
280 int undef_bit_pos = -1;
281 BigInteger offset = const2big(arg2, false, undef_bit_pos) * direction;
282
283 if (result_len < 0)
284 result_len = arg1.bits.size();
285
286 RTLIL::Const result(RTLIL::State::Sx, result_len);
287 if (undef_bit_pos >= 0)
288 return result;
289
290 for (int i = 0; i < result_len; i++) {
291 BigInteger pos = BigInteger(i) + offset;
292 if (pos < 0)
293 result.bits[i] = RTLIL::State::S0;
294 else if (pos >= BigInteger(int(arg1.bits.size())))
295 result.bits[i] = sign_ext ? arg1.bits.back() : RTLIL::State::S0;
296 else
297 result.bits[i] = arg1.bits[pos.toInt()];
298 }
299
300 return result;
301 }
302
303 RTLIL::Const RTLIL::const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len)
304 {
305 RTLIL::Const arg1_ext = arg1;
306 extend_u0(arg1_ext, result_len, signed1);
307 return const_shift_worker(arg1_ext, arg2, false, -1, result_len);
308 }
309
310 RTLIL::Const RTLIL::const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len)
311 {
312 RTLIL::Const arg1_ext = arg1;
313 extend_u0(arg1_ext, max(result_len, GetSize(arg1)), signed1);
314 return const_shift_worker(arg1_ext, arg2, false, +1, result_len);
315 }
316
317 RTLIL::Const RTLIL::const_sshl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
318 {
319 if (!signed1)
320 return const_shl(arg1, arg2, signed1, signed2, result_len);
321 return const_shift_worker(arg1, arg2, true, -1, result_len);
322 }
323
324 RTLIL::Const RTLIL::const_sshr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
325 {
326 if (!signed1)
327 return const_shr(arg1, arg2, signed1, signed2, result_len);
328 return const_shift_worker(arg1, arg2, true, +1, result_len);
329 }
330
331 static RTLIL::Const const_shift_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool, bool signed2, int result_len, RTLIL::State other_bits)
332 {
333 int undef_bit_pos = -1;
334 BigInteger offset = const2big(arg2, signed2, undef_bit_pos);
335
336 if (result_len < 0)
337 result_len = arg1.bits.size();
338
339 RTLIL::Const result(RTLIL::State::Sx, result_len);
340 if (undef_bit_pos >= 0)
341 return result;
342
343 for (int i = 0; i < result_len; i++) {
344 BigInteger pos = BigInteger(i) + offset;
345 if (pos < 0 || pos >= BigInteger(int(arg1.bits.size())))
346 result.bits[i] = other_bits;
347 else
348 result.bits[i] = arg1.bits[pos.toInt()];
349 }
350
351 return result;
352 }
353
354 RTLIL::Const RTLIL::const_shift(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
355 {
356 return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::S0);
357 }
358
359 RTLIL::Const RTLIL::const_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
360 {
361 return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::Sx);
362 }
363
364 RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
365 {
366 int undef_bit_pos = -1;
367 bool y = const2big(arg1, signed1, undef_bit_pos) < const2big(arg2, signed2, undef_bit_pos);
368 RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
369
370 while (int(result.bits.size()) < result_len)
371 result.bits.push_back(RTLIL::State::S0);
372 return result;
373 }
374
375 RTLIL::Const RTLIL::const_le(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
376 {
377 int undef_bit_pos = -1;
378 bool y = const2big(arg1, signed1, undef_bit_pos) <= const2big(arg2, signed2, undef_bit_pos);
379 RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
380
381 while (int(result.bits.size()) < result_len)
382 result.bits.push_back(RTLIL::State::S0);
383 return result;
384 }
385
386 RTLIL::Const RTLIL::const_eq(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
387 {
388 RTLIL::Const arg1_ext = arg1;
389 RTLIL::Const arg2_ext = arg2;
390 RTLIL::Const result(RTLIL::State::S0, result_len);
391
392 int width = max(arg1_ext.bits.size(), arg2_ext.bits.size());
393 extend_u0(arg1_ext, width, signed1 && signed2);
394 extend_u0(arg2_ext, width, signed1 && signed2);
395
396 RTLIL::State matched_status = RTLIL::State::S1;
397 for (size_t i = 0; i < arg1_ext.bits.size(); i++) {
398 if (arg1_ext.bits.at(i) == RTLIL::State::S0 && arg2_ext.bits.at(i) == RTLIL::State::S1)
399 return result;
400 if (arg1_ext.bits.at(i) == RTLIL::State::S1 && arg2_ext.bits.at(i) == RTLIL::State::S0)
401 return result;
402 if (arg1_ext.bits.at(i) > RTLIL::State::S1 || arg2_ext.bits.at(i) > RTLIL::State::S1)
403 matched_status = RTLIL::State::Sx;
404 }
405
406 result.bits.front() = matched_status;
407 return result;
408 }
409
410 RTLIL::Const RTLIL::const_ne(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
411 {
412 RTLIL::Const result = RTLIL::const_eq(arg1, arg2, signed1, signed2, result_len);
413 if (result.bits.front() == RTLIL::State::S0)
414 result.bits.front() = RTLIL::State::S1;
415 else if (result.bits.front() == RTLIL::State::S1)
416 result.bits.front() = RTLIL::State::S0;
417 return result;
418 }
419
420 RTLIL::Const RTLIL::const_eqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
421 {
422 RTLIL::Const arg1_ext = arg1;
423 RTLIL::Const arg2_ext = arg2;
424 RTLIL::Const result(RTLIL::State::S0, result_len);
425
426 int width = max(arg1_ext.bits.size(), arg2_ext.bits.size());
427 extend_u0(arg1_ext, width, signed1 && signed2);
428 extend_u0(arg2_ext, width, signed1 && signed2);
429
430 for (size_t i = 0; i < arg1_ext.bits.size(); i++) {
431 if (arg1_ext.bits.at(i) != arg2_ext.bits.at(i))
432 return result;
433 }
434
435 result.bits.front() = RTLIL::State::S1;
436 return result;
437 }
438
439 RTLIL::Const RTLIL::const_nex(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
440 {
441 RTLIL::Const result = RTLIL::const_eqx(arg1, arg2, signed1, signed2, result_len);
442 if (result.bits.front() == RTLIL::State::S0)
443 result.bits.front() = RTLIL::State::S1;
444 else if (result.bits.front() == RTLIL::State::S1)
445 result.bits.front() = RTLIL::State::S0;
446 return result;
447 }
448
449 RTLIL::Const RTLIL::const_ge(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
450 {
451 int undef_bit_pos = -1;
452 bool y = const2big(arg1, signed1, undef_bit_pos) >= const2big(arg2, signed2, undef_bit_pos);
453 RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
454
455 while (int(result.bits.size()) < result_len)
456 result.bits.push_back(RTLIL::State::S0);
457 return result;
458 }
459
460 RTLIL::Const RTLIL::const_gt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
461 {
462 int undef_bit_pos = -1;
463 bool y = const2big(arg1, signed1, undef_bit_pos) > const2big(arg2, signed2, undef_bit_pos);
464 RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
465
466 while (int(result.bits.size()) < result_len)
467 result.bits.push_back(RTLIL::State::S0);
468 return result;
469 }
470
471 RTLIL::Const RTLIL::const_add(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
472 {
473 int undef_bit_pos = -1;
474 BigInteger y = const2big(arg1, signed1, undef_bit_pos) + const2big(arg2, signed2, undef_bit_pos);
475 return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
476 }
477
478 RTLIL::Const RTLIL::const_sub(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
479 {
480 int undef_bit_pos = -1;
481 BigInteger y = const2big(arg1, signed1, undef_bit_pos) - const2big(arg2, signed2, undef_bit_pos);
482 return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
483 }
484
485 RTLIL::Const RTLIL::const_mul(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
486 {
487 int undef_bit_pos = -1;
488 BigInteger y = const2big(arg1, signed1, undef_bit_pos) * const2big(arg2, signed2, undef_bit_pos);
489 return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
490 }
491
492 // truncating division
493 RTLIL::Const RTLIL::const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
494 {
495 int undef_bit_pos = -1;
496 BigInteger a = const2big(arg1, signed1, undef_bit_pos);
497 BigInteger b = const2big(arg2, signed2, undef_bit_pos);
498 if (b.isZero())
499 return RTLIL::Const(RTLIL::State::Sx, result_len);
500 bool result_neg = (a.getSign() == BigInteger::negative) != (b.getSign() == BigInteger::negative);
501 a = a.getSign() == BigInteger::negative ? -a : a;
502 b = b.getSign() == BigInteger::negative ? -b : b;
503 return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
504 }
505
506 // truncating modulo
507 RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
508 {
509 int undef_bit_pos = -1;
510 BigInteger a = const2big(arg1, signed1, undef_bit_pos);
511 BigInteger b = const2big(arg2, signed2, undef_bit_pos);
512 if (b.isZero())
513 return RTLIL::Const(RTLIL::State::Sx, result_len);
514 bool result_neg = a.getSign() == BigInteger::negative;
515 a = a.getSign() == BigInteger::negative ? -a : a;
516 b = b.getSign() == BigInteger::negative ? -b : b;
517 return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
518 }
519
520 RTLIL::Const RTLIL::const_divfloor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
521 {
522 int undef_bit_pos = -1;
523 BigInteger a = const2big(arg1, signed1, undef_bit_pos);
524 BigInteger b = const2big(arg2, signed2, undef_bit_pos);
525 if (b.isZero())
526 return RTLIL::Const(RTLIL::State::Sx, result_len);
527
528 bool result_pos = (a.getSign() == BigInteger::negative) == (b.getSign() == BigInteger::negative);
529 a = a.getSign() == BigInteger::negative ? -a : a;
530 b = b.getSign() == BigInteger::negative ? -b : b;
531 BigInteger result;
532
533 if (result_pos || a == 0) {
534 result = a / b;
535 } else {
536 // bigint division with negative numbers is wonky, make sure we only negate at the very end
537 result = -((a + b - 1) / b);
538 }
539 return big2const(result, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
540 }
541
542 RTLIL::Const RTLIL::const_modfloor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
543 {
544 int undef_bit_pos = -1;
545 BigInteger a = const2big(arg1, signed1, undef_bit_pos);
546 BigInteger b = const2big(arg2, signed2, undef_bit_pos);
547 if (b.isZero())
548 return RTLIL::Const(RTLIL::State::Sx, result_len);
549
550 BigInteger::Sign a_sign = a.getSign();
551 BigInteger::Sign b_sign = b.getSign();
552 a = a_sign == BigInteger::negative ? -a : a;
553 b = b_sign == BigInteger::negative ? -b : b;
554 BigInteger truncated = a_sign == BigInteger::negative ? -(a % b) : (a % b);
555 BigInteger modulo;
556
557 if (truncated == 0 || (a_sign == b_sign)) {
558 modulo = truncated;
559 } else {
560 modulo = b_sign == BigInteger::negative ? truncated - b : truncated + b;
561 }
562 return big2const(modulo, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
563 }
564
565 RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
566 {
567 int undef_bit_pos = -1;
568
569 BigInteger a = const2big(arg1, signed1, undef_bit_pos);
570 BigInteger b = const2big(arg2, signed2, undef_bit_pos);
571 BigInteger y = 1;
572
573 if (a == 0 && b < 0)
574 return RTLIL::Const(RTLIL::State::Sx, result_len);
575
576 if (a == 0 && b > 0)
577 return RTLIL::Const(RTLIL::State::S0, result_len);
578
579 if (b < 0)
580 {
581 if (a < -1 || a > 1)
582 y = 0;
583 if (a == -1)
584 y = (-b % 2) == 0 ? 1 : -1;
585 }
586
587 if (b > 0)
588 {
589 // Power-modulo with 2^result_len as modulus
590 BigInteger modulus = 1;
591 int modulus_bits = (result_len >= 0 ? result_len : 1024);
592 for (int i = 0; i < modulus_bits; i++)
593 modulus *= 2;
594
595 bool flip_result_sign = false;
596 if (a < 0) {
597 a *= -1;
598 if (b % 2 == 1)
599 flip_result_sign = true;
600 }
601
602 while (b > 0) {
603 if (b % 2 == 1)
604 y = (y * a) % modulus;
605 b = b / 2;
606 a = (a * a) % modulus;
607 }
608
609 if (flip_result_sign)
610 y *= -1;
611 }
612
613 return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
614 }
615
616 RTLIL::Const RTLIL::const_pos(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
617 {
618 RTLIL::Const arg1_ext = arg1;
619 extend_u0(arg1_ext, result_len, signed1);
620
621 return arg1_ext;
622 }
623
624 RTLIL::Const RTLIL::const_neg(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
625 {
626 RTLIL::Const arg1_ext = arg1;
627 RTLIL::Const zero(RTLIL::State::S0, 1);
628
629 return RTLIL::const_sub(zero, arg1_ext, true, signed1, result_len);
630 }
631
632 YOSYS_NAMESPACE_END
633