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>
1220 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
1221 INLINE
ap_int_base<AP_MAX(_AP_W2 + _AP_W3, _AP_W), _AP_S> operator&(
1223 return *
this & a2.get();
1226 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
1227 INLINE
ap_int_base<AP_MAX(_AP_W2 + _AP_W3, _AP_W), _AP_S> operator|(
1229 return *
this | a2.get();
1232 template <
int _AP_W2,
typename _AP_T2,
int _AP_W3,
typename _AP_T3>
1233 INLINE
ap_int_base<AP_MAX(_AP_W2 + _AP_W3, _AP_W), _AP_S> operator^(
1235 return *
this ^ a2.get();
1238 template <
int _AP_W3>
1247 INLINE
bool and_reduce()
const {
return _AP_ROOT_op_reduce(and, Base::V); }
1248 INLINE
bool nand_reduce()
const {
return _AP_ROOT_op_reduce(nand, Base::V); }
1249 INLINE
bool or_reduce()
const {
return _AP_ROOT_op_reduce(or, Base::V); }
1250 INLINE
bool nor_reduce()
const {
return !(_AP_ROOT_op_reduce(or, Base::V)); }
1251 INLINE
bool xor_reduce()
const {
return _AP_ROOT_op_reduce(xor, Base::V); }
1252 INLINE
bool xnor_reduce()
const {
1253 return !(_AP_ROOT_op_reduce(xor, Base::V));
1259#ifndef __SYNTHESIS__
1260 std::string to_string(
signed char rd = 2,
bool sign = _AP_S)
const {
1263 if (rd == 2) sign =
false;
1264 return (Base::V).to_string(rd, sign);
1267 INLINE
char* to_string(
signed char rd = 2,
bool sign = _AP_S)
const {
1275#ifndef __SYNTHESIS__
1276template <
int _AP_W,
bool _AP_S>
1277INLINE std::ostream& operator<<(std::ostream& os,
1279 std::ios_base::fmtflags ff = std::cout.flags();
1280 if (ff & std::cout.
hex) {
1281 os << x.to_string(16);
1282 }
else if (ff & std::cout.oct) {
1283 os << x.to_string(8);
1285 os << x.to_string(10);
1291#ifndef __SYNTHESIS__
1292template <
int _AP_W,
bool _AP_S>
1293INLINE std::istream& operator>>(std::istream& in,
1297 const std::ios_base::fmtflags basefield =
1298 in.flags() & std::ios_base::basefield;
1299 unsigned radix = (basefield == std::ios_base::dec)
1301 : ((basefield == std::ios_base::oct)
1303 : ((basefield == std::ios_base::
hex) ? 16 : 0));
1313#define OP_BIN_AP(Sym, Rty) \
1314 template <int _AP_W, bool _AP_S, int _AP_W2, bool _AP_S2> \
1316 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, _AP_S2>::Rty \
1317 operator Sym(const ap_int_base<_AP_W, _AP_S>& op, \
1318 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1319 typename ap_int_base<_AP_W, _AP_S>::template RType< \
1320 _AP_W2, _AP_S2>::Rty##_base lhs(op); \
1321 typename ap_int_base<_AP_W, _AP_S>::template RType< \
1322 _AP_W2, _AP_S2>::Rty##_base rhs(op2); \
1323 typename ap_int_base<_AP_W, _AP_S>::template RType< \
1324 _AP_W2, _AP_S2>::Rty##_base ret; \
1325 ret.V = lhs.V Sym rhs.V; \
1336#define OP_BIN_AP2(Sym, Rty) \
1337 template <int _AP_W, bool _AP_S, int _AP_W2, bool _AP_S2> \
1339 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, _AP_S2>::Rty \
1340 operator Sym(const ap_int_base<_AP_W, _AP_S>& op, \
1341 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1342 typename ap_int_base<_AP_W, _AP_S>::template RType< \
1343 _AP_W2, _AP_S2>::Rty##_base ret; \
1344 ret.V = op.V Sym op2.V; \
1362#define OP_BIN_WITH_PTR(BIN_OP) \
1363 template <typename PTR_TYPE, int _AP_W, bool _AP_S> \
1364 INLINE PTR_TYPE* operator BIN_OP(PTR_TYPE * i_op, \
1365 const ap_int_base<_AP_W, _AP_S>& op) { \
1366 ap_slong op2 = op.to_int64(); \
1367 return i_op BIN_OP op2; \
1369 template <typename PTR_TYPE, int _AP_W, bool _AP_S> \
1370 INLINE PTR_TYPE* operator BIN_OP(const ap_int_base<_AP_W, _AP_S>& op, \
1371 PTR_TYPE * i_op) { \
1372 ap_slong op2 = op.to_int64(); \
1373 return op2 BIN_OP i_op; \
1384#define OP_BIN_WITH_FLOAT(BIN_OP, C_TYPE) \
1385 template <int _AP_W, bool _AP_S> \
1386 INLINE C_TYPE operator BIN_OP(C_TYPE i_op, \
1387 const ap_int_base<_AP_W, _AP_S>& op) { \
1388 typename ap_int_base<_AP_W, _AP_S>::RetType op2 = op; \
1389 return i_op BIN_OP op2; \
1391 template <int _AP_W, bool _AP_S> \
1392 INLINE C_TYPE operator BIN_OP(const ap_int_base<_AP_W, _AP_S>& op, \
1394 typename ap_int_base<_AP_W, _AP_S>::RetType op2 = op; \
1395 return op2 BIN_OP i_op; \
1398#define ALL_OP_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) \
1402 OP_BIN_WITH_FLOAT(-, C_TYPE)
1404#if _AP_ENABLE_HALF_ == 1
1405ALL_OP_WITH_FLOAT(half)
1407ALL_OP_WITH_FLOAT(
float)
1408ALL_OP_WITH_FLOAT(
double)
1416#define OP_BIN_WITH_INT(BIN_OP, C_TYPE, _AP_W2, _AP_S2, RTYPE) \
1417 template <int _AP_W, bool _AP_S> \
1418 INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, \
1420 operator BIN_OP(C_TYPE i_op, const ap_int_base<_AP_W, _AP_S>& op) { \
1421 return ap_int_base<_AP_W2, _AP_S2>(i_op) BIN_OP(op); \
1423 template <int _AP_W, bool _AP_S> \
1424 INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, \
1426 operator BIN_OP(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE i_op) { \
1427 return op BIN_OP ap_int_base<_AP_W2, _AP_S2>(i_op); \
1430#define ALL_OP_BIN_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1431 OP_BIN_WITH_INT(*, C_TYPE, _AP_W2, _AP_S2, mult) \
1432 OP_BIN_WITH_INT(+, C_TYPE, _AP_W2, _AP_S2, plus) \
1433 OP_BIN_WITH_INT(-, C_TYPE, _AP_W2, _AP_S2, minus) \
1434 OP_BIN_WITH_INT(/, C_TYPE, _AP_W2, _AP_S2, div) \
1435 OP_BIN_WITH_INT(%, C_TYPE, _AP_W2, _AP_S2, mod) \
1436 OP_BIN_WITH_INT(&, C_TYPE, _AP_W2, _AP_S2, logic) \
1437 OP_BIN_WITH_INT(|, C_TYPE, _AP_W2, _AP_S2, logic) \
1438 OP_BIN_WITH_INT(^, C_TYPE, _AP_W2, _AP_S2, logic)
1440ALL_OP_BIN_WITH_INT(
bool, 1,
false)
1441ALL_OP_BIN_WITH_INT(
char, 8, CHAR_IS_SIGNED)
1442ALL_OP_BIN_WITH_INT(
signed char, 8, true)
1443ALL_OP_BIN_WITH_INT(
unsigned char, 8, false)
1444ALL_OP_BIN_WITH_INT(
short, _AP_SIZE_short, true)
1445ALL_OP_BIN_WITH_INT(
unsigned short, _AP_SIZE_short, false)
1446ALL_OP_BIN_WITH_INT(
int, _AP_SIZE_int, true)
1447ALL_OP_BIN_WITH_INT(
unsigned int, _AP_SIZE_int, false)
1448ALL_OP_BIN_WITH_INT(
long, _AP_SIZE_long, true)
1449ALL_OP_BIN_WITH_INT(
unsigned long, _AP_SIZE_long, false)
1450ALL_OP_BIN_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1451ALL_OP_BIN_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1453#undef OP_BIN_WITH_INT
1454#undef ALL_OP_BIN_WITH_INT
1457#define ALL_OP_SHIFT_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1458 template <int _AP_W, bool _AP_S> \
1460 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W, _AP_S>::arg1 \
1461 operator<<(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1462 ap_int_base<_AP_W, _AP_S> r; \
1464 r.V = op2 >= 0 ? (op.V << op2) : (op.V >> (-op2)); \
1466 r.V = op.V << op2; \
1469 template <int _AP_W, bool _AP_S> \
1471 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W, _AP_S>::arg1 \
1472 operator>>(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1473 ap_int_base<_AP_W, _AP_S> r; \
1475 r.V = op2 >= 0 ? (op.V >> op2) : (op.V << (-op2)); \
1477 r.V = op.V >> op2; \
1481ALL_OP_SHIFT_WITH_INT(
char, 8, CHAR_IS_SIGNED)
1482ALL_OP_SHIFT_WITH_INT(
signed char, 8,
true)
1483ALL_OP_SHIFT_WITH_INT(
short, _AP_SIZE_short, true)
1484ALL_OP_SHIFT_WITH_INT(
int, _AP_SIZE_int, true)
1485ALL_OP_SHIFT_WITH_INT(
long, _AP_SIZE_long, true)
1486ALL_OP_SHIFT_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1488#undef ALL_OP_SHIFT_WITH_INT
1490#define ALL_OP_SHIFT_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1491 template <int _AP_W, bool _AP_S> \
1493 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W, _AP_S>::arg1 \
1494 operator<<(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1495 ap_int_base<_AP_W, _AP_S> r; \
1496 r.V = op.V << op2; \
1499 template <int _AP_W, bool _AP_S> \
1501 typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W, _AP_S>::arg1 \
1502 operator>>(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1503 ap_int_base<_AP_W, _AP_S> r; \
1504 r.V = op.V >> op2; \
1507ALL_OP_SHIFT_WITH_INT(
bool, 1,
false)
1508ALL_OP_SHIFT_WITH_INT(
unsigned char, 8, false)
1509ALL_OP_SHIFT_WITH_INT(
unsigned short, _AP_SIZE_short, false)
1510ALL_OP_SHIFT_WITH_INT(
unsigned int, _AP_SIZE_int, false)
1511ALL_OP_SHIFT_WITH_INT(
unsigned long, _AP_SIZE_long, false)
1512ALL_OP_SHIFT_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1514#undef ALL_OP_SHIFT_WITH_INT
1517#define OP_ASSIGN_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \
1518 template <int _AP_W, bool _AP_S> \
1519 INLINE ap_int_base<_AP_W, _AP_S>& operator ASSIGN_OP( \
1520 ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1521 return op ASSIGN_OP ap_int_base<_AP_W2, _AP_S2>(op2); \
1526#define ALL_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) \
1536 OP_ASSIGN_WITH_INT(<<=, C_TYPE, _AP_W2, _AP_S2)
1538ALL_OP_ASSIGN_WITH_INT(
bool, 1,
false)
1539ALL_OP_ASSIGN_WITH_INT(
char, 8, CHAR_IS_SIGNED)
1540ALL_OP_ASSIGN_WITH_INT(
signed char, 8, true)
1541ALL_OP_ASSIGN_WITH_INT(
unsigned char, 8, false)
1542ALL_OP_ASSIGN_WITH_INT(
short, _AP_SIZE_short, true)
1543ALL_OP_ASSIGN_WITH_INT(
unsigned short, _AP_SIZE_short, false)
1544ALL_OP_ASSIGN_WITH_INT(
int, _AP_SIZE_int, true)
1545ALL_OP_ASSIGN_WITH_INT(
unsigned int, _AP_SIZE_int, false)
1546ALL_OP_ASSIGN_WITH_INT(
long, _AP_SIZE_long, true)
1547ALL_OP_ASSIGN_WITH_INT(
unsigned long, _AP_SIZE_long, false)
1548ALL_OP_ASSIGN_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1549ALL_OP_ASSIGN_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1551#undef OP_ASSIGN_WITH_INT
1552#undef ALL_OP_ASSIGN_WITH_INT
1555#define OP_REL_WITH_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \
1556 template <int _AP_W, bool _AP_S> \
1557 INLINE bool operator REL_OP(C_TYPE i_op, \
1558 const ap_int_base<_AP_W, _AP_S>& op) { \
1559 return ap_int_base<_AP_W2, _AP_S2>(i_op) REL_OP op; \
1561 template <int _AP_W, bool _AP_S> \
1562 INLINE bool operator REL_OP(const ap_int_base<_AP_W, _AP_S>& op, \
1564 return op REL_OP ap_int_base<_AP_W2, _AP_S2>(op2); \
1567#define ALL_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) \
1573 OP_REL_WITH_INT(!=, C_TYPE, _AP_W2, _AP_S2)
1575ALL_OP_REL_WITH_INT(
bool, 1,
false)
1576ALL_OP_REL_WITH_INT(
char, 8, CHAR_IS_SIGNED)
1577ALL_OP_REL_WITH_INT(
signed char, 8, true)
1578ALL_OP_REL_WITH_INT(
unsigned char, 8, false)
1579ALL_OP_REL_WITH_INT(
short, _AP_SIZE_short, true)
1580ALL_OP_REL_WITH_INT(
unsigned short, _AP_SIZE_short, false)
1581ALL_OP_REL_WITH_INT(
int, _AP_SIZE_int, true)
1582ALL_OP_REL_WITH_INT(
unsigned int, _AP_SIZE_int, false)
1583ALL_OP_REL_WITH_INT(
long, _AP_SIZE_long, true)
1584ALL_OP_REL_WITH_INT(
unsigned long, _AP_SIZE_long, false)
1585ALL_OP_REL_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1586ALL_OP_REL_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1588#undef OP_REL_WITH_INT
1589#undef ALL_OP_BIN_WITH_INT
1591#define OP_REL_WITH_DOUBLE_OR_FLOAT(Sym) \
1592 template <int _AP_W, bool _AP_S> \
1593 INLINE bool operator Sym(const ap_int_base<_AP_W, _AP_S>& op1, double op2) { \
1594 return op1.to_double() Sym op2; \
1596 template <int _AP_W, bool _AP_S> \
1597 INLINE bool operator Sym(double op1, const ap_int_base<_AP_W, _AP_S>& op2) { \
1598 return op1 Sym op2.to_double(); \
1600 template <int _AP_W, bool _AP_S> \
1601 INLINE bool operator Sym(const ap_int_base<_AP_W, _AP_S>& op1, float op2) { \
1602 return op1.to_double() Sym op2; \
1604 template <int _AP_W, bool _AP_S> \
1605 INLINE bool operator Sym(float op1, const ap_int_base<_AP_W, _AP_S>& op2) { \
1606 return op1 Sym op2.to_double(); \
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(==)
1613OP_REL_WITH_DOUBLE_OR_FLOAT(!=)
1615#undef OP_REL_WITH_DOUBLE_OR_FLOAT
1621#define OP_BIN_WITH_RANGE(BIN_OP, RTYPE) \
1622 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1623 INLINE typename ap_int_base<_AP_W1, _AP_S1>::template RType<_AP_W2, \
1625 operator BIN_OP(const ap_range_ref<_AP_W1, _AP_S1>& op1, \
1626 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1627 return ap_int_base<_AP_W1, false>(op1) BIN_OP op2; \
1629 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1630 INLINE typename ap_int_base<_AP_W1, _AP_S1>::template RType<_AP_W2, \
1632 operator BIN_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1633 const ap_range_ref<_AP_W2, _AP_S2>& op2) { \
1634 return op1 BIN_OP ap_int_base<_AP_W2, false>(op2); \
1637OP_BIN_WITH_RANGE(+, plus)
1638OP_BIN_WITH_RANGE(-, minus)
1639OP_BIN_WITH_RANGE(*, mult)
1640OP_BIN_WITH_RANGE(/, div)
1641OP_BIN_WITH_RANGE(%, mod)
1642OP_BIN_WITH_RANGE(&, logic)
1643OP_BIN_WITH_RANGE(|, logic)
1644OP_BIN_WITH_RANGE(^, logic)
1645OP_BIN_WITH_RANGE(>>, arg1)
1646OP_BIN_WITH_RANGE(<<, arg1)
1648#undef OP_BIN_WITH_RANGE
1651#define OP_ASSIGN_WITH_RANGE(ASSIGN_OP) \
1652 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1653 INLINE ap_int_base<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1654 ap_int_base<_AP_W1, _AP_S1>& op1, ap_range_ref<_AP_W2, _AP_S2>& op2) { \
1655 return op1 ASSIGN_OP ap_int_base<_AP_W2, false>(op2); \
1657 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1658 INLINE ap_range_ref<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1659 ap_range_ref<_AP_W1, _AP_S1>& op1, ap_int_base<_AP_W2, _AP_S2>& op2) { \
1660 ap_int_base<_AP_W1, false> tmp(op1); \
1661 tmp ASSIGN_OP op2; \
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(>>=)
1675OP_ASSIGN_WITH_RANGE(<<=)
1677#undef OP_ASSIGN_WITH_RANGE
1680#define OP_REL_WITH_RANGE(REL_OP) \
1681 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1682 INLINE bool operator REL_OP(const ap_range_ref<_AP_W1, _AP_S1>& op1, \
1683 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1684 return ap_int_base<_AP_W1, false>(op1).operator REL_OP(op2); \
1686 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1687 INLINE bool operator REL_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1688 const ap_range_ref<_AP_W2, _AP_S2>& op2) { \
1689 return op1.operator REL_OP(op2.operator ap_int_base<_AP_W2, false>()); \
1692OP_REL_WITH_RANGE(==)
1693OP_REL_WITH_RANGE(!=)
1695OP_REL_WITH_RANGE(>=)
1697OP_REL_WITH_RANGE(<=)
1699#undef OP_REL_WITH_RANGE
1705#define OP_BIN_WITH_BIT(BIN_OP, RTYPE) \
1706 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1707 INLINE typename ap_int_base<_AP_W1, _AP_S1>::template RType<1, false>::RTYPE \
1708 operator BIN_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1709 const ap_bit_ref<_AP_W2, _AP_S2>& op2) { \
1710 return op1 BIN_OP ap_int_base<1, false>(op2); \
1712 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1713 INLINE typename ap_int_base<1, false>::template RType<_AP_W2, _AP_S2>::RTYPE \
1714 operator BIN_OP(const ap_bit_ref<_AP_W1, _AP_S1>& op1, \
1715 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1716 return ap_int_base<1, false>(op1) BIN_OP op2; \
1719OP_BIN_WITH_BIT(+, plus)
1720OP_BIN_WITH_BIT(-, minus)
1721OP_BIN_WITH_BIT(*, mult)
1722OP_BIN_WITH_BIT(/, div)
1723OP_BIN_WITH_BIT(%, mod)
1724OP_BIN_WITH_BIT(&, logic)
1725OP_BIN_WITH_BIT(|, logic)
1726OP_BIN_WITH_BIT(^, logic)
1727OP_BIN_WITH_BIT(>>, arg1)
1728OP_BIN_WITH_BIT(<<, arg1)
1730#undef OP_BIN_WITH_BIT
1733#define OP_ASSIGN_WITH_BIT(ASSIGN_OP) \
1734 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1735 INLINE ap_int_base<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1736 ap_int_base<_AP_W1, _AP_S1>& op1, ap_bit_ref<_AP_W2, _AP_S2>& op2) { \
1737 return op1 ASSIGN_OP ap_int_base<1, false>(op2); \
1739 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1740 INLINE ap_bit_ref<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1741 ap_bit_ref<_AP_W1, _AP_S1>& op1, ap_int_base<_AP_W2, _AP_S2>& op2) { \
1742 ap_int_base<1, false> tmp(op1); \
1743 tmp ASSIGN_OP op2; \
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(>>=)
1757OP_ASSIGN_WITH_BIT(<<=)
1759#undef OP_ASSIGN_WITH_BIT
1762#define OP_REL_WITH_BIT(REL_OP) \
1763 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1764 INLINE bool operator REL_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1765 const ap_bit_ref<_AP_W2, _AP_S2>& op2) { \
1766 return op1 REL_OP ap_int_base<1, false>(op2); \
1768 template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1769 INLINE bool operator REL_OP(const ap_bit_ref<_AP_W1, _AP_S1>& op1, \
1770 const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1771 return ap_int_base<1, false>(op1) REL_OP op2; \
1781#undef OP_REL_WITH_BIT
1790#define OP_BIN_WITH_CONCAT(BIN_OP, RTYPE) \
1791 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1792 int _AP_W3, bool _AP_S3> \
1793 INLINE typename ap_int_base<_AP_W3, _AP_S3>::template RType<_AP_W1 + _AP_W2, \
1795 operator BIN_OP(const ap_int_base<_AP_W3, _AP_S3>& op1, \
1796 const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op2) { \
1798 return op1 BIN_OP op2.get(); \
1800 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1801 int _AP_W3, bool _AP_S3> \
1802 INLINE typename ap_int_base<_AP_W1 + _AP_W2, \
1803 false>::template RType<_AP_W3, _AP_S3>::RTYPE \
1804 operator BIN_OP(const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op1, \
1805 const ap_int_base<_AP_W3, _AP_S3>& op2) { \
1807 return op1.get() BIN_OP op2; \
1810OP_BIN_WITH_CONCAT(+, plus)
1811OP_BIN_WITH_CONCAT(-, minus)
1812OP_BIN_WITH_CONCAT(*, mult)
1813OP_BIN_WITH_CONCAT(/, div)
1814OP_BIN_WITH_CONCAT(%, mod)
1815OP_BIN_WITH_CONCAT(&, logic)
1816OP_BIN_WITH_CONCAT(|, logic)
1817OP_BIN_WITH_CONCAT(^, logic)
1818OP_BIN_WITH_CONCAT(>>, arg1)
1819OP_BIN_WITH_CONCAT(<<, arg1)
1821#undef OP_BIN_WITH_CONCAT
1824#define OP_ASSIGN_WITH_CONCAT(ASSIGN_OP) \
1825 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1826 int _AP_W3, bool _AP_S3> \
1827 INLINE typename ap_int_base<_AP_W3, _AP_S3>::template RType<_AP_W1 + _AP_W2, \
1829 operator ASSIGN_OP( \
1830 const ap_int_base<_AP_W3, _AP_S3>& op1, \
1831 const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op2) { \
1833 return op1 ASSIGN_OP op2.get(); \
1835 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1836 int _AP_W3, bool _AP_S3> \
1837 INLINE typename ap_int_base<_AP_W1 + _AP_W2, \
1838 false>::template RType<_AP_W3, _AP_S3>::RTYPE \
1839 operator ASSIGN_OP(const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op1, \
1840 const ap_int_base<_AP_W3, _AP_S3>& op2) { \
1842 ap_int_base<_AP_W1 + _AP_W2, false> tmp = op1.get(); \
1843 tmp ASSIGN_OP op2; \
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(>>=)
1857OP_ASSIGN_WITH_CONCAT(<<=)
1859#undef OP_ASSIGN_WITH_CONCAT
1863#define OP_REL_WITH_CONCAT(REL_OP) \
1864 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1865 int _AP_W3, bool _AP_S3> \
1866 INLINE bool operator REL_OP( \
1867 const ap_int_base<_AP_W3, _AP_S3>& op1, \
1868 const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op2) { \
1870 return op1 REL_OP op2.get(); \
1872 template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1873 int _AP_W3, bool _AP_S3> \
1874 INLINE bool operator REL_OP( \
1875 const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op1, \
1876 const ap_int_base<_AP_W3, _AP_S3>& op2) { \
1878 return op1.get() REL_OP op2; \
1881OP_REL_WITH_CONCAT(==)
1882OP_REL_WITH_CONCAT(!=)
1883OP_REL_WITH_CONCAT(>)
1884OP_REL_WITH_CONCAT(>=)
1885OP_REL_WITH_CONCAT(<)
1886OP_REL_WITH_CONCAT(<=)
1888#undef OP_REL_WITH_CONCAT
conditions objects which are tables indexed by raw detector id values
Sign Arbitrary Precision Type.
Unsigned Arbitrary Precision Type.
A very simple wrapper enabling us to more easily tell the output stream to style the input word in he...