7bfdb895568434e2af019330aa3da045f044c930
2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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.
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.
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
24 #include "kernel/yosys.h"
25 #include "libs/bigint/BigIntegerLibrary.hh"
29 static void extend(RTLIL::Const
&arg
, int width
, bool is_signed
)
31 RTLIL::State padding
= RTLIL::State::S0
;
33 if (arg
.bits
.size() > 0 && (is_signed
|| arg
.bits
.back() > RTLIL::State::S1
))
34 padding
= arg
.bits
.back();
36 while (int(arg
.bits
.size()) < width
)
37 arg
.bits
.push_back(padding
);
39 arg
.bits
.resize(width
);
42 static void extend_u0(RTLIL::Const
&arg
, int width
, bool is_signed
)
44 RTLIL::State padding
= RTLIL::State::S0
;
46 if (arg
.bits
.size() > 0 && is_signed
)
47 padding
= arg
.bits
.back();
49 while (int(arg
.bits
.size()) < width
)
50 arg
.bits
.push_back(padding
);
52 arg
.bits
.resize(width
);
55 static BigInteger
const2big(const RTLIL::Const
&val
, bool as_signed
, int &undef_bit_pos
)
57 BigInteger result
= 0, this_bit
= 1;
58 for (size_t i
= 0; i
< val
.bits
.size(); i
++) {
59 if (val
.bits
[i
] == RTLIL::State::S1
) {
60 if (as_signed
&& i
+1 == val
.bits
.size())
65 else if (val
.bits
[i
] != RTLIL::State::S0
) {
66 if (undef_bit_pos
< 0)
74 static RTLIL::Const
big2const(const BigInteger
&val
, int result_len
, int undef_bit_pos
)
76 if (undef_bit_pos
>= 0)
77 return RTLIL::Const(RTLIL::State::Sx
, result_len
);
79 BigUnsigned mag
= val
.getMagnitude();
80 RTLIL::Const
result(0, result_len
);
84 if (val
.getSign() < 0)
87 for (int i
= 0; i
< result_len
; i
++)
88 result
.bits
[i
] = mag
.getBit(i
) ? RTLIL::State::S0
: RTLIL::State::S1
;
92 for (int i
= 0; i
< result_len
; i
++)
93 result
.bits
[i
] = mag
.getBit(i
) ? RTLIL::State::S1
: RTLIL::State::S0
;
98 if (undef_bit_pos
>= 0)
99 for (int i
= undef_bit_pos
; i
< result_len
; i
++)
100 result
.bits
[i
] = RTLIL::State::Sx
;
106 static RTLIL::State
logic_and(RTLIL::State a
, RTLIL::State b
)
108 if (a
== RTLIL::State::S0
) return RTLIL::State::S0
;
109 if (b
== RTLIL::State::S0
) return RTLIL::State::S0
;
110 if (a
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
111 if (b
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
112 return RTLIL::State::S1
;
115 static RTLIL::State
logic_or(RTLIL::State a
, RTLIL::State b
)
117 if (a
== RTLIL::State::S1
) return RTLIL::State::S1
;
118 if (b
== RTLIL::State::S1
) return RTLIL::State::S1
;
119 if (a
!= RTLIL::State::S0
) return RTLIL::State::Sx
;
120 if (b
!= RTLIL::State::S0
) return RTLIL::State::Sx
;
121 return RTLIL::State::S0
;
124 static RTLIL::State
logic_xor(RTLIL::State a
, RTLIL::State b
)
126 if (a
!= RTLIL::State::S0
&& a
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
127 if (b
!= RTLIL::State::S0
&& b
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
128 return a
!= b
? RTLIL::State::S1
: RTLIL::State::S0
;
131 static RTLIL::State
logic_xnor(RTLIL::State a
, RTLIL::State b
)
133 if (a
!= RTLIL::State::S0
&& a
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
134 if (b
!= RTLIL::State::S0
&& b
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
135 return a
== b
? RTLIL::State::S1
: RTLIL::State::S0
;
138 RTLIL::Const
RTLIL::const_not(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool signed1
, bool, int result_len
)
141 result_len
= arg1
.bits
.size();
143 RTLIL::Const arg1_ext
= arg1
;
144 extend_u0(arg1_ext
, result_len
, signed1
);
146 RTLIL::Const
result(RTLIL::State::Sx
, result_len
);
147 for (size_t i
= 0; i
< size_t(result_len
); i
++) {
148 if (i
>= arg1_ext
.bits
.size())
149 result
.bits
[i
] = RTLIL::State::S0
;
150 else if (arg1_ext
.bits
[i
] == RTLIL::State::S0
)
151 result
.bits
[i
] = RTLIL::State::S1
;
152 else if (arg1_ext
.bits
[i
] == RTLIL::State::S1
)
153 result
.bits
[i
] = RTLIL::State::S0
;
159 static RTLIL::Const
logic_wrapper(RTLIL::State(*logic_func
)(RTLIL::State
, RTLIL::State
),
160 RTLIL::Const arg1
, RTLIL::Const arg2
, bool signed1
, bool signed2
, int result_len
= -1)
163 result_len
= std::max(arg1
.bits
.size(), arg2
.bits
.size());
165 extend_u0(arg1
, result_len
, signed1
);
166 extend_u0(arg2
, result_len
, signed2
);
168 RTLIL::Const
result(RTLIL::State::Sx
, result_len
);
169 for (size_t i
= 0; i
< size_t(result_len
); i
++) {
170 RTLIL::State a
= i
< arg1
.bits
.size() ? arg1
.bits
[i
] : RTLIL::State::S0
;
171 RTLIL::State b
= i
< arg2
.bits
.size() ? arg2
.bits
[i
] : RTLIL::State::S0
;
172 result
.bits
[i
] = logic_func(a
, b
);
178 RTLIL::Const
RTLIL::const_and(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
180 return logic_wrapper(logic_and
, arg1
, arg2
, signed1
, signed2
, result_len
);
183 RTLIL::Const
RTLIL::const_or(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
185 return logic_wrapper(logic_or
, arg1
, arg2
, signed1
, signed2
, result_len
);
188 RTLIL::Const
RTLIL::const_xor(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
190 return logic_wrapper(logic_xor
, arg1
, arg2
, signed1
, signed2
, result_len
);
193 RTLIL::Const
RTLIL::const_xnor(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
195 return logic_wrapper(logic_xnor
, arg1
, arg2
, signed1
, signed2
, result_len
);
198 static RTLIL::Const
logic_reduce_wrapper(RTLIL::State initial
, RTLIL::State(*logic_func
)(RTLIL::State
, RTLIL::State
), const RTLIL::Const
&arg1
, int result_len
)
200 RTLIL::State temp
= initial
;
202 for (size_t i
= 0; i
< arg1
.bits
.size(); i
++)
203 temp
= logic_func(temp
, arg1
.bits
[i
]);
205 RTLIL::Const
result(temp
);
206 while (int(result
.bits
.size()) < result_len
)
207 result
.bits
.push_back(RTLIL::State::S0
);
211 RTLIL::Const
RTLIL::const_reduce_and(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int result_len
)
213 return logic_reduce_wrapper(RTLIL::State::S1
, logic_and
, arg1
, result_len
);
216 RTLIL::Const
RTLIL::const_reduce_or(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int result_len
)
218 return logic_reduce_wrapper(RTLIL::State::S0
, logic_or
, arg1
, result_len
);
221 RTLIL::Const
RTLIL::const_reduce_xor(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int result_len
)
223 return logic_reduce_wrapper(RTLIL::State::S0
, logic_xor
, arg1
, result_len
);
226 RTLIL::Const
RTLIL::const_reduce_xnor(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int result_len
)
228 RTLIL::Const buffer
= logic_reduce_wrapper(RTLIL::State::S0
, logic_xor
, arg1
, result_len
);
229 if (!buffer
.bits
.empty()) {
230 if (buffer
.bits
.front() == RTLIL::State::S0
)
231 buffer
.bits
.front() = RTLIL::State::S1
;
232 else if (buffer
.bits
.front() == RTLIL::State::S1
)
233 buffer
.bits
.front() = RTLIL::State::S0
;
238 RTLIL::Const
RTLIL::const_reduce_bool(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int result_len
)
240 return logic_reduce_wrapper(RTLIL::State::S0
, logic_or
, arg1
, result_len
);
243 RTLIL::Const
RTLIL::const_logic_not(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool signed1
, bool, int result_len
)
245 int undef_bit_pos_a
= -1;
246 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos_a
);
247 RTLIL::Const
result(a
.isZero() ? undef_bit_pos_a
>= 0 ? RTLIL::State::Sx
: RTLIL::State::S1
: RTLIL::State::S0
);
249 while (int(result
.bits
.size()) < result_len
)
250 result
.bits
.push_back(RTLIL::State::S0
);
254 RTLIL::Const
RTLIL::const_logic_and(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
256 int undef_bit_pos_a
= -1, undef_bit_pos_b
= -1;
257 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos_a
);
258 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos_b
);
260 RTLIL::State bit_a
= a
.isZero() ? undef_bit_pos_a
>= 0 ? RTLIL::State::Sx
: RTLIL::State::S0
: RTLIL::State::S1
;
261 RTLIL::State bit_b
= b
.isZero() ? undef_bit_pos_b
>= 0 ? RTLIL::State::Sx
: RTLIL::State::S0
: RTLIL::State::S1
;
262 RTLIL::Const
result(logic_and(bit_a
, bit_b
));
264 while (int(result
.bits
.size()) < result_len
)
265 result
.bits
.push_back(RTLIL::State::S0
);
269 RTLIL::Const
RTLIL::const_logic_or(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
271 int undef_bit_pos_a
= -1, undef_bit_pos_b
= -1;
272 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos_a
);
273 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos_b
);
275 RTLIL::State bit_a
= a
.isZero() ? undef_bit_pos_a
>= 0 ? RTLIL::State::Sx
: RTLIL::State::S0
: RTLIL::State::S1
;
276 RTLIL::State bit_b
= b
.isZero() ? undef_bit_pos_b
>= 0 ? RTLIL::State::Sx
: RTLIL::State::S0
: RTLIL::State::S1
;
277 RTLIL::Const
result(logic_or(bit_a
, bit_b
));
279 while (int(result
.bits
.size()) < result_len
)
280 result
.bits
.push_back(RTLIL::State::S0
);
284 static RTLIL::Const
const_shift_worker(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool sign_ext
, int direction
, int result_len
)
286 int undef_bit_pos
= -1;
287 BigInteger offset
= const2big(arg2
, false, undef_bit_pos
) * direction
;
290 result_len
= arg1
.bits
.size();
292 RTLIL::Const
result(RTLIL::State::Sx
, result_len
);
293 if (undef_bit_pos
>= 0)
296 for (int i
= 0; i
< result_len
; i
++) {
297 BigInteger pos
= BigInteger(i
) + offset
;
299 result
.bits
[i
] = RTLIL::State::S0
;
300 else if (pos
>= arg1
.bits
.size())
301 result
.bits
[i
] = sign_ext
? arg1
.bits
.back() : RTLIL::State::S0
;
303 result
.bits
[i
] = arg1
.bits
[pos
.toInt()];
309 RTLIL::Const
RTLIL::const_shl(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool, int result_len
)
311 RTLIL::Const arg1_ext
= arg1
;
312 extend_u0(arg1_ext
, result_len
, signed1
);
313 return const_shift_worker(arg1_ext
, arg2
, false, -1, result_len
);
316 RTLIL::Const
RTLIL::const_shr(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool, int result_len
)
318 RTLIL::Const arg1_ext
= arg1
;
319 extend_u0(arg1_ext
, std::max(result_len
, SIZE(arg1
)), signed1
);
320 return const_shift_worker(arg1_ext
, arg2
, false, +1, result_len
);
323 RTLIL::Const
RTLIL::const_sshl(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
326 return const_shl(arg1
, arg2
, signed1
, signed2
, result_len
);
327 return const_shift_worker(arg1
, arg2
, true, -1, result_len
);
330 RTLIL::Const
RTLIL::const_sshr(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
333 return const_shr(arg1
, arg2
, signed1
, signed2
, result_len
);
334 return const_shift_worker(arg1
, arg2
, true, +1, result_len
);
337 static RTLIL::Const
const_shift_shiftx(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool, bool signed2
, int result_len
, RTLIL::State other_bits
)
339 int undef_bit_pos
= -1;
340 BigInteger offset
= const2big(arg2
, signed2
, undef_bit_pos
);
343 result_len
= arg1
.bits
.size();
345 RTLIL::Const
result(RTLIL::State::Sx
, result_len
);
346 if (undef_bit_pos
>= 0)
349 for (int i
= 0; i
< result_len
; i
++) {
350 BigInteger pos
= BigInteger(i
) + offset
;
351 if (pos
< 0 || pos
>= arg1
.bits
.size())
352 result
.bits
[i
] = other_bits
;
354 result
.bits
[i
] = arg1
.bits
[pos
.toInt()];
360 RTLIL::Const
RTLIL::const_shift(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
362 return const_shift_shiftx(arg1
, arg2
, signed1
, signed2
, result_len
, RTLIL::State::S0
);
365 RTLIL::Const
RTLIL::const_shiftx(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
367 return const_shift_shiftx(arg1
, arg2
, signed1
, signed2
, result_len
, RTLIL::State::Sx
);
370 RTLIL::Const
RTLIL::const_lt(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
372 int undef_bit_pos
= -1;
373 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) < const2big(arg2
, signed2
, undef_bit_pos
);
374 RTLIL::Const
result(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
376 while (int(result
.bits
.size()) < result_len
)
377 result
.bits
.push_back(RTLIL::State::S0
);
381 RTLIL::Const
RTLIL::const_le(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
383 int undef_bit_pos
= -1;
384 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) <= const2big(arg2
, signed2
, undef_bit_pos
);
385 RTLIL::Const
result(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
387 while (int(result
.bits
.size()) < result_len
)
388 result
.bits
.push_back(RTLIL::State::S0
);
392 RTLIL::Const
RTLIL::const_eq(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
394 RTLIL::Const arg1_ext
= arg1
;
395 RTLIL::Const arg2_ext
= arg2
;
396 RTLIL::Const
result(RTLIL::State::S0
, result_len
);
398 int width
= std::max(arg1_ext
.bits
.size(), arg2_ext
.bits
.size());
399 extend_u0(arg1_ext
, width
, signed1
&& signed2
);
400 extend_u0(arg2_ext
, width
, signed1
&& signed2
);
402 RTLIL::State matched_status
= RTLIL::State::S1
;
403 for (size_t i
= 0; i
< arg1_ext
.bits
.size(); i
++) {
404 if (arg1_ext
.bits
.at(i
) == RTLIL::State::S0
&& arg2_ext
.bits
.at(i
) == RTLIL::State::S1
)
406 if (arg1_ext
.bits
.at(i
) == RTLIL::State::S1
&& arg2_ext
.bits
.at(i
) == RTLIL::State::S0
)
408 if (arg1_ext
.bits
.at(i
) > RTLIL::State::S1
|| arg2_ext
.bits
.at(i
) > RTLIL::State::S1
)
409 matched_status
= RTLIL::State::Sx
;
412 result
.bits
.front() = matched_status
;
416 RTLIL::Const
RTLIL::const_ne(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
418 RTLIL::Const result
= RTLIL::const_eq(arg1
, arg2
, signed1
, signed2
, result_len
);
419 if (result
.bits
.front() == RTLIL::State::S0
)
420 result
.bits
.front() = RTLIL::State::S1
;
421 else if (result
.bits
.front() == RTLIL::State::S1
)
422 result
.bits
.front() = RTLIL::State::S0
;
426 RTLIL::Const
RTLIL::const_eqx(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
428 RTLIL::Const arg1_ext
= arg1
;
429 RTLIL::Const arg2_ext
= arg2
;
430 RTLIL::Const
result(RTLIL::State::S0
, result_len
);
432 int width
= std::max(arg1_ext
.bits
.size(), arg2_ext
.bits
.size());
433 extend_u0(arg1_ext
, width
, signed1
&& signed2
);
434 extend_u0(arg2_ext
, width
, signed1
&& signed2
);
436 for (size_t i
= 0; i
< arg1_ext
.bits
.size(); i
++) {
437 if (arg1_ext
.bits
.at(i
) != arg2_ext
.bits
.at(i
))
441 result
.bits
.front() = RTLIL::State::S1
;
445 RTLIL::Const
RTLIL::const_nex(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
447 RTLIL::Const result
= RTLIL::const_eqx(arg1
, arg2
, signed1
, signed2
, result_len
);
448 if (result
.bits
.front() == RTLIL::State::S0
)
449 result
.bits
.front() = RTLIL::State::S1
;
450 else if (result
.bits
.front() == RTLIL::State::S1
)
451 result
.bits
.front() = RTLIL::State::S0
;
455 RTLIL::Const
RTLIL::const_ge(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
457 int undef_bit_pos
= -1;
458 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) >= const2big(arg2
, signed2
, undef_bit_pos
);
459 RTLIL::Const
result(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
461 while (int(result
.bits
.size()) < result_len
)
462 result
.bits
.push_back(RTLIL::State::S0
);
466 RTLIL::Const
RTLIL::const_gt(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
468 int undef_bit_pos
= -1;
469 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) > const2big(arg2
, signed2
, undef_bit_pos
);
470 RTLIL::Const
result(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
472 while (int(result
.bits
.size()) < result_len
)
473 result
.bits
.push_back(RTLIL::State::S0
);
477 RTLIL::Const
RTLIL::const_add(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
479 int undef_bit_pos
= -1;
480 BigInteger y
= const2big(arg1
, signed1
, undef_bit_pos
) + const2big(arg2
, signed2
, undef_bit_pos
);
481 return big2const(y
, result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), undef_bit_pos
);
484 RTLIL::Const
RTLIL::const_sub(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
486 int undef_bit_pos
= -1;
487 BigInteger y
= const2big(arg1
, signed1
, undef_bit_pos
) - const2big(arg2
, signed2
, undef_bit_pos
);
488 return big2const(y
, result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), undef_bit_pos
);
491 RTLIL::Const
RTLIL::const_mul(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
493 int undef_bit_pos
= -1;
494 BigInteger y
= const2big(arg1
, signed1
, undef_bit_pos
) * const2big(arg2
, signed2
, undef_bit_pos
);
495 return big2const(y
, result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), std::min(undef_bit_pos
, 0));
498 RTLIL::Const
RTLIL::const_div(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
500 int undef_bit_pos
= -1;
501 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos
);
502 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos
);
504 return RTLIL::Const(RTLIL::State::Sx
, result_len
);
505 bool result_neg
= (a
.getSign() == BigInteger::negative
) != (b
.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));
511 RTLIL::Const
RTLIL::const_mod(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
513 int undef_bit_pos
= -1;
514 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos
);
515 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos
);
517 return RTLIL::Const(RTLIL::State::Sx
, result_len
);
518 bool result_neg
= a
.getSign() == BigInteger::negative
;
519 a
= a
.getSign() == BigInteger::negative
? -a
: a
;
520 b
= b
.getSign() == BigInteger::negative
? -b
: b
;
521 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));
524 RTLIL::Const
RTLIL::const_pow(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
526 int undef_bit_pos
= -1;
528 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos
);
529 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos
);
533 return RTLIL::Const(RTLIL::State::Sx
, result_len
);
536 return RTLIL::Const(RTLIL::State::S0
, result_len
);
543 y
= (-b
% 2) == 0 ? 1 : -1;
548 // Power-modulo with 2^result_len as modulus
549 BigInteger modulus
= 1;
550 int modulus_bits
= (result_len
>= 0 ? result_len
: 1024);
551 for (int i
= 0; i
< modulus_bits
; i
++)
554 bool flip_result_sign
= false;
558 flip_result_sign
= true;
563 y
= (y
* a
) % modulus
;
565 a
= (a
* a
) % modulus
;
568 if (flip_result_sign
)
572 return big2const(y
, result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), std::min(undef_bit_pos
, 0));
575 RTLIL::Const
RTLIL::const_pos(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool signed1
, bool, int result_len
)
577 RTLIL::Const arg1_ext
= arg1
;
578 extend(arg1_ext
, result_len
, signed1
);
583 RTLIL::Const
RTLIL::const_bu0(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool signed1
, bool, int result_len
)
585 RTLIL::Const arg1_ext
= arg1
;
586 extend_u0(arg1_ext
, result_len
, signed1
);
591 RTLIL::Const
RTLIL::const_neg(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool signed1
, bool, int result_len
)
593 RTLIL::Const arg1_ext
= arg1
;
594 extend(arg1_ext
, result_len
, signed1
);
596 RTLIL::Const
zero(RTLIL::State::S0
, 1);
597 return RTLIL::const_sub(zero
, arg1_ext
, false, signed1
, result_len
);