17#ifndef __AP_INT_BASE_H__
18#define __AP_INT_BASE_H__
21#error "Only ap_fixed.h and ap_int.h can be included directly in user code."
25#error "C++ is required to include this header file"
30#if _AP_ENABLE_HALF_ == 1
46template <
int _AP_N,
bool _AP_S>
51struct retval<_AP_N, true> {
52 typedef ap_slong Type;
56struct retval<_AP_N, false> {
57 typedef ap_ulong Type;
62struct retval<1, true> {
63 typedef signed char Type;
67struct retval<1, false> {
68 typedef unsigned char Type;
73struct retval<2, true> {
78struct retval<2, false> {
79 typedef unsigned short Type;
84struct retval<3, true> {
89struct retval<3, false> {
90 typedef unsigned long Type;
94struct retval<4, true> {
99struct retval<4, false> {
100 typedef unsigned long Type;
106template <
int _AP_W2,
bool _AP_S2>
107struct _ap_int_factory;
109struct _ap_int_factory<_AP_W2, true> {
113struct _ap_int_factory<_AP_W2, false> {
117template <
int _AP_W,
bool _AP_S>
118struct ap_int_base :
public _AP_ROOT_TYPE<_AP_W, _AP_S> {
120 typedef _AP_ROOT_TYPE<_AP_W, _AP_S>
Base;
128 typedef typename retval<AP_MAX((_AP_W + 7) / 8, 8), _AP_S>::Type RetType;
130 static const int width = _AP_W;
132 template <
int _AP_W2,
bool _AP_S2>
135 mult_w = _AP_W + _AP_W2,
136 mult_s = _AP_S || _AP_S2,
138 AP_MAX(_AP_W + (_AP_S2 && !_AP_S), _AP_W2 + (_AP_S && !_AP_S2)) + 1,
139 plus_s = _AP_S || _AP_S2,
141 AP_MAX(_AP_W + (_AP_S2 && !_AP_S), _AP_W2 + (_AP_S && !_AP_S2)) + 1,
143 div_w = _AP_W + _AP_S2,
144 div_s = _AP_S || _AP_S2,
145 mod_w = AP_MIN(_AP_W, _AP_W2 + (!_AP_S2 && _AP_S)),
147 logic_w = AP_MAX(_AP_W + (_AP_S2 && !_AP_S), _AP_W2 + (_AP_S && !_AP_S2)),
148 logic_s = _AP_S || _AP_S2
159 typedef typename _ap_int_factory<mult_w, mult_s>::type mult;
160 typedef typename _ap_int_factory<plus_w, plus_s>::type plus;
161 typedef typename _ap_int_factory<minus_w, minus_s>::type minus;
162 typedef typename _ap_int_factory<logic_w, logic_s>::type logic;
163 typedef typename _ap_int_factory<div_w, div_s>::type div;
164 typedef typename _ap_int_factory<mod_w, mod_s>::type mod;
165 typedef typename _ap_int_factory<_AP_W, _AP_S>::type arg1;
182 template <
int _AP_W2,
bool _AP_S2>
188 template <
int _AP_W2,
bool _AP_S2>
203#define CTOR_FROM_INT(Type, Size, Signed) \
204 INLINE ap_int_base(const Type op) { Base::V = op; }
206 CTOR_FROM_INT(
bool, 1,
false)
207 CTOR_FROM_INT(
char, 8, CHAR_IS_SIGNED)
208 CTOR_FROM_INT(
signed char, 8, true)
209 CTOR_FROM_INT(
unsigned char, 8, false)
210 CTOR_FROM_INT(
short, _AP_SIZE_short, true)
211 CTOR_FROM_INT(
unsigned short, _AP_SIZE_short, false)
212 CTOR_FROM_INT(
int, _AP_SIZE_int, true)
213 CTOR_FROM_INT(
unsigned int, _AP_SIZE_int, false)
214 CTOR_FROM_INT(
long, _AP_SIZE_long, true)
215 CTOR_FROM_INT(
unsigned long, _AP_SIZE_long, false)
216 CTOR_FROM_INT(ap_slong, _AP_SIZE_ap_slong, true)
217 CTOR_FROM_INT(ap_ulong, _AP_SIZE_ap_slong, false)
220#if _AP_ENABLE_HALF_ == 1
231 const int BITS = FLOAT_MAN + FLOAT_EXP + 1;
233 reg.V = floatToRawBits(op);
234 bool is_neg = _AP_ROOT_op_get_bit(reg.V, BITS - 1);
237 exp.V = _AP_ROOT_op_get_range(reg.V, FLOAT_MAN, BITS - 2);
238 exp = exp - FLOAT_BIAS;
241 man.V = _AP_ROOT_op_get_range(reg.V, 0, FLOAT_MAN - 1);
243 _AP_WARNING(exp == ((
unsigned char)(FLOAT_BIAS + 1)) && man.V != 0,
244 "assign NaN to ap integer value");
246 man.V = _AP_ROOT_op_set_bit(man.V, FLOAT_MAN, 1);
249 if ((reg.V & 0x7ffffffful) == 0) {
252 int sh_amt = FLOAT_MAN - exp.V;
255 }
else if (sh_amt > 0) {
256 if (sh_amt < FLOAT_MAN + 2) {
257 Base::V = man.V >> sh_amt;
266 if (sh_amt < _AP_W) {
274 if (is_neg) *
this = -(*this);
279 const int BITS = DOUBLE_MAN + DOUBLE_EXP + 1;
281 reg.V = doubleToRawBits(op);
282 bool is_neg = _AP_ROOT_op_get_bit(reg.V, BITS - 1);
285 exp.V = _AP_ROOT_op_get_range(reg.V, DOUBLE_MAN, BITS - 2);
286 exp = exp - DOUBLE_BIAS;
289 man.V = _AP_ROOT_op_get_range(reg.V, 0, DOUBLE_MAN - 1);
291 _AP_WARNING(exp == ((
unsigned char)(DOUBLE_BIAS + 1)) && man.V != 0,
292 "assign NaN to ap integer value");
294 man.V = _AP_ROOT_op_set_bit(man.V, DOUBLE_MAN, 1);
297 if ((reg.V & 0x7fffffffffffffffull) == 0) {
300 int sh_amt = DOUBLE_MAN - exp.V;
303 }
else if (sh_amt > 0) {
304 if (sh_amt < DOUBLE_MAN + 2) {
305 Base::V = man.V >> sh_amt;
314 if (sh_amt < _AP_W) {
322 if (is_neg) *
this = -(*this);
326 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
327 ap_o_mode _AP_O2,
int _AP_N2>
330 Base::V = op.to_ap_int_base().V;
333 template <
int _AP_W2,
bool _AP_S2>
335 Base::V = (ref.get()).V;
338 template <
int _AP_W2,
bool _AP_S2>
340 Base::V = ref.operator bool();
343 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
354 INLINE
ap_int_base(
const char* s,
signed char rd = 0) {
355 if (rd == 0) rd = guess_radix(s);
356 unsigned int length = strlen(s);
357 Base::V.fromString(s, length, rd);
363 _ssdm_string2bits((
void*)(&t), (
const char*)(s), 10, _AP_W, _AP_S, AP_TRN,
364 AP_WRAP, 0, _AP_C99);
367 INLINE
ap_int_base(
const char* s,
signed char rd) {
369 _ssdm_string2bits((
void*)(&t), (
const char*)(s), rd, _AP_W, _AP_S, AP_TRN,
370 AP_WRAP, 0, _AP_C99);
375 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
376 ap_o_mode _AP_O2,
int _AP_N2>
379 Base::V = (val.get()).V;
382 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
383 ap_o_mode _AP_O2,
int _AP_N2>
386 Base::V = val.operator bool();
402 template <
int _AP_W2,
bool _AP_S2>
403 INLINE
void operator=(
408 INLINE
void operator=(
413 template <
int _AP_W2,
bool _AP_S2>
422 template <
int _AP_W2,
bool _AP_S2>
429 template <
int _AP_W2,
bool _AP_S2>
445#define ASSIGN_OP_FROM_INT(Type, Size, Signed) \
446 INLINE ap_int_base& operator=(Type op) { \
451 ASSIGN_OP_FROM_INT(
bool, 1,
false)
452 ASSIGN_OP_FROM_INT(
char, 8, CHAR_IS_SIGNED)
453 ASSIGN_OP_FROM_INT(
signed char, 8, true)
454 ASSIGN_OP_FROM_INT(
unsigned char, 8, false)
455 ASSIGN_OP_FROM_INT(
short, _AP_SIZE_short, true)
456 ASSIGN_OP_FROM_INT(
unsigned short, _AP_SIZE_short, false)
457 ASSIGN_OP_FROM_INT(
int, _AP_SIZE_int, true)
458 ASSIGN_OP_FROM_INT(
unsigned int, _AP_SIZE_int, false)
459 ASSIGN_OP_FROM_INT(
long, _AP_SIZE_long, true)
460 ASSIGN_OP_FROM_INT(
unsigned long, _AP_SIZE_long, false)
461 ASSIGN_OP_FROM_INT(ap_slong, _AP_SIZE_ap_slong, true)
462 ASSIGN_OP_FROM_INT(ap_ulong, _AP_SIZE_ap_slong, false)
464#undef ASSIGN_OP_FROM_INT
466 template <
int _AP_W2,
bool _AP_S2>
472 template <
int _AP_W2,
bool _AP_S2>
478 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
481 Base::V = op2.get().V;
485 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
486 ap_o_mode _AP_O2,
int _AP_N2>
489 Base::V = op.to_ap_int_base().V;
493 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
494 ap_o_mode _AP_O2,
int _AP_N2>
501 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
502 ap_o_mode _AP_O2,
int _AP_N2>
513 INLINE
operator RetType()
const {
return (RetType)(Base::V); }
518 INLINE
bool to_bool()
const {
return (
bool)(Base::V); }
519 INLINE
char to_char()
const {
return (
char)(Base::V); }
520 INLINE
signed char to_schar()
const {
return (
signed char)(Base::V); }
521 INLINE
unsigned char to_uchar()
const {
return (
unsigned char)(Base::V); }
522 INLINE
short to_short()
const {
return (
short)(Base::V); }
523 INLINE
unsigned short to_ushort()
const {
return (
unsigned short)(Base::V); }
524 INLINE
int to_int()
const {
return (
int)(Base::V); }
525 INLINE
unsigned to_uint()
const {
return (
unsigned)(Base::V); }
526 INLINE
long to_long()
const {
return (
long)(Base::V); }
527 INLINE
unsigned long to_ulong()
const {
return (
unsigned long)(Base::V); }
528 INLINE ap_slong to_int64()
const {
return (ap_slong)(Base::V); }
529 INLINE ap_ulong to_uint64()
const {
return (ap_ulong)(Base::V); }
530 INLINE
float to_float()
const {
return (
float)(Base::V); }
531 INLINE
double to_double()
const {
return (
double)(Base::V); }
535 INLINE
operator char()
const {
return (
char)(Base::V); }
536 INLINE
operator signed char()
const {
return (
signed char)(Base::V); }
537 INLINE
operator unsigned char()
const {
return (
unsigned char)(Base::V); }
538 INLINE
operator short()
const {
return (
short)(Base::V); }
539 INLINE
operator unsigned short()
const {
return (
unsigned short)(Base::V); }
540 INLINE
operator int()
const {
return (
int)(Base::V); }
541 INLINE
operator unsigned int ()
const {
return (
unsigned)(Base::V); }
542 INLINE
operator long ()
const {
return (
long)(Base::V); }
543 INLINE
operator unsigned long ()
const {
return (
unsigned long)(Base::V); }
544 INLINE
operator ap_slong () {
return (ap_slong)(Base::V); }
545 INLINE
operator ap_ulong () {
return (ap_ulong)(Base::V); }
555 INLINE
int length()
const volatile {
return _AP_W; }
558 INLINE
bool iszero()
const {
return Base::V == 0; }
561 INLINE
bool is_zero()
const {
return Base::V == 0; }
564 INLINE
bool sign()
const {
565 if (_AP_S && _AP_ROOT_op_get_bit(Base::V, _AP_W - 1))
572 INLINE
void clear(
int i) {
573 AP_ASSERT(i >= 0 && i < _AP_W,
"position out of range");
574 Base::V = _AP_ROOT_op_set_bit(Base::V, i, 0);
578 INLINE
void invert(
int i) {
579 AP_ASSERT(i >= 0 && i < _AP_W,
"position out of range");
580 bool val = _AP_ROOT_op_get_bit(Base::V, i);
582 Base::V = _AP_ROOT_op_set_bit(Base::V, i, 0);
584 Base::V = _AP_ROOT_op_set_bit(Base::V, i, 1);
587 INLINE
bool test(
int i)
const {
588 AP_ASSERT(i >= 0 && i < _AP_W,
"position out of range");
589 return _AP_ROOT_op_get_bit(Base::V, i);
596 INLINE
void set(
int i) {
597 AP_ASSERT(i >= 0 && i < _AP_W,
"position out of range");
598 Base::V = _AP_ROOT_op_set_bit(Base::V, i, 1);
602 INLINE
void set(
int i,
bool v) {
603 AP_ASSERT(i >= 0 && i < _AP_W,
"position out of range");
604 Base::V = _AP_ROOT_op_set_bit(Base::V, i, v);
610 AP_ASSERT(n >= 0 && n < _AP_W,
"shift value out of range");
613 typeof(Base::V) l_p = Base::V << n;
614 typeof(Base::V) r_p = Base::V >> (_AP_W - n);
625 AP_ASSERT(n >= 0 && n < _AP_W,
"shift value out of range");
628 typeof(Base::V) l_p = Base::V << (_AP_W - n);
629 typeof(Base::V) r_p = Base::V >> n;
640 Base::V = _AP_ROOT_op_get_range(Base::V, _AP_W - 1, 0);
645 INLINE
void set_bit(
int i,
bool v) {
646 Base::V = _AP_ROOT_op_set_bit(Base::V, i, v);
650 INLINE
bool get_bit(
int i)
const {
651 return (
bool)_AP_ROOT_op_get_bit(Base::V, i);
655 INLINE
void b_not() { Base::V =
~Base::V; }
657#define OP_ASSIGN_AP(Sym) \
658 template <int _AP_W2, bool _AP_S2> \
659 INLINE ap_int_base& operator Sym(const ap_int_base<_AP_W2, _AP_S2>& op2) { \
677#define OP_ASSIGN_AP_CHK(Sym) \
678 template <int _AP_W2, bool _AP_S2> \
679 INLINE ap_int_base& operator Sym(const ap_int_base<_AP_W2, _AP_S2>& op2) { \
680 _AP_WARNING((_AP_W != _AP_W2), \
681 "Bitsize mismatch for ap_[u]int" #Sym "ap_[u]int."); \
688#undef OP_ASSIGN_AP_CHK
705 INLINE
const typename RType<_AP_W, _AP_S>::arg1 operator++(
int) {
710 INLINE
const typename RType<_AP_W, _AP_S>::arg1 operator--(
int) {
719 INLINE
typename RType<_AP_W, _AP_S>::arg1 operator+()
const {
return *
this; }
722 INLINE
typename RType<1, false>::minus operator-()
const {
729 INLINE
bool operator!()
const {
return Base::V == 0; }
735 INLINE
typename RType<_AP_W, _AP_S>::arg1 operator~()
const {
744 template <
int _AP_W2>
745 INLINE
typename RType<_AP_W, _AP_S>::arg1 operator<<(
747 bool isNeg = _AP_ROOT_op_get_bit(op2.V, _AP_W2 - 1);
751 return operator>>(sh);
753 return operator<<(sh);
756 template <
int _AP_W2>
757 INLINE
typename RType<_AP_W, _AP_S>::arg1 operator<<(
760 r.V = Base::V << op2.to_uint();
764 template <
int _AP_W2>
765 INLINE
typename RType<_AP_W, _AP_S>::arg1 operator>>(
767 bool isNeg = _AP_ROOT_op_get_bit(op2.V, _AP_W2 - 1);
771 return operator<<(sh);
773 return operator>>(sh);
776 template <
int _AP_W2>
777 INLINE
typename RType<_AP_W, _AP_S>::arg1 operator>>(
780 r.V = Base::V >> op2.to_uint();
786 template <
int _AP_W2,
bool _AP_S2>
791 template <
int _AP_W2,
bool _AP_S2>
800 template <
int _AP_W2>
802 bool isNeg = _AP_ROOT_op_get_bit(op2.V, _AP_W2 - 1);
806 return operator>>=(sh);
808 return operator<<=(sh);
811 template <
int _AP_W2>
813 Base::V <<= op2.to_uint();
817 template <
int _AP_W2>
819 bool isNeg = _AP_ROOT_op_get_bit(op2.V, _AP_W2 - 1);
823 return operator<<=(sh);
825 return operator>>=(sh);
828 template <
int _AP_W2>
830 Base::V >>= op2.to_uint();
836 template <
int _AP_W2,
bool _AP_S2>
840 template <
int _AP_W2,
bool _AP_S2>
849 template <
int _AP_W2,
bool _AP_S2>
851 return Base::V == op2.V;
853 template <
int _AP_W2,
bool _AP_S2>
855 return !(Base::V == op2.V);
857 template <
int _AP_W2,
bool _AP_S2>
859 return Base::V < op2.V;
861 template <
int _AP_W2,
bool _AP_S2>
863 return Base::V >= op2.V;
865 template <
int _AP_W2,
bool _AP_S2>
867 return Base::V > op2.V;
869 template <
int _AP_W2,
bool _AP_S2>
871 return Base::V <= op2.V;
878 _AP_ERROR(Hi >= _AP_W,
"Hi(%d)out of bound(%d) in range()", Hi, _AP_W);
879 _AP_ERROR(Lo >= _AP_W,
"Lo(%d)out of bound(%d) in range()", Lo, _AP_W);
885 _AP_ERROR(Hi >= _AP_W,
"Hi(%d)out of bound(%d) in range()", Hi, _AP_W);
886 _AP_ERROR(Lo >= _AP_W,
"Lo(%d)out of bound(%d) in range()", Lo, _AP_W);
890 template <
int _AP_W2,
bool _AP_S2,
int _AP_W3,
bool _AP_S3>
894 int Hi = HiIdx.to_int();
895 int Lo = LoIdx.to_int();
896 return this->range(Hi, Lo);
899 template <
int _AP_W2,
bool _AP_S2,
int _AP_W3,
bool _AP_S3>
903 int Hi = HiIdx.to_int();
904 int Lo = LoIdx.to_int();
905 return this->range(Hi, Lo);
909 return this->range(_AP_W - 1, 0);
913 return this->range(_AP_W - 1, 0);
917 return this->range(Hi, Lo);
921 return this->range(Hi, Lo);
924 template <
int _AP_W2,
bool _AP_S2,
int _AP_W3,
bool _AP_S3>
928 int Hi = HiIdx.to_int();
929 int Lo = LoIdx.to_int();
930 return this->range(Hi, Lo);
933 template <
int _AP_W2,
bool _AP_S2,
int _AP_W3,
bool _AP_S3>
937 int Hi = HiIdx.to_int();
938 int Lo = LoIdx.to_int();
939 return this->range(Hi, Lo);
943 template<
int Hi,
int Lo>
945 AP_ASSERT(Hi >= Lo && Hi < _AP_W && Lo < _AP_W,
"Out of bounds in slice()");
947 tmp.V = _AP_ROOT_op_get_range(Base::V, Lo, Hi);
952 AP_ASSERT(uindex < _AP_W,
"Attempting to read bit beyond MSB");
959 AP_ASSERT(index >= 0,
"Attempting to read bit with negative index");
960 AP_ASSERT(index < _AP_W,
"Attempting to read bit beyond MSB");
965 template <
int _AP_W2,
bool _AP_S2>
968 AP_ASSERT(index >= 0,
"Attempting to read bit with negative index");
969 AP_ASSERT(index < _AP_W,
"Attempting to read bit beyond MSB");
974 INLINE
bool operator[](
int index)
const {
975 AP_ASSERT(index >= 0,
"Attempting to read bit with negative index");
976 AP_ASSERT(index < _AP_W,
"Attempting to read bit beyond MSB");
980 template <
int _AP_W2,
bool _AP_S2>
982 AP_ASSERT(index < _AP_W,
"Attempting to read bit beyond MSB");
988 AP_ASSERT(index >= 0,
"Attempting to read bit with negative index");
989 AP_ASSERT(index < _AP_W,
"Attempting to read bit beyond MSB");
993 template <
int _AP_W2,
bool _AP_S2>
996 AP_ASSERT(index >= 0,
"Attempting to read bit with negative index");
997 AP_ASSERT(index < _AP_W,
"Attempting to read bit beyond MSB");
1002 INLINE
bool bit(
int index)
const {
1003 AP_ASSERT(index >= 0,
"Attempting to read bit with negative index");
1004 AP_ASSERT(index < _AP_W,
"Attempting to read bit beyond MSB");
1006 return br.to_bool();
1009 template <
int _AP_W2,
bool _AP_S2>
1011 return bit(index.to_int());
1015 template<
typename _AP_T>
1016 INLINE
bool operator[](_AP_T index)
const {
1017 AP_ASSERT(index < _AP_W,
"Attempting to read bit beyond MSB");
1019 return br.to_bool();
1025 INLINE
int countLeadingZeros() {
1029 x.V = _AP_ROOT_op_get_range(this->V, _AP_W - 1, 0);
1030 t.V = _AP_ROOT_op_set_range(t.V, 0, _AP_W - 1, x.V);
1031 return __builtin_ctz(t.V);
1032 }
else if (_AP_W <= 64) {
1035 x.V = _AP_ROOT_op_get_range(this->V, _AP_W - 1, 0);
1036 t.V = _AP_ROOT_op_set_range(t.V, 0, _AP_W - 1, x.V);
1037 return __builtin_ctzll(t.V);
1039 enum {__N = (_AP_W + 63) / 64};
1042 bool hitNonZero =
false;
1043 for (i = 0; i < __N - 1; ++i) {
1045 t.V = _AP_ROOT_op_get_range(this->V, _AP_W - i * 64 - 64,
1046 _AP_W - i * 64 - 1);
1048 hitNonZero ? 0 : __builtin_clzll(t.V);
1049 hitNonZero |= (t.V != 0);
1053 enum {REST = (_AP_W - 1) % 64};
1055 x.V = _AP_ROOT_op_get_range(this->V, 0, REST);
1056 t.V = _AP_ROOT_op_set_range(t.V, 63 - REST, 63, x.V);
1057 NZeros += __builtin_clzll(t.V);
1062 return (Base::V).countLeadingZeros();
1066 template <
int _AP_W2,
bool _AP_S2>
1075 template <
int _AP_W2,
bool _AP_S2>
1082 template <
int _AP_W2,
bool _AP_S2>
1092 template <
int _AP_W2,
bool _AP_S2>
1100 template <
int _AP_W2,
bool _AP_S2>
1108 template <
int _AP_W2,
bool _AP_S2>
1116 template <
int _AP_W2,
bool _AP_S2>
1125 template <
int _AP_W2,
bool _AP_S2>
1132 template <
int _AP_W2,
bool _AP_S2>
1140 template <
int _AP_W2,
bool _AP_S2>
1147 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
1157 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
1166 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
1167 ap_o_mode _AP_O2,
int _AP_N2>
1181 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
1182 ap_o_mode _AP_O2,
int _AP_N2>
1193 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
1194 ap_o_mode _AP_O2,
int _AP_N2>
1208 template <
int _AP_W2,
int _AP_I2,
bool _AP_S2, ap_q_mode _AP_Q2,
1209 ap_o_mode _AP_O2,
int _AP_N2>
1219 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
1220 INLINE
ap_int_base<AP_MAX(_AP_W2 + _AP_W3, _AP_W), _AP_S> operator&(
1222 return *
this & a2.get();
1225 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
1226 INLINE
ap_int_base<AP_MAX(_AP_W2 + _AP_W3, _AP_W), _AP_S> operator|(
1228 return *
this | a2.get();
1231 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
1232 INLINE
ap_int_base<AP_MAX(_AP_W2 + _AP_W3, _AP_W), _AP_S> operator^(
1234 return *
this ^ a2.get();
1237 template <
int _AP_W3>
1246 INLINE
bool and_reduce()
const {
return _AP_ROOT_op_reduce(and, Base::V); }
1247 INLINE
bool nand_reduce()
const {
return _AP_ROOT_op_reduce(nand, Base::V); }
1248 INLINE
bool or_reduce()
const {
return _AP_ROOT_op_reduce(or, Base::V); }
1249 INLINE
bool nor_reduce()
const {
return !(_AP_ROOT_op_reduce(or, Base::V)); }
1250 INLINE
bool xor_reduce()
const {
return _AP_ROOT_op_reduce(xor, Base::V); }
1251 INLINE
bool xnor_reduce()
const {
1252 return !(_AP_ROOT_op_reduce(xor, Base::V));
1258#ifndef __SYNTHESIS__
1259 std::string to_string(
signed char rd = 2,
bool sign = _AP_S)
const {
1262 if (rd == 2) sign =
false;
1263 return (Base::V).to_string(rd, sign);
1266 INLINE
char* to_string(
signed char rd = 2,
bool sign = _AP_S)
const {
1274#ifndef __SYNTHESIS__
1275template <
int _AP_W,
bool _AP_S>
1276INLINE std::ostream& operator<<(std::ostream& os,
1278 std::ios_base::fmtflags ff = std::cout.flags();
1279 if (ff & std::cout.hex) {
1280 os << x.to_string(16);
1281 }
else if (ff & std::cout.oct) {
1282 os << x.to_string(8);
1284 os << x.to_string(10);
1290#ifndef __SYNTHESIS__
1291template <
int _AP_W,
bool _AP_S>
1292INLINE std::istream& operator>>(std::istream& in,
1296 const std::ios_base::fmtflags basefield =
1297 in.flags() & std::ios_base::basefield;
1298 unsigned radix = (basefield == std::ios_base::dec)
1300 : ((basefield == std::ios_base::oct)
1302 : ((basefield == std::ios_base::hex) ? 16 : 0));
1312#define OP_BIN_AP(Sym, Rty) \
1313 template <int _AP_W, bool _AP_S, int _AP_W2, bool _AP_S2> \
1315 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, _AP_S2>::Rty \
1316 operator Sym(const ap_int_base<_AP_W, _AP_S>& op, \
1317 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1318 typename ap_int_base<_AP_W, _AP_S>::template RType< \
1319 _AP_W2, _AP_S2>::Rty##_base lhs(op); \
1320 typename ap_int_base<_AP_W, _AP_S>::template RType< \
1321 _AP_W2, _AP_S2>::Rty##_base rhs(op2); \
1322 typename ap_int_base<_AP_W, _AP_S>::template RType< \
1323 _AP_W2, _AP_S2>::Rty##_base ret; \
1324 ret.V = lhs.V Sym rhs.V; \
1335#define OP_BIN_AP2(Sym, Rty) \
1336 template <int _AP_W, bool _AP_S, int _AP_W2, bool _AP_S2> \
1338 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, _AP_S2>::Rty \
1339 operator Sym(const ap_int_base<_AP_W, _AP_S>& op, \
1340 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1341 typename ap_int_base<_AP_W, _AP_S>::template RType< \
1342 _AP_W2, _AP_S2>::Rty##_base ret; \
1343 ret.V = op.V Sym op2.V; \
1361#define OP_BIN_WITH_PTR(BIN_OP) \
1362 template <typename PTR_TYPE, int _AP_W, bool _AP_S> \
1363 INLINE PTR_TYPE* operator BIN_OP(PTR_TYPE* i_op, \
1364 const ap_int_base<_AP_W, _AP_S>& op) { \
1365 ap_slong op2 = op.to_int64(); \
1366 return i_op BIN_OP op2; \
1368 template <typename PTR_TYPE, int _AP_W, bool _AP_S> \
1369 INLINE PTR_TYPE* operator BIN_OP(const ap_int_base<_AP_W, _AP_S>& op, \
1371 ap_slong op2 = op.to_int64(); \
1372 return op2 BIN_OP i_op; \
1383#define OP_BIN_WITH_FLOAT(BIN_OP, C_TYPE) \
1384 template <int _AP_W, bool _AP_S> \
1385 INLINE C_TYPE operator BIN_OP(C_TYPE i_op, \
1386 const ap_int_base<_AP_W, _AP_S>& op) { \
1387 typename ap_int_base<_AP_W, _AP_S>::RetType op2 = op; \
1388 return i_op BIN_OP op2; \
1390 template <int _AP_W, bool _AP_S> \
1391 INLINE C_TYPE operator BIN_OP(const ap_int_base<_AP_W, _AP_S>& op, \
1393 typename ap_int_base<_AP_W, _AP_S>::RetType op2 = op; \
1394 return op2 BIN_OP i_op; \
1397#define ALL_OP_WITH_FLOAT(C_TYPE) \
1398 OP_BIN_WITH_FLOAT(*, C_TYPE) \
1399 OP_BIN_WITH_FLOAT(/, C_TYPE) \
1400 OP_BIN_WITH_FLOAT(+, C_TYPE) \
1401 OP_BIN_WITH_FLOAT(-, C_TYPE)
1403#if _AP_ENABLE_HALF_ == 1
1404ALL_OP_WITH_FLOAT(half)
1406ALL_OP_WITH_FLOAT(
float)
1407ALL_OP_WITH_FLOAT(
double)
1415#define OP_BIN_WITH_INT(BIN_OP, C_TYPE, _AP_W2, _AP_S2, RTYPE) \
1416 template <int _AP_W, bool _AP_S> \
1417 INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, \
1419 operator BIN_OP(C_TYPE i_op, const ap_int_base<_AP_W, _AP_S>& op) { \
1420 return ap_int_base<_AP_W2, _AP_S2>(i_op) BIN_OP(op); \
1422 template <int _AP_W, bool _AP_S> \
1423 INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, \
1425 operator BIN_OP(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE i_op) { \
1426 return op BIN_OP ap_int_base<_AP_W2, _AP_S2>(i_op); \
1429#define ALL_OP_BIN_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1430 OP_BIN_WITH_INT(*, C_TYPE, _AP_W2, _AP_S2, mult) \
1431 OP_BIN_WITH_INT(+, C_TYPE, _AP_W2, _AP_S2, plus) \
1432 OP_BIN_WITH_INT(-, C_TYPE, _AP_W2, _AP_S2, minus) \
1433 OP_BIN_WITH_INT(/, C_TYPE, _AP_W2, _AP_S2, div) \
1434 OP_BIN_WITH_INT(%, C_TYPE, _AP_W2, _AP_S2, mod) \
1435 OP_BIN_WITH_INT(&, C_TYPE, _AP_W2, _AP_S2, logic) \
1436 OP_BIN_WITH_INT(|, C_TYPE, _AP_W2, _AP_S2, logic) \
1437 OP_BIN_WITH_INT(^, C_TYPE, _AP_W2, _AP_S2, logic)
1439ALL_OP_BIN_WITH_INT(
bool, 1,
false)
1440ALL_OP_BIN_WITH_INT(
char, 8, CHAR_IS_SIGNED)
1441ALL_OP_BIN_WITH_INT(
signed char, 8, true)
1442ALL_OP_BIN_WITH_INT(
unsigned char, 8, false)
1443ALL_OP_BIN_WITH_INT(
short, _AP_SIZE_short, true)
1444ALL_OP_BIN_WITH_INT(
unsigned short, _AP_SIZE_short, false)
1445ALL_OP_BIN_WITH_INT(
int, _AP_SIZE_int, true)
1446ALL_OP_BIN_WITH_INT(
unsigned int, _AP_SIZE_int, false)
1447ALL_OP_BIN_WITH_INT(
long, _AP_SIZE_long, true)
1448ALL_OP_BIN_WITH_INT(
unsigned long, _AP_SIZE_long, false)
1449ALL_OP_BIN_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1450ALL_OP_BIN_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1452#undef OP_BIN_WITH_INT
1453#undef ALL_OP_BIN_WITH_INT
1456#define ALL_OP_SHIFT_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1457 template <int _AP_W, bool _AP_S> \
1459 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W, _AP_S>::arg1 \
1460 operator<<(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1461 ap_int_base<_AP_W, _AP_S> r; \
1463 r.V = op2 >= 0 ? (op.V << op2) : (op.V >> (-op2)); \
1465 r.V = op.V << op2; \
1468 template <int _AP_W, bool _AP_S> \
1470 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W, _AP_S>::arg1 \
1471 operator>>(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1472 ap_int_base<_AP_W, _AP_S> r; \
1474 r.V = op2 >= 0 ? (op.V >> op2) : (op.V << (-op2)); \
1476 r.V = op.V >> op2; \
1480ALL_OP_SHIFT_WITH_INT(
char, 8, CHAR_IS_SIGNED)
1481ALL_OP_SHIFT_WITH_INT(
signed char, 8,
true)
1482ALL_OP_SHIFT_WITH_INT(
short, _AP_SIZE_short, true)
1483ALL_OP_SHIFT_WITH_INT(
int, _AP_SIZE_int, true)
1484ALL_OP_SHIFT_WITH_INT(
long, _AP_SIZE_long, true)
1485ALL_OP_SHIFT_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1487#undef ALL_OP_SHIFT_WITH_INT
1489#define ALL_OP_SHIFT_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1490 template <int _AP_W, bool _AP_S> \
1492 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W, _AP_S>::arg1 \
1493 operator<<(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1494 ap_int_base<_AP_W, _AP_S> r; \
1495 r.V = op.V << op2; \
1498 template <int _AP_W, bool _AP_S> \
1500 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W, _AP_S>::arg1 \
1501 operator>>(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1502 ap_int_base<_AP_W, _AP_S> r; \
1503 r.V = op.V >> op2; \
1506ALL_OP_SHIFT_WITH_INT(
bool, 1,
false)
1507ALL_OP_SHIFT_WITH_INT(
unsigned char, 8, false)
1508ALL_OP_SHIFT_WITH_INT(
unsigned short, _AP_SIZE_short, false)
1509ALL_OP_SHIFT_WITH_INT(
unsigned int, _AP_SIZE_int, false)
1510ALL_OP_SHIFT_WITH_INT(
unsigned long, _AP_SIZE_long, false)
1511ALL_OP_SHIFT_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1513#undef ALL_OP_SHIFT_WITH_INT
1516#define OP_ASSIGN_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \
1517 template <int _AP_W, bool _AP_S> \
1518 INLINE ap_int_base<_AP_W, _AP_S>& operator ASSIGN_OP( \
1519 ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1520 return op ASSIGN_OP ap_int_base<_AP_W2, _AP_S2>(op2); \
1525#define ALL_OP_ASSIGN_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1526 OP_ASSIGN_WITH_INT(+=, C_TYPE, _AP_W2, _AP_S2) \
1527 OP_ASSIGN_WITH_INT(-=, C_TYPE, _AP_W2, _AP_S2) \
1528 OP_ASSIGN_WITH_INT(*=, C_TYPE, _AP_W2, _AP_S2) \
1529 OP_ASSIGN_WITH_INT(/=, C_TYPE, _AP_W2, _AP_S2) \
1530 OP_ASSIGN_WITH_INT(%=, C_TYPE, _AP_W2, _AP_S2) \
1531 OP_ASSIGN_WITH_INT(&=, C_TYPE, _AP_W2, _AP_S2) \
1532 OP_ASSIGN_WITH_INT(|=, C_TYPE, _AP_W2, _AP_S2) \
1533 OP_ASSIGN_WITH_INT(^=, C_TYPE, _AP_W2, _AP_S2) \
1534 OP_ASSIGN_WITH_INT(>>=, C_TYPE, _AP_W2, _AP_S2) \
1535 OP_ASSIGN_WITH_INT(<<=, C_TYPE, _AP_W2, _AP_S2)
1537ALL_OP_ASSIGN_WITH_INT(
bool, 1,
false)
1538ALL_OP_ASSIGN_WITH_INT(
char, 8, CHAR_IS_SIGNED)
1539ALL_OP_ASSIGN_WITH_INT(
signed char, 8, true)
1540ALL_OP_ASSIGN_WITH_INT(
unsigned char, 8, false)
1541ALL_OP_ASSIGN_WITH_INT(
short, _AP_SIZE_short, true)
1542ALL_OP_ASSIGN_WITH_INT(
unsigned short, _AP_SIZE_short, false)
1543ALL_OP_ASSIGN_WITH_INT(
int, _AP_SIZE_int, true)
1544ALL_OP_ASSIGN_WITH_INT(
unsigned int, _AP_SIZE_int, false)
1545ALL_OP_ASSIGN_WITH_INT(
long, _AP_SIZE_long, true)
1546ALL_OP_ASSIGN_WITH_INT(
unsigned long, _AP_SIZE_long, false)
1547ALL_OP_ASSIGN_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1548ALL_OP_ASSIGN_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1550#undef OP_ASSIGN_WITH_INT
1551#undef ALL_OP_ASSIGN_WITH_INT
1554#define OP_REL_WITH_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \
1555 template <int _AP_W, bool _AP_S> \
1556 INLINE bool operator REL_OP(C_TYPE i_op, \
1557 const ap_int_base<_AP_W, _AP_S>& op) { \
1558 return ap_int_base<_AP_W2, _AP_S2>(i_op) REL_OP op; \
1560 template <int _AP_W, bool _AP_S> \
1561 INLINE bool operator REL_OP(const ap_int_base<_AP_W, _AP_S>& op, \
1563 return op REL_OP ap_int_base<_AP_W2, _AP_S2>(op2); \
1566#define ALL_OP_REL_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1567 OP_REL_WITH_INT(>, C_TYPE, _AP_W2, _AP_S2) \
1568 OP_REL_WITH_INT(<, C_TYPE, _AP_W2, _AP_S2) \
1569 OP_REL_WITH_INT(>=, C_TYPE, _AP_W2, _AP_S2) \
1570 OP_REL_WITH_INT(<=, C_TYPE, _AP_W2, _AP_S2) \
1571 OP_REL_WITH_INT(==, C_TYPE, _AP_W2, _AP_S2) \
1572 OP_REL_WITH_INT(!=, C_TYPE, _AP_W2, _AP_S2)
1574ALL_OP_REL_WITH_INT(
bool, 1,
false)
1575ALL_OP_REL_WITH_INT(
char, 8, CHAR_IS_SIGNED)
1576ALL_OP_REL_WITH_INT(
signed char, 8, true)
1577ALL_OP_REL_WITH_INT(
unsigned char, 8, false)
1578ALL_OP_REL_WITH_INT(
short, _AP_SIZE_short, true)
1579ALL_OP_REL_WITH_INT(
unsigned short, _AP_SIZE_short, false)
1580ALL_OP_REL_WITH_INT(
int, _AP_SIZE_int, true)
1581ALL_OP_REL_WITH_INT(
unsigned int, _AP_SIZE_int, false)
1582ALL_OP_REL_WITH_INT(
long, _AP_SIZE_long, true)
1583ALL_OP_REL_WITH_INT(
unsigned long, _AP_SIZE_long, false)
1584ALL_OP_REL_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1585ALL_OP_REL_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1587#undef OP_REL_WITH_INT
1588#undef ALL_OP_BIN_WITH_INT
1590#define OP_REL_WITH_DOUBLE_OR_FLOAT(Sym) \
1591 template <int _AP_W, bool _AP_S> \
1592 INLINE bool operator Sym(const ap_int_base<_AP_W, _AP_S>& op1, double op2) { \
1593 return op1.to_double() Sym op2; \
1595 template <int _AP_W, bool _AP_S> \
1596 INLINE bool operator Sym(double op1, const ap_int_base<_AP_W, _AP_S>& op2) { \
1597 return op1 Sym op2.to_double(); \
1599 template <int _AP_W, bool _AP_S> \
1600 INLINE bool operator Sym(const ap_int_base<_AP_W, _AP_S>& op1, float op2) { \
1601 return op1.to_double() Sym op2; \
1603 template <int _AP_W, bool _AP_S> \
1604 INLINE bool operator Sym(float op1, const ap_int_base<_AP_W, _AP_S>& op2) { \
1605 return op1 Sym op2.to_double(); \
1607OP_REL_WITH_DOUBLE_OR_FLOAT(>)
1608OP_REL_WITH_DOUBLE_OR_FLOAT(<)
1609OP_REL_WITH_DOUBLE_OR_FLOAT(>=)
1610OP_REL_WITH_DOUBLE_OR_FLOAT(<=)
1611OP_REL_WITH_DOUBLE_OR_FLOAT(==)
1612OP_REL_WITH_DOUBLE_OR_FLOAT(!=)
1614#undef OP_REL_WITH_DOUBLE_OR_FLOAT
1620#define OP_BIN_WITH_RANGE(BIN_OP, RTYPE) \
1621 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1622 INLINE typename ap_int_base<_AP_W1, _AP_S1>::template RType<_AP_W2, \
1624 operator BIN_OP(const ap_range_ref<_AP_W1, _AP_S1>& op1, \
1625 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1626 return ap_int_base<_AP_W1, false>(op1) BIN_OP op2; \
1628 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1629 INLINE typename ap_int_base<_AP_W1, _AP_S1>::template RType<_AP_W2, \
1631 operator BIN_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1632 const ap_range_ref<_AP_W2, _AP_S2>& op2) { \
1633 return op1 BIN_OP ap_int_base<_AP_W2, false>(op2); \
1636OP_BIN_WITH_RANGE(+, plus)
1637OP_BIN_WITH_RANGE(-, minus)
1638OP_BIN_WITH_RANGE(*, mult)
1639OP_BIN_WITH_RANGE(/, div)
1640OP_BIN_WITH_RANGE(%, mod)
1641OP_BIN_WITH_RANGE(&, logic)
1642OP_BIN_WITH_RANGE(|, logic)
1643OP_BIN_WITH_RANGE(^, logic)
1644OP_BIN_WITH_RANGE(>>, arg1)
1645OP_BIN_WITH_RANGE(<<, arg1)
1647#undef OP_BIN_WITH_RANGE
1650#define OP_ASSIGN_WITH_RANGE(ASSIGN_OP) \
1651 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1652 INLINE ap_int_base<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1653 ap_int_base<_AP_W1, _AP_S1>& op1, ap_range_ref<_AP_W2, _AP_S2>& op2) { \
1654 return op1 ASSIGN_OP ap_int_base<_AP_W2, false>(op2); \
1656 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1657 INLINE ap_range_ref<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1658 ap_range_ref<_AP_W1, _AP_S1>& op1, ap_int_base<_AP_W2, _AP_S2>& op2) { \
1659 ap_int_base<_AP_W1, false> tmp(op1); \
1660 tmp ASSIGN_OP op2; \
1665OP_ASSIGN_WITH_RANGE(+=)
1666OP_ASSIGN_WITH_RANGE(-=)
1667OP_ASSIGN_WITH_RANGE(*=)
1668OP_ASSIGN_WITH_RANGE(/=)
1669OP_ASSIGN_WITH_RANGE(%=)
1670OP_ASSIGN_WITH_RANGE(&=)
1671OP_ASSIGN_WITH_RANGE(|=)
1672OP_ASSIGN_WITH_RANGE(^=)
1673OP_ASSIGN_WITH_RANGE(>>=)
1674OP_ASSIGN_WITH_RANGE(<<=)
1676#undef OP_ASSIGN_WITH_RANGE
1679#define OP_REL_WITH_RANGE(REL_OP) \
1680 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1681 INLINE bool operator REL_OP(const ap_range_ref<_AP_W1, _AP_S1>& op1, \
1682 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1683 return ap_int_base<_AP_W1, false>(op1).operator REL_OP(op2); \
1685 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1686 INLINE bool operator REL_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1687 const ap_range_ref<_AP_W2, _AP_S2>& op2) { \
1688 return op1.operator REL_OP(op2.operator ap_int_base<_AP_W2, false>()); \
1691OP_REL_WITH_RANGE(==)
1692OP_REL_WITH_RANGE(!=)
1694OP_REL_WITH_RANGE(>=)
1696OP_REL_WITH_RANGE(<=)
1698#undef OP_REL_WITH_RANGE
1704#define OP_BIN_WITH_BIT(BIN_OP, RTYPE) \
1705 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1706 INLINE typename ap_int_base<_AP_W1, _AP_S1>::template RType<1, false>::RTYPE \
1707 operator BIN_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1708 const ap_bit_ref<_AP_W2, _AP_S2>& op2) { \
1709 return op1 BIN_OP ap_int_base<1, false>(op2); \
1711 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1712 INLINE typename ap_int_base<1, false>::template RType<_AP_W2, _AP_S2>::RTYPE \
1713 operator BIN_OP(const ap_bit_ref<_AP_W1, _AP_S1>& op1, \
1714 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1715 return ap_int_base<1, false>(op1) BIN_OP op2; \
1718OP_BIN_WITH_BIT(+, plus)
1719OP_BIN_WITH_BIT(-, minus)
1720OP_BIN_WITH_BIT(*, mult)
1721OP_BIN_WITH_BIT(/, div)
1722OP_BIN_WITH_BIT(%, mod)
1723OP_BIN_WITH_BIT(&, logic)
1724OP_BIN_WITH_BIT(|, logic)
1725OP_BIN_WITH_BIT(^, logic)
1726OP_BIN_WITH_BIT(>>, arg1)
1727OP_BIN_WITH_BIT(<<, arg1)
1729#undef OP_BIN_WITH_BIT
1732#define OP_ASSIGN_WITH_BIT(ASSIGN_OP) \
1733 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1734 INLINE ap_int_base<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1735 ap_int_base<_AP_W1, _AP_S1>& op1, ap_bit_ref<_AP_W2, _AP_S2>& op2) { \
1736 return op1 ASSIGN_OP ap_int_base<1, false>(op2); \
1738 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1739 INLINE ap_bit_ref<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1740 ap_bit_ref<_AP_W1, _AP_S1>& op1, ap_int_base<_AP_W2, _AP_S2>& op2) { \
1741 ap_int_base<1, false> tmp(op1); \
1742 tmp ASSIGN_OP op2; \
1747OP_ASSIGN_WITH_BIT(+=)
1748OP_ASSIGN_WITH_BIT(-=)
1749OP_ASSIGN_WITH_BIT(*=)
1750OP_ASSIGN_WITH_BIT(/=)
1751OP_ASSIGN_WITH_BIT(%=)
1752OP_ASSIGN_WITH_BIT(&=)
1753OP_ASSIGN_WITH_BIT(|=)
1754OP_ASSIGN_WITH_BIT(^=)
1755OP_ASSIGN_WITH_BIT(>>=)
1756OP_ASSIGN_WITH_BIT(<<=)
1758#undef OP_ASSIGN_WITH_BIT
1761#define OP_REL_WITH_BIT(REL_OP) \
1762 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1763 INLINE bool operator REL_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1764 const ap_bit_ref<_AP_W2, _AP_S2>& op2) { \
1765 return op1 REL_OP ap_int_base<1, false>(op2); \
1767 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1768 INLINE bool operator REL_OP(const ap_bit_ref<_AP_W1, _AP_S1>& op1, \
1769 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1770 return ap_int_base<1, false>(op1) REL_OP op2; \
1780#undef OP_REL_WITH_BIT
1789#define OP_BIN_WITH_CONCAT(BIN_OP, RTYPE) \
1790 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1791 int _AP_W3, bool _AP_S3> \
1792 INLINE typename ap_int_base<_AP_W3, _AP_S3>::template RType<_AP_W1 + _AP_W2, \
1794 operator BIN_OP(const ap_int_base<_AP_W3, _AP_S3>& op1, \
1795 const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op2) { \
1797 return op1 BIN_OP op2.get(); \
1799 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1800 int _AP_W3, bool _AP_S3> \
1801 INLINE typename ap_int_base<_AP_W1 + _AP_W2, \
1802 false>::template RType<_AP_W3, _AP_S3>::RTYPE \
1803 operator BIN_OP(const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op1, \
1804 const ap_int_base<_AP_W3, _AP_S3>& op2) { \
1806 return op1.get() BIN_OP op2; \
1809OP_BIN_WITH_CONCAT(+, plus)
1810OP_BIN_WITH_CONCAT(-, minus)
1811OP_BIN_WITH_CONCAT(*, mult)
1812OP_BIN_WITH_CONCAT(/, div)
1813OP_BIN_WITH_CONCAT(%, mod)
1814OP_BIN_WITH_CONCAT(&, logic)
1815OP_BIN_WITH_CONCAT(|, logic)
1816OP_BIN_WITH_CONCAT(^, logic)
1817OP_BIN_WITH_CONCAT(>>, arg1)
1818OP_BIN_WITH_CONCAT(<<, arg1)
1820#undef OP_BIN_WITH_CONCAT
1823#define OP_ASSIGN_WITH_CONCAT(ASSIGN_OP) \
1824 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1825 int _AP_W3, bool _AP_S3> \
1826 INLINE typename ap_int_base<_AP_W3, _AP_S3>::template RType<_AP_W1 + _AP_W2, \
1828 operator ASSIGN_OP( \
1829 const ap_int_base<_AP_W3, _AP_S3>& op1, \
1830 const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op2) { \
1832 return op1 ASSIGN_OP op2.get(); \
1834 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1835 int _AP_W3, bool _AP_S3> \
1836 INLINE typename ap_int_base<_AP_W1 + _AP_W2, \
1837 false>::template RType<_AP_W3, _AP_S3>::RTYPE \
1838 operator ASSIGN_OP(const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op1, \
1839 const ap_int_base<_AP_W3, _AP_S3>& op2) { \
1841 ap_int_base<_AP_W1 + _AP_W2, false> tmp = op1.get(); \
1842 tmp ASSIGN_OP op2; \
1847OP_ASSIGN_WITH_CONCAT(+=)
1848OP_ASSIGN_WITH_CONCAT(-=)
1849OP_ASSIGN_WITH_CONCAT(*=)
1850OP_ASSIGN_WITH_CONCAT(/=)
1851OP_ASSIGN_WITH_CONCAT(%=)
1852OP_ASSIGN_WITH_CONCAT(&=)
1853OP_ASSIGN_WITH_CONCAT(|=)
1854OP_ASSIGN_WITH_CONCAT(^=)
1855OP_ASSIGN_WITH_CONCAT(>>=)
1856OP_ASSIGN_WITH_CONCAT(<<=)
1858#undef OP_ASSIGN_WITH_CONCAT
1862#define OP_REL_WITH_CONCAT(REL_OP) \
1863 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1864 int _AP_W3, bool _AP_S3> \
1865 INLINE bool operator REL_OP( \
1866 const ap_int_base<_AP_W3, _AP_S3>& op1, \
1867 const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op2) { \
1869 return op1 REL_OP op2.get(); \
1871 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1872 int _AP_W3, bool _AP_S3> \
1873 INLINE bool operator REL_OP( \
1874 const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op1, \
1875 const ap_int_base<_AP_W3, _AP_S3>& op2) { \
1877 return op1.get() REL_OP op2; \
1880OP_REL_WITH_CONCAT(==)
1881OP_REL_WITH_CONCAT(!=)
1882OP_REL_WITH_CONCAT(>)
1883OP_REL_WITH_CONCAT(>=)
1884OP_REL_WITH_CONCAT(<)
1885OP_REL_WITH_CONCAT(<=)
1887#undef OP_REL_WITH_CONCAT
conditions objects which are tables indexed by raw detector id values
Sign Arbitrary Precision Type.
Unsigned Arbitrary Precision Type.