yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
calc.cc
Go to the documentation of this file.
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"
26 
28 
29 static void extend_u0(RTLIL::Const &arg, int width, bool is_signed)
30 {
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  BigInteger result = 0, this_bit = 1;
45  for (size_t i = 0; i < val.bits.size(); i++) {
46  if (val.bits[i] == RTLIL::State::S1) {
47  if (as_signed && i+1 == val.bits.size())
48  result -= this_bit;
49  else
50  result += this_bit;
51  }
52  else if (val.bits[i] != RTLIL::State::S0) {
53  if (undef_bit_pos < 0)
54  undef_bit_pos = i;
55  }
56  this_bit *= 2;
57  }
58  return result;
59 }
60 
61 static RTLIL::Const big2const(const BigInteger &val, int result_len, int undef_bit_pos)
62 {
63  if (undef_bit_pos >= 0)
64  return RTLIL::Const(RTLIL::State::Sx, result_len);
65 
66  BigUnsigned mag = val.getMagnitude();
67  RTLIL::Const result(0, result_len);
68 
69  if (!mag.isZero())
70  {
71  if (val.getSign() < 0)
72  {
73  mag--;
74  for (int i = 0; i < result_len; i++)
75  result.bits[i] = mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1;
76  }
77  else
78  {
79  for (int i = 0; i < result_len; i++)
80  result.bits[i] = mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0;
81  }
82  }
83 
84 #if 0
85  if (undef_bit_pos >= 0)
86  for (int i = undef_bit_pos; i < result_len; i++)
87  result.bits[i] = RTLIL::State::Sx;
88 #endif
89 
90  return result;
91 }
92 
94 {
95  if (a == RTLIL::State::S0) return RTLIL::State::S0;
96  if (b == RTLIL::State::S0) return RTLIL::State::S0;
97  if (a != RTLIL::State::S1) return RTLIL::State::Sx;
98  if (b != RTLIL::State::S1) return RTLIL::State::Sx;
99  return RTLIL::State::S1;
100 }
101 
103 {
104  if (a == RTLIL::State::S1) return RTLIL::State::S1;
105  if (b == RTLIL::State::S1) return RTLIL::State::S1;
106  if (a != RTLIL::State::S0) return RTLIL::State::Sx;
107  if (b != RTLIL::State::S0) return RTLIL::State::Sx;
108  return RTLIL::State::S0;
109 }
110 
112 {
113  if (a != RTLIL::State::S0 && a != RTLIL::State::S1) return RTLIL::State::Sx;
114  if (b != RTLIL::State::S0 && b != RTLIL::State::S1) return RTLIL::State::Sx;
115  return a != b ? RTLIL::State::S1 : RTLIL::State::S0;
116 }
117 
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 RTLIL::Const RTLIL::const_not(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
126 {
127  if (result_len < 0)
128  result_len = arg1.bits.size();
129 
130  RTLIL::Const arg1_ext = arg1;
131  extend_u0(arg1_ext, result_len, signed1);
132 
133  RTLIL::Const result(RTLIL::State::Sx, result_len);
134  for (size_t i = 0; i < size_t(result_len); i++) {
135  if (i >= arg1_ext.bits.size())
136  result.bits[i] = RTLIL::State::S0;
137  else if (arg1_ext.bits[i] == RTLIL::State::S0)
138  result.bits[i] = RTLIL::State::S1;
139  else if (arg1_ext.bits[i] == RTLIL::State::S1)
140  result.bits[i] = RTLIL::State::S0;
141  }
142 
143  return result;
144 }
145 
147  RTLIL::Const arg1, RTLIL::Const arg2, bool signed1, bool signed2, int result_len = -1)
148 {
149  if (result_len < 0)
150  result_len = std::max(arg1.bits.size(), arg2.bits.size());
151 
152  extend_u0(arg1, result_len, signed1);
153  extend_u0(arg2, result_len, signed2);
154 
155  RTLIL::Const result(RTLIL::State::Sx, result_len);
156  for (size_t i = 0; i < size_t(result_len); i++) {
157  RTLIL::State a = i < arg1.bits.size() ? arg1.bits[i] : RTLIL::State::S0;
158  RTLIL::State b = i < arg2.bits.size() ? arg2.bits[i] : RTLIL::State::S0;
159  result.bits[i] = logic_func(a, b);
160  }
161 
162  return result;
163 }
164 
165 RTLIL::Const RTLIL::const_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
166 {
167  return logic_wrapper(logic_and, arg1, arg2, signed1, signed2, result_len);
168 }
169 
170 RTLIL::Const RTLIL::const_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
171 {
172  return logic_wrapper(logic_or, arg1, arg2, signed1, signed2, result_len);
173 }
174 
175 RTLIL::Const RTLIL::const_xor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
176 {
177  return logic_wrapper(logic_xor, arg1, arg2, signed1, signed2, result_len);
178 }
179 
180 RTLIL::Const RTLIL::const_xnor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
181 {
182  return logic_wrapper(logic_xnor, arg1, arg2, signed1, signed2, result_len);
183 }
184 
185 static RTLIL::Const logic_reduce_wrapper(RTLIL::State initial, RTLIL::State(*logic_func)(RTLIL::State, RTLIL::State), const RTLIL::Const &arg1, int result_len)
186 {
187  RTLIL::State temp = initial;
188 
189  for (size_t i = 0; i < arg1.bits.size(); i++)
190  temp = logic_func(temp, arg1.bits[i]);
191 
192  RTLIL::Const result(temp);
193  while (int(result.bits.size()) < result_len)
194  result.bits.push_back(RTLIL::State::S0);
195  return result;
196 }
197 
198 RTLIL::Const RTLIL::const_reduce_and(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
199 {
200  return logic_reduce_wrapper(RTLIL::State::S1, logic_and, arg1, result_len);
201 }
202 
203 RTLIL::Const RTLIL::const_reduce_or(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
204 {
205  return logic_reduce_wrapper(RTLIL::State::S0, logic_or, arg1, result_len);
206 }
207 
208 RTLIL::Const RTLIL::const_reduce_xor(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
209 {
210  return logic_reduce_wrapper(RTLIL::State::S0, logic_xor, arg1, result_len);
211 }
212 
213 RTLIL::Const RTLIL::const_reduce_xnor(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
214 {
215  RTLIL::Const buffer = logic_reduce_wrapper(RTLIL::State::S0, logic_xor, arg1, result_len);
216  if (!buffer.bits.empty()) {
217  if (buffer.bits.front() == RTLIL::State::S0)
218  buffer.bits.front() = RTLIL::State::S1;
219  else if (buffer.bits.front() == RTLIL::State::S1)
220  buffer.bits.front() = RTLIL::State::S0;
221  }
222  return buffer;
223 }
224 
225 RTLIL::Const RTLIL::const_reduce_bool(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
226 {
227  return logic_reduce_wrapper(RTLIL::State::S0, logic_or, arg1, result_len);
228 }
229 
230 RTLIL::Const RTLIL::const_logic_not(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
231 {
232  int undef_bit_pos_a = -1;
233  BigInteger a = const2big(arg1, signed1, undef_bit_pos_a);
234  RTLIL::Const result(a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S1 : RTLIL::State::S0);
235 
236  while (int(result.bits.size()) < result_len)
237  result.bits.push_back(RTLIL::State::S0);
238  return result;
239 }
240 
241 RTLIL::Const RTLIL::const_logic_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
242 {
243  int undef_bit_pos_a = -1, undef_bit_pos_b = -1;
244  BigInteger a = const2big(arg1, signed1, undef_bit_pos_a);
245  BigInteger b = const2big(arg2, signed2, undef_bit_pos_b);
246 
247  RTLIL::State bit_a = a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
248  RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
249  RTLIL::Const result(logic_and(bit_a, bit_b));
250 
251  while (int(result.bits.size()) < result_len)
252  result.bits.push_back(RTLIL::State::S0);
253  return result;
254 }
255 
256 RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
257 {
258  int undef_bit_pos_a = -1, undef_bit_pos_b = -1;
259  BigInteger a = const2big(arg1, signed1, undef_bit_pos_a);
260  BigInteger b = const2big(arg2, signed2, undef_bit_pos_b);
261 
262  RTLIL::State bit_a = a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
263  RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
264  RTLIL::Const result(logic_or(bit_a, bit_b));
265 
266  while (int(result.bits.size()) < result_len)
267  result.bits.push_back(RTLIL::State::S0);
268  return result;
269 }
270 
271 static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool sign_ext, int direction, int result_len)
272 {
273  int undef_bit_pos = -1;
274  BigInteger offset = const2big(arg2, false, undef_bit_pos) * direction;
275 
276  if (result_len < 0)
277  result_len = arg1.bits.size();
278 
279  RTLIL::Const result(RTLIL::State::Sx, result_len);
280  if (undef_bit_pos >= 0)
281  return result;
282 
283  for (int i = 0; i < result_len; i++) {
284  BigInteger pos = BigInteger(i) + offset;
285  if (pos < 0)
286  result.bits[i] = RTLIL::State::S0;
287  else if (pos >= arg1.bits.size())
288  result.bits[i] = sign_ext ? arg1.bits.back() : RTLIL::State::S0;
289  else
290  result.bits[i] = arg1.bits[pos.toInt()];
291  }
292 
293  return result;
294 }
295 
296 RTLIL::Const RTLIL::const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len)
297 {
298  RTLIL::Const arg1_ext = arg1;
299  extend_u0(arg1_ext, result_len, signed1);
300  return const_shift_worker(arg1_ext, arg2, false, -1, result_len);
301 }
302 
303 RTLIL::Const RTLIL::const_shr(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, std::max(result_len, GetSize(arg1)), signed1);
307  return const_shift_worker(arg1_ext, arg2, false, +1, result_len);
308 }
309 
310 RTLIL::Const RTLIL::const_sshl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
311 {
312  if (!signed1)
313  return const_shl(arg1, arg2, signed1, signed2, result_len);
314  return const_shift_worker(arg1, arg2, true, -1, result_len);
315 }
316 
317 RTLIL::Const RTLIL::const_sshr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
318 {
319  if (!signed1)
320  return const_shr(arg1, arg2, signed1, signed2, result_len);
321  return const_shift_worker(arg1, arg2, true, +1, result_len);
322 }
323 
324 static RTLIL::Const const_shift_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool, bool signed2, int result_len, RTLIL::State other_bits)
325 {
326  int undef_bit_pos = -1;
327  BigInteger offset = const2big(arg2, signed2, undef_bit_pos);
328 
329  if (result_len < 0)
330  result_len = arg1.bits.size();
331 
332  RTLIL::Const result(RTLIL::State::Sx, result_len);
333  if (undef_bit_pos >= 0)
334  return result;
335 
336  for (int i = 0; i < result_len; i++) {
337  BigInteger pos = BigInteger(i) + offset;
338  if (pos < 0 || pos >= arg1.bits.size())
339  result.bits[i] = other_bits;
340  else
341  result.bits[i] = arg1.bits[pos.toInt()];
342  }
343 
344  return result;
345 }
346 
347 RTLIL::Const RTLIL::const_shift(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
348 {
349  return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::S0);
350 }
351 
352 RTLIL::Const RTLIL::const_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
353 {
354  return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::Sx);
355 }
356 
357 RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
358 {
359  int undef_bit_pos = -1;
360  bool y = const2big(arg1, signed1, undef_bit_pos) < const2big(arg2, signed2, undef_bit_pos);
361  RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
362 
363  while (int(result.bits.size()) < result_len)
364  result.bits.push_back(RTLIL::State::S0);
365  return result;
366 }
367 
368 RTLIL::Const RTLIL::const_le(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
369 {
370  int undef_bit_pos = -1;
371  bool y = const2big(arg1, signed1, undef_bit_pos) <= const2big(arg2, signed2, undef_bit_pos);
372  RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
373 
374  while (int(result.bits.size()) < result_len)
375  result.bits.push_back(RTLIL::State::S0);
376  return result;
377 }
378 
379 RTLIL::Const RTLIL::const_eq(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
380 {
381  RTLIL::Const arg1_ext = arg1;
382  RTLIL::Const arg2_ext = arg2;
383  RTLIL::Const result(RTLIL::State::S0, result_len);
384 
385  int width = std::max(arg1_ext.bits.size(), arg2_ext.bits.size());
386  extend_u0(arg1_ext, width, signed1 && signed2);
387  extend_u0(arg2_ext, width, signed1 && signed2);
388 
389  RTLIL::State matched_status = RTLIL::State::S1;
390  for (size_t i = 0; i < arg1_ext.bits.size(); i++) {
391  if (arg1_ext.bits.at(i) == RTLIL::State::S0 && arg2_ext.bits.at(i) == RTLIL::State::S1)
392  return result;
393  if (arg1_ext.bits.at(i) == RTLIL::State::S1 && arg2_ext.bits.at(i) == RTLIL::State::S0)
394  return result;
395  if (arg1_ext.bits.at(i) > RTLIL::State::S1 || arg2_ext.bits.at(i) > RTLIL::State::S1)
396  matched_status = RTLIL::State::Sx;
397  }
398 
399  result.bits.front() = matched_status;
400  return result;
401 }
402 
403 RTLIL::Const RTLIL::const_ne(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
404 {
405  RTLIL::Const result = RTLIL::const_eq(arg1, arg2, signed1, signed2, result_len);
406  if (result.bits.front() == RTLIL::State::S0)
407  result.bits.front() = RTLIL::State::S1;
408  else if (result.bits.front() == RTLIL::State::S1)
409  result.bits.front() = RTLIL::State::S0;
410  return result;
411 }
412 
413 RTLIL::Const RTLIL::const_eqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
414 {
415  RTLIL::Const arg1_ext = arg1;
416  RTLIL::Const arg2_ext = arg2;
417  RTLIL::Const result(RTLIL::State::S0, result_len);
418 
419  int width = std::max(arg1_ext.bits.size(), arg2_ext.bits.size());
420  extend_u0(arg1_ext, width, signed1 && signed2);
421  extend_u0(arg2_ext, width, signed1 && signed2);
422 
423  for (size_t i = 0; i < arg1_ext.bits.size(); i++) {
424  if (arg1_ext.bits.at(i) != arg2_ext.bits.at(i))
425  return result;
426  }
427 
428  result.bits.front() = RTLIL::State::S1;
429  return result;
430 }
431 
432 RTLIL::Const RTLIL::const_nex(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
433 {
434  RTLIL::Const result = RTLIL::const_eqx(arg1, arg2, signed1, signed2, result_len);
435  if (result.bits.front() == RTLIL::State::S0)
436  result.bits.front() = RTLIL::State::S1;
437  else if (result.bits.front() == RTLIL::State::S1)
438  result.bits.front() = RTLIL::State::S0;
439  return result;
440 }
441 
442 RTLIL::Const RTLIL::const_ge(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
443 {
444  int undef_bit_pos = -1;
445  bool y = const2big(arg1, signed1, undef_bit_pos) >= const2big(arg2, signed2, undef_bit_pos);
446  RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
447 
448  while (int(result.bits.size()) < result_len)
449  result.bits.push_back(RTLIL::State::S0);
450  return result;
451 }
452 
453 RTLIL::Const RTLIL::const_gt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
454 {
455  int undef_bit_pos = -1;
456  bool y = const2big(arg1, signed1, undef_bit_pos) > const2big(arg2, signed2, undef_bit_pos);
457  RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
458 
459  while (int(result.bits.size()) < result_len)
460  result.bits.push_back(RTLIL::State::S0);
461  return result;
462 }
463 
464 RTLIL::Const RTLIL::const_add(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
465 {
466  int undef_bit_pos = -1;
467  BigInteger y = const2big(arg1, signed1, undef_bit_pos) + const2big(arg2, signed2, undef_bit_pos);
468  return big2const(y, result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
469 }
470 
471 RTLIL::Const RTLIL::const_sub(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 : std::max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
476 }
477 
478 RTLIL::Const RTLIL::const_mul(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 : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
483 }
484 
485 RTLIL::Const RTLIL::const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
486 {
487  int undef_bit_pos = -1;
488  BigInteger a = const2big(arg1, signed1, undef_bit_pos);
489  BigInteger b = const2big(arg2, signed2, undef_bit_pos);
490  if (b.isZero())
491  return RTLIL::Const(RTLIL::State::Sx, result_len);
492  bool result_neg = (a.getSign() == BigInteger::negative) != (b.getSign() == BigInteger::negative);
493  a = a.getSign() == BigInteger::negative ? -a : a;
494  b = b.getSign() == BigInteger::negative ? -b : b;
495  return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
496 }
497 
498 RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
499 {
500  int undef_bit_pos = -1;
501  BigInteger a = const2big(arg1, signed1, undef_bit_pos);
502  BigInteger b = const2big(arg2, signed2, undef_bit_pos);
503  if (b.isZero())
504  return RTLIL::Const(RTLIL::State::Sx, result_len);
505  bool result_neg = a.getSign() == BigInteger::negative;
506  a = a.getSign() == BigInteger::negative ? -a : a;
507  b = b.getSign() == BigInteger::negative ? -b : b;
508  return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
509 }
510 
511 RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
512 {
513  int undef_bit_pos = -1;
514 
515  BigInteger a = const2big(arg1, signed1, undef_bit_pos);
516  BigInteger b = const2big(arg2, signed2, undef_bit_pos);
517  BigInteger y = 1;
518 
519  if (a == 0 && b < 0)
520  return RTLIL::Const(RTLIL::State::Sx, result_len);
521 
522  if (a == 0 && b > 0)
523  return RTLIL::Const(RTLIL::State::S0, result_len);
524 
525  if (b < 0)
526  {
527  if (a < -1 || a > 1)
528  y = 0;
529  if (a == -1)
530  y = (-b % 2) == 0 ? 1 : -1;
531  }
532 
533  if (b > 0)
534  {
535  // Power-modulo with 2^result_len as modulus
536  BigInteger modulus = 1;
537  int modulus_bits = (result_len >= 0 ? result_len : 1024);
538  for (int i = 0; i < modulus_bits; i++)
539  modulus *= 2;
540 
541  bool flip_result_sign = false;
542  if (a < 0) {
543  a *= -1;
544  if (b % 2 == 1)
545  flip_result_sign = true;
546  }
547 
548  while (b > 0) {
549  if (b % 2 == 1)
550  y = (y * a) % modulus;
551  b = b / 2;
552  a = (a * a) % modulus;
553  }
554 
555  if (flip_result_sign)
556  y *= -1;
557  }
558 
559  return big2const(y, result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
560 }
561 
562 RTLIL::Const RTLIL::const_pos(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
563 {
564  RTLIL::Const arg1_ext = arg1;
565  extend_u0(arg1_ext, result_len, signed1);
566 
567  return arg1_ext;
568 }
569 
570 RTLIL::Const RTLIL::const_neg(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
571 {
572  RTLIL::Const arg1_ext = arg1;
574 
575  return RTLIL::const_sub(zero, arg1_ext, true, signed1, result_len);
576 }
577 
579 
RTLIL::Const const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:256
RTLIL::Const const_xor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:175
RTLIL::Const const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:511
static RTLIL::State logic_xnor(RTLIL::State a, RTLIL::State b)
Definition: calc.cc:118
RTLIL::Const const_ne(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:403
static RTLIL::State logic_xor(RTLIL::State a, RTLIL::State b)
Definition: calc.cc:111
RTLIL::Const const_eq(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:379
#define YOSYS_NAMESPACE_END
Definition: yosys.h:100
static RTLIL::Const logic_wrapper(RTLIL::State(*logic_func)(RTLIL::State, RTLIL::State), RTLIL::Const arg1, RTLIL::Const arg2, bool signed1, bool signed2, int result_len=-1)
Definition: calc.cc:146
RTLIL::Const const_sub(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:471
RTLIL::Const const_logic_not(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:230
static RTLIL::Const logic_reduce_wrapper(RTLIL::State initial, RTLIL::State(*logic_func)(RTLIL::State, RTLIL::State), const RTLIL::Const &arg1, int result_len)
Definition: calc.cc:185
RTLIL::Const const_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:170
static BigInteger const2big(const RTLIL::Const &val, bool as_signed, int &undef_bit_pos)
Definition: calc.cc:42
RTLIL::Const const_ge(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:442
RTLIL::Const const_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:165
RTLIL::Const const_mul(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:478
if(!(yy_init))
Definition: ilang_lexer.cc:846
const BigUnsigned & getMagnitude() const
Definition: BigInteger.hh:83
RTLIL::Const const_reduce_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:198
RTLIL::Const const_reduce_xor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:208
RTLIL::Const const_sshl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:310
RTLIL::Const const_reduce_xnor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:213
RTLIL::Const const_xnor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:180
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
static YOSYS_NAMESPACE_BEGIN void extend_u0(RTLIL::Const &arg, int width, bool is_signed)
Definition: calc.cc:29
RTLIL::Const const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:303
RTLIL::Const const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:498
RTLIL::Const const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:296
bool isZero() const
Definition: BigUnsigned.hh:97
RTLIL::Const const_le(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:368
RTLIL::Const const_eqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:413
static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool sign_ext, int direction, int result_len)
Definition: calc.cc:271
RTLIL::Const const_sshr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:317
RTLIL::Const const_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:352
static RTLIL::Const const_shift_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool, bool signed2, int result_len, RTLIL::State other_bits)
Definition: calc.cc:324
bool isZero() const
Definition: BigInteger.hh:89
RTLIL::Const const_logic_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:241
RTLIL::Const const_reduce_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:203
#define YOSYS_NAMESPACE_BEGIN
Definition: yosys.h:99
RTLIL::Const const_nex(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:432
RTLIL::Const const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:485
RTLIL::Const const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:357
int toInt() const
Definition: BigInteger.cc:131
Sign getSign() const
Definition: BigInteger.hh:80
std::vector< RTLIL::State > bits
Definition: rtlil.h:438
static RTLIL::State logic_or(RTLIL::State a, RTLIL::State b)
Definition: calc.cc:102
RTLIL::Const const_neg(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:570
State
Definition: rtlil.h:29
RTLIL::Const const_add(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:464
static RTLIL::State logic_and(RTLIL::State a, RTLIL::State b)
Definition: calc.cc:93
RTLIL::Const const_reduce_bool(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:225
RTLIL::Const const_pos(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:562
RTLIL::Const const_gt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:453
RTLIL::Const const_shift(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:347
RTLIL::Const const_not(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:125
static RTLIL::Const big2const(const BigInteger &val, int result_len, int undef_bit_pos)
Definition: calc.cc:61
bool getBit(Index bi) const
Definition: BigUnsigned.hh:105