mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	rtlil: represent Const strings as std::string
This commit is contained in:
		
							parent
							
								
									61ed9b6263
								
							
						
					
					
						commit
						785bd44da7
					
				
					 90 changed files with 947 additions and 643 deletions
				
			
		|  | @ -80,7 +80,7 @@ struct BitPatternPool | |||
| 	bits_t sig2bits(RTLIL::SigSpec sig) | ||||
| 	{ | ||||
| 		bits_t bits; | ||||
| 		bits.bitdata = sig.as_const().bits; | ||||
| 		bits.bitdata = sig.as_const().bits(); | ||||
| 		for (auto &b : bits.bitdata) | ||||
| 			if (b > RTLIL::State::S1) | ||||
| 				b = RTLIL::State::Sa; | ||||
|  |  | |||
							
								
								
									
										170
									
								
								kernel/calc.cc
									
										
									
									
									
								
							
							
						
						
									
										170
									
								
								kernel/calc.cc
									
										
									
									
									
								
							|  | @ -30,13 +30,13 @@ static void extend_u0(RTLIL::Const &arg, int width, bool is_signed) | |||
| { | ||||
| 	RTLIL::State padding = RTLIL::State::S0; | ||||
| 
 | ||||
| 	if (arg.bits.size() > 0 && is_signed) | ||||
| 		padding = arg.bits.back(); | ||||
| 	if (arg.size() > 0 && is_signed) | ||||
| 		padding = arg.back(); | ||||
| 
 | ||||
| 	while (int(arg.bits.size()) < width) | ||||
| 		arg.bits.push_back(padding); | ||||
| 	while (int(arg.size()) < width) | ||||
| 		arg.bits().push_back(padding); | ||||
| 
 | ||||
| 	arg.bits.resize(width); | ||||
| 	arg.bits().resize(width); | ||||
| } | ||||
| 
 | ||||
| static BigInteger const2big(const RTLIL::Const &val, bool as_signed, int &undef_bit_pos) | ||||
|  | @ -45,17 +45,17 @@ static BigInteger const2big(const RTLIL::Const &val, bool as_signed, int &undef_ | |||
| 
 | ||||
| 	BigInteger::Sign sign = BigInteger::positive; | ||||
| 	State inv_sign_bit = RTLIL::State::S1; | ||||
| 	size_t num_bits = val.bits.size(); | ||||
| 	size_t num_bits = val.size(); | ||||
| 
 | ||||
| 	if (as_signed && num_bits && val.bits[num_bits-1] == RTLIL::State::S1) { | ||||
| 	if (as_signed && num_bits && val[num_bits-1] == RTLIL::State::S1) { | ||||
| 		inv_sign_bit = RTLIL::State::S0; | ||||
| 		sign = BigInteger::negative; | ||||
| 		num_bits--; | ||||
| 	} | ||||
| 
 | ||||
| 	for (size_t i = 0; i < num_bits; i++) | ||||
| 		if (val.bits[i] == RTLIL::State::S0 || val.bits[i] == RTLIL::State::S1) | ||||
| 			mag.setBit(i, val.bits[i] == inv_sign_bit); | ||||
| 		if (val[i] == RTLIL::State::S0 || val[i] == RTLIL::State::S1) | ||||
| 			mag.setBit(i, val[i] == inv_sign_bit); | ||||
| 		else if (undef_bit_pos < 0) | ||||
| 			undef_bit_pos = i; | ||||
| 
 | ||||
|  | @ -79,19 +79,19 @@ static RTLIL::Const big2const(const BigInteger &val, int result_len, int undef_b | |||
| 		{ | ||||
| 			mag--; | ||||
| 			for (int i = 0; i < result_len; i++) | ||||
| 				result.bits[i] = mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1; | ||||
| 				result.bits()[i] = mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			for (int i = 0; i < result_len; i++) | ||||
| 				result.bits[i] = mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0; | ||||
| 				result.bits()[i] = mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| #if 0 | ||||
| 	if (undef_bit_pos >= 0) | ||||
| 		for (int i = undef_bit_pos; i < result_len; i++) | ||||
| 			result.bits[i] = RTLIL::State::Sx; | ||||
| 			result[i] = RTLIL::State::Sx; | ||||
| #endif | ||||
| 
 | ||||
| 	return result; | ||||
|  | @ -132,19 +132,19 @@ static RTLIL::State logic_xnor(RTLIL::State a, RTLIL::State b) | |||
| RTLIL::Const RTLIL::const_not(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len) | ||||
| { | ||||
| 	if (result_len < 0) | ||||
| 		result_len = arg1.bits.size(); | ||||
| 		result_len = arg1.size(); | ||||
| 
 | ||||
| 	RTLIL::Const arg1_ext = arg1; | ||||
| 	extend_u0(arg1_ext, result_len, signed1); | ||||
| 
 | ||||
| 	RTLIL::Const result(RTLIL::State::Sx, result_len); | ||||
| 	for (size_t i = 0; i < size_t(result_len); i++) { | ||||
| 		if (i >= arg1_ext.bits.size()) | ||||
| 			result.bits[i] = RTLIL::State::S0; | ||||
| 		else if (arg1_ext.bits[i] == RTLIL::State::S0) | ||||
| 			result.bits[i] = RTLIL::State::S1; | ||||
| 		else if (arg1_ext.bits[i] == RTLIL::State::S1) | ||||
| 			result.bits[i] = RTLIL::State::S0; | ||||
| 		if (i >= arg1_ext.size()) | ||||
| 			result.bits()[i] = RTLIL::State::S0; | ||||
| 		else if (arg1_ext.bits()[i] == RTLIL::State::S0) | ||||
| 			result.bits()[i] = RTLIL::State::S1; | ||||
| 		else if (arg1_ext.bits()[i] == RTLIL::State::S1) | ||||
| 			result.bits()[i] = RTLIL::State::S0; | ||||
| 	} | ||||
| 
 | ||||
| 	return result; | ||||
|  | @ -154,16 +154,16 @@ static RTLIL::Const logic_wrapper(RTLIL::State(*logic_func)(RTLIL::State, RTLIL: | |||
| 		RTLIL::Const arg1, RTLIL::Const arg2, bool signed1, bool signed2, int result_len = -1) | ||||
| { | ||||
| 	if (result_len < 0) | ||||
| 		result_len = max(arg1.bits.size(), arg2.bits.size()); | ||||
| 		result_len = max(arg1.size(), arg2.size()); | ||||
| 
 | ||||
| 	extend_u0(arg1, result_len, signed1); | ||||
| 	extend_u0(arg2, result_len, signed2); | ||||
| 
 | ||||
| 	RTLIL::Const result(RTLIL::State::Sx, result_len); | ||||
| 	for (size_t i = 0; i < size_t(result_len); i++) { | ||||
| 		RTLIL::State a = i < arg1.bits.size() ? arg1.bits[i] : RTLIL::State::S0; | ||||
| 		RTLIL::State b = i < arg2.bits.size() ? arg2.bits[i] : RTLIL::State::S0; | ||||
| 		result.bits[i] = logic_func(a, b); | ||||
| 		RTLIL::State a = i < arg1.size() ? arg1.bits()[i] : RTLIL::State::S0; | ||||
| 		RTLIL::State b = i < arg2.size() ? arg2.bits()[i] : RTLIL::State::S0; | ||||
| 		result.bits()[i] = logic_func(a, b); | ||||
| 	} | ||||
| 
 | ||||
| 	return result; | ||||
|  | @ -193,12 +193,12 @@ static RTLIL::Const logic_reduce_wrapper(RTLIL::State initial, RTLIL::State(*log | |||
| { | ||||
| 	RTLIL::State temp = initial; | ||||
| 
 | ||||
| 	for (size_t i = 0; i < arg1.bits.size(); i++) | ||||
| 		temp = logic_func(temp, arg1.bits[i]); | ||||
| 	for (size_t i = 0; i < arg1.size(); i++) | ||||
| 		temp = logic_func(temp, arg1[i]); | ||||
| 
 | ||||
| 	RTLIL::Const result(temp); | ||||
| 	while (int(result.bits.size()) < result_len) | ||||
| 		result.bits.push_back(RTLIL::State::S0); | ||||
| 	while (int(result.size()) < result_len) | ||||
| 		result.bits().push_back(RTLIL::State::S0); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -220,11 +220,11 @@ RTLIL::Const RTLIL::const_reduce_xor(const RTLIL::Const &arg1, const RTLIL::Cons | |||
| RTLIL::Const RTLIL::const_reduce_xnor(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len) | ||||
| { | ||||
| 	RTLIL::Const buffer = logic_reduce_wrapper(RTLIL::State::S0, logic_xor, arg1, result_len); | ||||
| 	if (!buffer.bits.empty()) { | ||||
| 		if (buffer.bits.front() == RTLIL::State::S0) | ||||
| 			buffer.bits.front() = RTLIL::State::S1; | ||||
| 		else if (buffer.bits.front() == RTLIL::State::S1) | ||||
| 			buffer.bits.front() = RTLIL::State::S0; | ||||
| 	if (!buffer.empty()) { | ||||
| 		if (buffer.front() == RTLIL::State::S0) | ||||
| 			buffer.bits().front() = RTLIL::State::S1; | ||||
| 		else if (buffer.front() == RTLIL::State::S1) | ||||
| 			buffer.bits().front() = RTLIL::State::S0; | ||||
| 	} | ||||
| 	return buffer; | ||||
| } | ||||
|  | @ -240,8 +240,8 @@ RTLIL::Const RTLIL::const_logic_not(const RTLIL::Const &arg1, const RTLIL::Const | |||
| 	BigInteger a = const2big(arg1, signed1, undef_bit_pos_a); | ||||
| 	RTLIL::Const result(a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S1 : RTLIL::State::S0); | ||||
| 
 | ||||
| 	while (int(result.bits.size()) < result_len) | ||||
| 		result.bits.push_back(RTLIL::State::S0); | ||||
| 	while (int(result.size()) < result_len) | ||||
| 		result.bits().push_back(RTLIL::State::S0); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -255,8 +255,8 @@ RTLIL::Const RTLIL::const_logic_and(const RTLIL::Const &arg1, const RTLIL::Const | |||
| 	RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1; | ||||
| 	RTLIL::Const result(logic_and(bit_a, bit_b)); | ||||
| 
 | ||||
| 	while (int(result.bits.size()) < result_len) | ||||
| 		result.bits.push_back(RTLIL::State::S0); | ||||
| 	while (int(result.size()) < result_len) | ||||
| 		result.bits().push_back(RTLIL::State::S0); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -270,8 +270,8 @@ RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const | |||
| 	RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1; | ||||
| 	RTLIL::Const result(logic_or(bit_a, bit_b)); | ||||
| 
 | ||||
| 	while (int(result.bits.size()) < result_len) | ||||
| 		result.bits.push_back(RTLIL::State::S0); | ||||
| 	while (int(result.size()) < result_len) | ||||
| 		result.bits().push_back(RTLIL::State::S0); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -286,7 +286,7 @@ static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Co | |||
| 	BigInteger offset = const2big(arg2, signed2, undef_bit_pos) * direction; | ||||
| 
 | ||||
| 	if (result_len < 0) | ||||
| 		result_len = arg1.bits.size(); | ||||
| 		result_len = arg1.size(); | ||||
| 
 | ||||
| 	RTLIL::Const result(RTLIL::State::Sx, result_len); | ||||
| 	if (undef_bit_pos >= 0) | ||||
|  | @ -295,11 +295,11 @@ static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Co | |||
| 	for (int i = 0; i < result_len; i++) { | ||||
| 		BigInteger pos = BigInteger(i) + offset; | ||||
| 		if (pos < 0) | ||||
| 			result.bits[i] = vacant_bits; | ||||
| 		else if (pos >= BigInteger(int(arg1.bits.size()))) | ||||
| 			result.bits[i] = sign_ext ? arg1.bits.back() : vacant_bits; | ||||
| 			result.bits()[i] = vacant_bits; | ||||
| 		else if (pos >= BigInteger(int(arg1.size()))) | ||||
| 			result.bits()[i] = sign_ext ? arg1.back() : vacant_bits; | ||||
| 		else | ||||
| 			result.bits[i] = arg1.bits[pos.toInt()]; | ||||
| 			result.bits()[i] = arg1[pos.toInt()]; | ||||
| 	} | ||||
| 
 | ||||
| 	return result; | ||||
|  | @ -347,8 +347,8 @@ RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, | |||
| 	bool y = const2big(arg1, signed1, undef_bit_pos) < const2big(arg2, signed2, undef_bit_pos); | ||||
| 	RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0); | ||||
| 
 | ||||
| 	while (int(result.bits.size()) < result_len) | ||||
| 		result.bits.push_back(RTLIL::State::S0); | ||||
| 	while (int(result.size()) < result_len) | ||||
| 		result.bits().push_back(RTLIL::State::S0); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -358,8 +358,8 @@ RTLIL::Const RTLIL::const_le(const RTLIL::Const &arg1, const RTLIL::Const &arg2, | |||
| 	bool y = const2big(arg1, signed1, undef_bit_pos) <= const2big(arg2, signed2, undef_bit_pos); | ||||
| 	RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0); | ||||
| 
 | ||||
| 	while (int(result.bits.size()) < result_len) | ||||
| 		result.bits.push_back(RTLIL::State::S0); | ||||
| 	while (int(result.size()) < result_len) | ||||
| 		result.bits().push_back(RTLIL::State::S0); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -369,31 +369,31 @@ RTLIL::Const RTLIL::const_eq(const RTLIL::Const &arg1, const RTLIL::Const &arg2, | |||
| 	RTLIL::Const arg2_ext = arg2; | ||||
| 	RTLIL::Const result(RTLIL::State::S0, result_len); | ||||
| 
 | ||||
| 	int width = max(arg1_ext.bits.size(), arg2_ext.bits.size()); | ||||
| 	int width = max(arg1_ext.size(), arg2_ext.size()); | ||||
| 	extend_u0(arg1_ext, width, signed1 && signed2); | ||||
| 	extend_u0(arg2_ext, width, signed1 && signed2); | ||||
| 
 | ||||
| 	RTLIL::State matched_status = RTLIL::State::S1; | ||||
| 	for (size_t i = 0; i < arg1_ext.bits.size(); i++) { | ||||
| 		if (arg1_ext.bits.at(i) == RTLIL::State::S0 && arg2_ext.bits.at(i) == RTLIL::State::S1) | ||||
| 	for (size_t i = 0; i < arg1_ext.size(); i++) { | ||||
| 		if (arg1_ext.at(i) == RTLIL::State::S0 && arg2_ext.at(i) == RTLIL::State::S1) | ||||
| 			return result; | ||||
| 		if (arg1_ext.bits.at(i) == RTLIL::State::S1 && arg2_ext.bits.at(i) == RTLIL::State::S0) | ||||
| 		if (arg1_ext.at(i) == RTLIL::State::S1 && arg2_ext.at(i) == RTLIL::State::S0) | ||||
| 			return result; | ||||
| 		if (arg1_ext.bits.at(i) > RTLIL::State::S1 || arg2_ext.bits.at(i) > RTLIL::State::S1) | ||||
| 		if (arg1_ext.at(i) > RTLIL::State::S1 || arg2_ext.at(i) > RTLIL::State::S1) | ||||
| 			matched_status = RTLIL::State::Sx; | ||||
| 	} | ||||
| 
 | ||||
| 	result.bits.front() = matched_status; | ||||
| 	result.bits().front() = matched_status; | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::const_ne(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) | ||||
| { | ||||
| 	RTLIL::Const result = RTLIL::const_eq(arg1, arg2, signed1, signed2, result_len); | ||||
| 	if (result.bits.front() == RTLIL::State::S0) | ||||
| 		result.bits.front() = RTLIL::State::S1; | ||||
| 	else if (result.bits.front() == RTLIL::State::S1) | ||||
| 		result.bits.front() = RTLIL::State::S0; | ||||
| 	if (result.front() == RTLIL::State::S0) | ||||
| 		result.bits().front() = RTLIL::State::S1; | ||||
| 	else if (result.front() == RTLIL::State::S1) | ||||
| 		result.bits().front() = RTLIL::State::S0; | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -403,26 +403,26 @@ RTLIL::Const RTLIL::const_eqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2 | |||
| 	RTLIL::Const arg2_ext = arg2; | ||||
| 	RTLIL::Const result(RTLIL::State::S0, result_len); | ||||
| 
 | ||||
| 	int width = max(arg1_ext.bits.size(), arg2_ext.bits.size()); | ||||
| 	int width = max(arg1_ext.size(), arg2_ext.size()); | ||||
| 	extend_u0(arg1_ext, width, signed1 && signed2); | ||||
| 	extend_u0(arg2_ext, width, signed1 && signed2); | ||||
| 
 | ||||
| 	for (size_t i = 0; i < arg1_ext.bits.size(); i++) { | ||||
| 		if (arg1_ext.bits.at(i) != arg2_ext.bits.at(i)) | ||||
| 	for (size_t i = 0; i < arg1_ext.size(); i++) { | ||||
| 		if (arg1_ext.at(i) != arg2_ext.at(i)) | ||||
| 			return result; | ||||
| 	} | ||||
| 
 | ||||
| 	result.bits.front() = RTLIL::State::S1; | ||||
| 	result.bits().front() = RTLIL::State::S1; | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::const_nex(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) | ||||
| { | ||||
| 	RTLIL::Const result = RTLIL::const_eqx(arg1, arg2, signed1, signed2, result_len); | ||||
| 	if (result.bits.front() == RTLIL::State::S0) | ||||
| 		result.bits.front() = RTLIL::State::S1; | ||||
| 	else if (result.bits.front() == RTLIL::State::S1) | ||||
| 		result.bits.front() = RTLIL::State::S0; | ||||
| 	if (result.front() == RTLIL::State::S0) | ||||
| 		result.bits().front() = RTLIL::State::S1; | ||||
| 	else if (result.front() == RTLIL::State::S1) | ||||
| 		result.bits().front() = RTLIL::State::S0; | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -432,8 +432,8 @@ RTLIL::Const RTLIL::const_ge(const RTLIL::Const &arg1, const RTLIL::Const &arg2, | |||
| 	bool y = const2big(arg1, signed1, undef_bit_pos) >= const2big(arg2, signed2, undef_bit_pos); | ||||
| 	RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0); | ||||
| 
 | ||||
| 	while (int(result.bits.size()) < result_len) | ||||
| 		result.bits.push_back(RTLIL::State::S0); | ||||
| 	while (int(result.size()) < result_len) | ||||
| 		result.bits().push_back(RTLIL::State::S0); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -443,8 +443,8 @@ RTLIL::Const RTLIL::const_gt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, | |||
| 	bool y = const2big(arg1, signed1, undef_bit_pos) > const2big(arg2, signed2, undef_bit_pos); | ||||
| 	RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0); | ||||
| 
 | ||||
| 	while (int(result.bits.size()) < result_len) | ||||
| 		result.bits.push_back(RTLIL::State::S0); | ||||
| 	while (int(result.size()) < result_len) | ||||
| 		result.bits().push_back(RTLIL::State::S0); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -452,21 +452,21 @@ RTLIL::Const RTLIL::const_add(const RTLIL::Const &arg1, const RTLIL::Const &arg2 | |||
| { | ||||
| 	int undef_bit_pos = -1; | ||||
| 	BigInteger y = const2big(arg1, signed1, undef_bit_pos) + const2big(arg2, signed2, undef_bit_pos); | ||||
| 	return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos); | ||||
| 	return big2const(y, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), undef_bit_pos); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::const_sub(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) | ||||
| { | ||||
| 	int undef_bit_pos = -1; | ||||
| 	BigInteger y = const2big(arg1, signed1, undef_bit_pos) - const2big(arg2, signed2, undef_bit_pos); | ||||
| 	return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos); | ||||
| 	return big2const(y, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), undef_bit_pos); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::const_mul(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) | ||||
| { | ||||
| 	int undef_bit_pos = -1; | ||||
| 	BigInteger y = const2big(arg1, signed1, undef_bit_pos) * const2big(arg2, signed2, undef_bit_pos); | ||||
| 	return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); | ||||
| 	return big2const(y, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0)); | ||||
| } | ||||
| 
 | ||||
| // truncating division
 | ||||
|  | @ -480,7 +480,7 @@ RTLIL::Const RTLIL::const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2 | |||
| 	bool result_neg = (a.getSign() == BigInteger::negative) != (b.getSign() == BigInteger::negative); | ||||
| 	a = a.getSign() == BigInteger::negative ? -a : a; | ||||
| 	b = b.getSign() == BigInteger::negative ? -b : b; | ||||
| 	return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); | ||||
| 	return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0)); | ||||
| } | ||||
| 
 | ||||
| // truncating modulo
 | ||||
|  | @ -494,7 +494,7 @@ RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2 | |||
| 	bool result_neg = a.getSign() == BigInteger::negative; | ||||
| 	a = a.getSign() == BigInteger::negative ? -a : a; | ||||
| 	b = b.getSign() == BigInteger::negative ? -b : b; | ||||
| 	return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); | ||||
| 	return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0)); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::const_divfloor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) | ||||
|  | @ -516,7 +516,7 @@ RTLIL::Const RTLIL::const_divfloor(const RTLIL::Const &arg1, const RTLIL::Const | |||
| 		// bigint division with negative numbers is wonky, make sure we only negate at the very end
 | ||||
| 		result = -((a + b - 1) / b); | ||||
| 	} | ||||
| 	return big2const(result, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); | ||||
| 	return big2const(result, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0)); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::const_modfloor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) | ||||
|  | @ -539,7 +539,7 @@ RTLIL::Const RTLIL::const_modfloor(const RTLIL::Const &arg1, const RTLIL::Const | |||
| 	} else { | ||||
| 		modulo = b_sign == BigInteger::negative ? truncated - b : truncated + b; | ||||
| 	} | ||||
| 	return big2const(modulo, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); | ||||
| 	return big2const(modulo, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0)); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) | ||||
|  | @ -590,7 +590,7 @@ RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2 | |||
| 			y *= -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0)); | ||||
| 	return big2const(y, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0)); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::const_pos(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len) | ||||
|  | @ -628,7 +628,7 @@ RTLIL::Const RTLIL::const_mux(const RTLIL::Const &arg1, const RTLIL::Const &arg2 | |||
| 	RTLIL::Const ret = arg1; | ||||
| 	for (int i = 0; i < ret.size(); i++) | ||||
| 		if (ret[i] != arg2[i]) | ||||
| 			ret[i] = State::Sx; | ||||
| 			ret.bits()[i] = State::Sx; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
|  | @ -642,18 +642,18 @@ RTLIL::Const RTLIL::const_pmux(const RTLIL::Const &arg1, const RTLIL::Const &arg | |||
| 
 | ||||
| 	for (int i = 0; i < arg3.size(); i++) | ||||
| 		if (arg3[i] == State::S1) | ||||
| 			return RTLIL::Const(std::vector<RTLIL::State>(arg2.bits.begin() + i*arg1.bits.size(), arg2.bits.begin() + (i+1)*arg1.bits.size())); | ||||
| 			return RTLIL::Const(std::vector<RTLIL::State>(arg2.begin() + i*arg1.size(), arg2.begin() + (i+1)*arg1.size())); | ||||
| 
 | ||||
| 	log_abort(); // unreachable
 | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::const_bmux(const RTLIL::Const &arg1, const RTLIL::Const &arg2) | ||||
| { | ||||
| 	std::vector<RTLIL::State> t = arg1.bits; | ||||
| 	std::vector<State> t = arg1.to_bits(); | ||||
| 
 | ||||
| 	for (int i = GetSize(arg2)-1; i >= 0; i--) | ||||
| 	{ | ||||
| 		RTLIL::State sel = arg2.bits.at(i); | ||||
| 		RTLIL::State sel = arg2.at(i); | ||||
| 		std::vector<RTLIL::State> new_t; | ||||
| 		if (sel == State::S0) | ||||
| 			new_t = std::vector<RTLIL::State>(t.begin(), t.begin() + GetSize(t)/2); | ||||
|  | @ -689,10 +689,10 @@ RTLIL::Const RTLIL::const_demux(const RTLIL::Const &arg1, const RTLIL::Const &ar | |||
| 				res.push_back(State::S0); | ||||
| 		} else if (x) { | ||||
| 			for (int j = 0; j < width; j++) | ||||
| 				res.push_back(arg1.bits[j] == State::S0 ? State::S0 : State::Sx); | ||||
| 				res.push_back(arg1[j] == State::S0 ? State::S0 : State::Sx); | ||||
| 		} else { | ||||
| 			for (int j = 0; j < width; j++) | ||||
| 				res.push_back(arg1.bits[j]); | ||||
| 				res.push_back(arg1[j]); | ||||
| 		} | ||||
| 	} | ||||
| 	return res; | ||||
|  | @ -703,7 +703,7 @@ RTLIL::Const RTLIL::const_bweqx(const RTLIL::Const &arg1, const RTLIL::Const &ar | |||
| 	log_assert(arg2.size() == arg1.size()); | ||||
| 	RTLIL::Const result(RTLIL::State::S0, arg1.size()); | ||||
| 	for (int i = 0; i < arg1.size(); i++) | ||||
| 		result[i] = arg1[i] == arg2[i] ? State::S1 : State::S0; | ||||
| 		result.bits()[i] = arg1[i] == arg2[i] ? State::S1 : State::S0; | ||||
| 
 | ||||
| 	return result; | ||||
| } | ||||
|  | @ -715,7 +715,7 @@ RTLIL::Const RTLIL::const_bwmux(const RTLIL::Const &arg1, const RTLIL::Const &ar | |||
| 	RTLIL::Const result(RTLIL::State::Sx, arg1.size()); | ||||
| 	for (int i = 0; i < arg1.size(); i++) { | ||||
| 		if (arg3[i] != State::Sx || arg1[i] == arg2[i]) | ||||
| 			result[i] = arg3[i] == State::S1 ? arg2[i] : arg1[i]; | ||||
| 			result.bits()[i] = arg3[i] == State::S1 ? arg2[i] : arg1[i]; | ||||
| 	} | ||||
| 
 | ||||
| 	return result; | ||||
|  |  | |||
|  | @ -325,7 +325,7 @@ struct CellTypes | |||
| 
 | ||||
| 	static RTLIL::Const eval_not(RTLIL::Const v) | ||||
| 	{ | ||||
| 		for (auto &bit : v.bits) | ||||
| 		for (auto &bit : v.bits()) | ||||
| 			if (bit == State::S0) bit = State::S1; | ||||
| 			else if (bit == State::S1) bit = State::S0; | ||||
| 		return v; | ||||
|  | @ -419,13 +419,13 @@ struct CellTypes | |||
| 			RTLIL::Const ret; | ||||
| 			int width = cell->parameters.at(ID::Y_WIDTH).as_int(); | ||||
| 			int offset = cell->parameters.at(ID::OFFSET).as_int(); | ||||
| 			ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width); | ||||
| 			ret.bits().insert(ret.bits().end(), arg1.begin()+offset, arg1.begin()+offset+width); | ||||
| 			return ret; | ||||
| 		} | ||||
| 
 | ||||
| 		if (cell->type == ID($concat)) { | ||||
| 			RTLIL::Const ret = arg1; | ||||
| 			ret.bits.insert(ret.bits.end(), arg2.bits.begin(), arg2.bits.end()); | ||||
| 			ret.bits().insert(ret.bits().end(), arg2.begin(), arg2.end()); | ||||
| 			return ret; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -448,7 +448,7 @@ struct CellTypes | |||
| 		{ | ||||
| 			int width = cell->parameters.at(ID::WIDTH).as_int(); | ||||
| 
 | ||||
| 			std::vector<RTLIL::State> t = cell->parameters.at(ID::LUT).bits; | ||||
| 			std::vector<RTLIL::State> t = cell->parameters.at(ID::LUT).to_bits(); | ||||
| 			while (GetSize(t) < (1 << width)) | ||||
| 				t.push_back(State::S0); | ||||
| 			t.resize(1 << width); | ||||
|  | @ -460,7 +460,7 @@ struct CellTypes | |||
| 		{ | ||||
| 			int width = cell->parameters.at(ID::WIDTH).as_int(); | ||||
| 			int depth = cell->parameters.at(ID::DEPTH).as_int(); | ||||
| 			std::vector<RTLIL::State> t = cell->parameters.at(ID::TABLE).bits; | ||||
| 			std::vector<RTLIL::State> t = cell->parameters.at(ID::TABLE).to_bits(); | ||||
| 
 | ||||
| 			while (GetSize(t) < width*depth*2) | ||||
| 				t.push_back(State::S0); | ||||
|  | @ -473,7 +473,7 @@ struct CellTypes | |||
| 				bool match_x = true; | ||||
| 
 | ||||
| 				for (int j = 0; j < width; j++) { | ||||
| 					RTLIL::State a = arg1.bits.at(j); | ||||
| 					RTLIL::State a = arg1.at(j); | ||||
| 					if (t.at(2*width*i + 2*j + 0) == State::S1) { | ||||
| 						if (a == State::S1) match_x = false; | ||||
| 						if (a != State::S0) match = false; | ||||
|  | @ -513,7 +513,7 @@ struct CellTypes | |||
| 		if (cell->type == ID($_OAI3_)) | ||||
| 			return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1)); | ||||
| 
 | ||||
| 		log_assert(arg3.bits.size() == 0); | ||||
| 		log_assert(arg3.size() == 0); | ||||
| 		return eval(cell, arg1, arg2, errp); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -524,7 +524,7 @@ struct CellTypes | |||
| 		if (cell->type == ID($_OAI4_)) | ||||
| 			return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1)); | ||||
| 
 | ||||
| 		log_assert(arg4.bits.size() == 0); | ||||
| 		log_assert(arg4.size() == 0); | ||||
| 		return eval(cell, arg1, arg2, arg3, errp); | ||||
| 	} | ||||
| }; | ||||
|  |  | |||
|  | @ -76,7 +76,7 @@ struct ConstEval | |||
| #ifndef NDEBUG | ||||
| 		RTLIL::SigSpec current_val = values_map(sig); | ||||
| 		for (int i = 0; i < GetSize(current_val); i++) | ||||
| 			log_assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]); | ||||
| 			log_assert(current_val[i].wire != NULL || current_val[i] == value[i]); | ||||
| #endif | ||||
| 		values_map.add(sig, RTLIL::SigSpec(value)); | ||||
| 	} | ||||
|  | @ -115,7 +115,7 @@ struct ConstEval | |||
| 
 | ||||
| 				for (int i = 0; i < GetSize(coval); i++) { | ||||
| 					carry = (sig_g[i] == State::S1) || (sig_p[i] == RTLIL::S1 && carry); | ||||
| 					coval.bits[i] = carry ? State::S1 : State::S0; | ||||
| 					coval.bits()[i] = carry ? State::S1 : State::S0; | ||||
| 				} | ||||
| 
 | ||||
| 				set(sig_co, coval); | ||||
|  | @ -153,7 +153,7 @@ struct ConstEval | |||
| 
 | ||||
| 			for (int i = 0; i < sig_s.size(); i++) | ||||
| 			{ | ||||
| 				RTLIL::State s_bit = sig_s.extract(i, 1).as_const().bits.at(0); | ||||
| 				RTLIL::State s_bit = sig_s.extract(i, 1).as_const().at(0); | ||||
| 				RTLIL::SigSpec b_slice = sig_b.extract(sig_y.size()*i, sig_y.size()); | ||||
| 
 | ||||
| 				if (s_bit == RTLIL::State::Sx || s_bit == RTLIL::State::S1) | ||||
|  | @ -180,10 +180,10 @@ struct ConstEval | |||
| 
 | ||||
| 			if (y_values.size() > 1) | ||||
| 			{ | ||||
| 				std::vector<RTLIL::State> master_bits = y_values.at(0).bits; | ||||
| 				std::vector<RTLIL::State> master_bits = y_values.at(0).to_bits(); | ||||
| 
 | ||||
| 				for (size_t i = 1; i < y_values.size(); i++) { | ||||
| 					std::vector<RTLIL::State> &slave_bits = y_values.at(i).bits; | ||||
| 					std::vector<RTLIL::State> slave_bits = y_values.at(i).to_bits(); | ||||
| 					log_assert(master_bits.size() == slave_bits.size()); | ||||
| 					for (size_t j = 0; j < master_bits.size(); j++) | ||||
| 						if (master_bits[j] != slave_bits[j]) | ||||
|  | @ -248,8 +248,8 @@ struct ConstEval | |||
| 			RTLIL::Const val_x = const_or(t2, t3, false, false, width); | ||||
| 
 | ||||
| 			for (int i = 0; i < GetSize(val_y); i++) | ||||
| 				if (val_y.bits[i] == RTLIL::Sx) | ||||
| 					val_x.bits[i] = RTLIL::Sx; | ||||
| 				if (val_y[i] == RTLIL::Sx) | ||||
| 					val_x.bits()[i] = RTLIL::Sx; | ||||
| 
 | ||||
| 			set(sig_y, val_y); | ||||
| 			set(sig_x, val_x); | ||||
|  |  | |||
|  | @ -260,7 +260,7 @@ bool DriveChunkMultiple::try_append(DriveBitMultiple const &bit) | |||
| 		switch (single.type()) | ||||
| 		{ | ||||
| 			case DriveType::CONSTANT: { | ||||
| 				single.constant().bits.push_back(constant); | ||||
| 				single.constant().bits().push_back(constant); | ||||
| 			} break; | ||||
| 			case DriveType::WIRE: { | ||||
| 				single.wire().width += 1; | ||||
|  | @ -295,8 +295,8 @@ bool DriveChunkMultiple::try_append(DriveChunkMultiple const &chunk) | |||
| 		switch (single.type()) | ||||
| 		{ | ||||
| 			case DriveType::CONSTANT: { | ||||
| 				auto &bits = single.constant().bits; | ||||
| 				bits.insert(bits.end(), constant.bits.begin(), constant.bits.end()); | ||||
| 				auto &bits = single.constant().bits(); | ||||
| 				bits.insert(bits.end(), constant.bits().begin(), constant.bits().end()); | ||||
| 			} break; | ||||
| 			case DriveType::WIRE: { | ||||
| 				single.wire().width += width; | ||||
|  | @ -349,7 +349,7 @@ bool DriveChunk::try_append(DriveBit const &bit) | |||
| 			none_ += 1; | ||||
| 			return true; | ||||
| 		case DriveType::CONSTANT: | ||||
| 			constant_.bits.push_back(bit.constant()); | ||||
| 			constant_.bits().push_back(bit.constant()); | ||||
| 			return true; | ||||
| 		case DriveType::WIRE: | ||||
| 			return wire_.try_append(bit.wire()); | ||||
|  | @ -375,7 +375,7 @@ bool DriveChunk::try_append(DriveChunk const &chunk) | |||
| 			none_ += chunk.none_; | ||||
| 			return true; | ||||
| 		case DriveType::CONSTANT: | ||||
| 			constant_.bits.insert(constant_.bits.end(), chunk.constant_.bits.begin(), chunk.constant_.bits.end()); | ||||
| 			constant_.bits().insert(constant_.bits().end(), chunk.constant_.begin(), chunk.constant_.end()); | ||||
| 			return true; | ||||
| 		case DriveType::WIRE: | ||||
| 			return wire_.try_append(chunk.wire()); | ||||
|  |  | |||
							
								
								
									
										14
									
								
								kernel/ff.cc
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								kernel/ff.cc
									
										
									
									
									
								
							|  | @ -298,11 +298,11 @@ FfData FfData::slice(const std::vector<int> &bits) { | |||
| 			res.sig_set.append(sig_set[i]); | ||||
| 		} | ||||
| 		if (has_arst) | ||||
| 			res.val_arst.bits.push_back(val_arst[i]); | ||||
| 			res.val_arst.bits().push_back(val_arst[i]); | ||||
| 		if (has_srst) | ||||
| 			res.val_srst.bits.push_back(val_srst[i]); | ||||
| 			res.val_srst.bits().push_back(val_srst[i]); | ||||
| 		if (initvals) | ||||
| 			res.val_init.bits.push_back(val_init[i]); | ||||
| 			res.val_init.bits().push_back(val_init[i]); | ||||
| 	} | ||||
| 	res.width = GetSize(res.sig_q); | ||||
| 	return res; | ||||
|  | @ -688,10 +688,10 @@ void FfData::flip_rst_bits(const pool<int> &bits) { | |||
| 
 | ||||
| 	for (auto bit: bits) { | ||||
| 		if (has_arst) | ||||
| 			val_arst[bit] = invert(val_arst[bit]); | ||||
| 			val_arst.bits()[bit] = invert(val_arst[bit]); | ||||
| 		if (has_srst) | ||||
| 			val_srst[bit] = invert(val_srst[bit]); | ||||
| 		val_init[bit] = invert(val_init[bit]); | ||||
| 			val_srst.bits()[bit] = invert(val_srst[bit]); | ||||
| 		val_init.bits()[bit] = invert(val_init[bit]); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -760,7 +760,7 @@ void FfData::flip_bits(const pool<int> &bits) { | |||
| 
 | ||||
| 		Const mask = Const(State::S0, width); | ||||
| 		for (auto bit: bits) | ||||
| 			mask.bits[bit] = State::S1; | ||||
| 			mask.bits()[bit] = State::S1; | ||||
| 
 | ||||
| 		if (has_clk || has_gclk) | ||||
| 			sig_d = module->Xor(NEW_ID, sig_d, mask); | ||||
|  |  | |||
|  | @ -76,7 +76,7 @@ struct FfInitVals | |||
| 	{ | ||||
| 		RTLIL::Const res; | ||||
| 		for (auto bit : sig) | ||||
| 			res.bits.push_back((*this)(bit)); | ||||
| 			res.bits().push_back((*this)(bit)); | ||||
| 		return res; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -93,12 +93,12 @@ struct FfInitVals | |||
| 		initbits[mbit] = std::make_pair(val,abit); | ||||
| 		auto it2 = abit.wire->attributes.find(ID::init); | ||||
| 		if (it2 != abit.wire->attributes.end()) { | ||||
| 			it2->second[abit.offset] = val; | ||||
| 			it2->second.bits()[abit.offset] = val; | ||||
| 			if (it2->second.is_fully_undef()) | ||||
| 				abit.wire->attributes.erase(it2); | ||||
| 		} else if (val != State::Sx) { | ||||
| 			Const cval(State::Sx, GetSize(abit.wire)); | ||||
| 			cval[abit.offset] = val; | ||||
| 			cval.bits()[abit.offset] = val; | ||||
| 			abit.wire->attributes[ID::init] = cval; | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -42,9 +42,9 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pai | |||
| 			ff.sig_d.append(bit); | ||||
| 			ff.sig_clr.append(State::Sx); | ||||
| 			ff.sig_set.append(State::Sx); | ||||
| 			ff.val_init.bits.push_back(State::Sx); | ||||
| 			ff.val_srst.bits.push_back(State::Sx); | ||||
| 			ff.val_arst.bits.push_back(State::Sx); | ||||
| 			ff.val_init.bits().push_back(State::Sx); | ||||
| 			ff.val_srst.bits().push_back(State::Sx); | ||||
| 			ff.val_arst.bits().push_back(State::Sx); | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -147,9 +147,9 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pai | |||
| 		ff.sig_q.append(cur_ff.sig_q[idx]); | ||||
| 		ff.sig_clr.append(ff.has_sr ? cur_ff.sig_clr[idx] : State::S0); | ||||
| 		ff.sig_set.append(ff.has_sr ? cur_ff.sig_set[idx] : State::S0); | ||||
| 		ff.val_arst.bits.push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx); | ||||
| 		ff.val_srst.bits.push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx); | ||||
| 		ff.val_init.bits.push_back(cur_ff.val_init[idx]); | ||||
| 		ff.val_arst.bits().push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx); | ||||
| 		ff.val_srst.bits().push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx); | ||||
| 		ff.val_init.bits().push_back(cur_ff.val_init[idx]); | ||||
| 		found = true; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -174,9 +174,9 @@ bool FfMergeHelper::find_input_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pair | |||
| 			// These two will be fixed up later.
 | ||||
| 			ff.sig_clr.append(State::Sx); | ||||
| 			ff.sig_set.append(State::Sx); | ||||
| 			ff.val_init.bits.push_back(bit.data); | ||||
| 			ff.val_srst.bits.push_back(bit.data); | ||||
| 			ff.val_arst.bits.push_back(bit.data); | ||||
| 			ff.val_init.bits().push_back(bit.data); | ||||
| 			ff.val_srst.bits().push_back(bit.data); | ||||
| 			ff.val_arst.bits().push_back(bit.data); | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -274,9 +274,9 @@ bool FfMergeHelper::find_input_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pair | |||
| 		ff.sig_q.append(cur_ff.sig_q[idx]); | ||||
| 		ff.sig_clr.append(ff.has_sr ? cur_ff.sig_clr[idx] : State::S0); | ||||
| 		ff.sig_set.append(ff.has_sr ? cur_ff.sig_set[idx] : State::S0); | ||||
| 		ff.val_arst.bits.push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx); | ||||
| 		ff.val_srst.bits.push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx); | ||||
| 		ff.val_init.bits.push_back(cur_ff.val_init[idx]); | ||||
| 		ff.val_arst.bits().push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx); | ||||
| 		ff.val_srst.bits().push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx); | ||||
| 		ff.val_init.bits().push_back(cur_ff.val_init[idx]); | ||||
| 		found = true; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -104,7 +104,7 @@ struct Macc | |||
| 		ports.clear(); | ||||
| 		bit_ports = cell->getPort(ID::B); | ||||
| 
 | ||||
| 		std::vector<RTLIL::State> config_bits = cell->getParam(ID::CONFIG).bits; | ||||
| 		auto config_bits = cell->getParam(ID::CONFIG); | ||||
| 		int config_cursor = 0; | ||||
| 
 | ||||
| 		int config_width = cell->getParam(ID::CONFIG_WIDTH).as_int(); | ||||
|  | @ -199,7 +199,7 @@ struct Macc | |||
| 
 | ||||
| 	bool eval(RTLIL::Const &result) const | ||||
| 	{ | ||||
| 		for (auto &bit : result.bits) | ||||
| 		for (auto &bit : result.bits()) | ||||
| 			bit = State::S0; | ||||
| 
 | ||||
| 		for (auto &port : ports) | ||||
|  |  | |||
|  | @ -157,10 +157,10 @@ void Mem::emit() { | |||
| 			} | ||||
| 			for (int sub = 0; sub < (1 << port.wide_log2); sub++) | ||||
| 			{ | ||||
| 				rd_wide_continuation.bits.push_back(State(sub != 0)); | ||||
| 				rd_clk_enable.bits.push_back(State(port.clk_enable)); | ||||
| 				rd_clk_polarity.bits.push_back(State(port.clk_polarity)); | ||||
| 				rd_ce_over_srst.bits.push_back(State(port.ce_over_srst)); | ||||
| 				rd_wide_continuation.bits().push_back(State(sub != 0)); | ||||
| 				rd_clk_enable.bits().push_back(State(port.clk_enable)); | ||||
| 				rd_clk_polarity.bits().push_back(State(port.clk_polarity)); | ||||
| 				rd_ce_over_srst.bits().push_back(State(port.ce_over_srst)); | ||||
| 				rd_clk.append(port.clk); | ||||
| 				rd_arst.append(port.arst); | ||||
| 				rd_srst.append(port.srst); | ||||
|  | @ -170,17 +170,17 @@ void Mem::emit() { | |||
| 				rd_addr.append(addr); | ||||
| 				log_assert(GetSize(addr) == abits); | ||||
| 				for (auto idx : wr_port_xlat) { | ||||
| 					rd_transparency_mask.bits.push_back(State(bool(port.transparency_mask[idx]))); | ||||
| 					rd_collision_x_mask.bits.push_back(State(bool(port.collision_x_mask[idx]))); | ||||
| 					rd_transparency_mask.bits().push_back(State(bool(port.transparency_mask[idx]))); | ||||
| 					rd_collision_x_mask.bits().push_back(State(bool(port.collision_x_mask[idx]))); | ||||
| 				} | ||||
| 			} | ||||
| 			rd_data.append(port.data); | ||||
| 			for (auto &bit : port.arst_value) | ||||
| 				rd_arst_value.bits.push_back(bit); | ||||
| 			for (auto &bit : port.srst_value) | ||||
| 				rd_srst_value.bits.push_back(bit); | ||||
| 			for (auto &bit : port.init_value) | ||||
| 				rd_init_value.bits.push_back(bit); | ||||
| 			for (auto bit : port.arst_value) | ||||
| 				rd_arst_value.bits().push_back(bit); | ||||
| 			for (auto bit : port.srst_value) | ||||
| 				rd_srst_value.bits().push_back(bit); | ||||
| 			for (auto bit : port.init_value) | ||||
| 				rd_init_value.bits().push_back(bit); | ||||
| 		} | ||||
| 		if (rd_ports.empty()) { | ||||
| 			rd_wide_continuation = State::S0; | ||||
|  | @ -222,12 +222,12 @@ void Mem::emit() { | |||
| 			} | ||||
| 			for (int sub = 0; sub < (1 << port.wide_log2); sub++) | ||||
| 			{ | ||||
| 				wr_wide_continuation.bits.push_back(State(sub != 0)); | ||||
| 				wr_clk_enable.bits.push_back(State(port.clk_enable)); | ||||
| 				wr_clk_polarity.bits.push_back(State(port.clk_polarity)); | ||||
| 				wr_wide_continuation.bits().push_back(State(sub != 0)); | ||||
| 				wr_clk_enable.bits().push_back(State(port.clk_enable)); | ||||
| 				wr_clk_polarity.bits().push_back(State(port.clk_polarity)); | ||||
| 				wr_clk.append(port.clk); | ||||
| 				for (auto idx : wr_port_xlat) | ||||
| 					wr_priority_mask.bits.push_back(State(bool(port.priority_mask[idx]))); | ||||
| 					wr_priority_mask.bits().push_back(State(bool(port.priority_mask[idx]))); | ||||
| 				SigSpec addr = port.sub_addr(sub); | ||||
| 				addr.extend_u0(abits, false); | ||||
| 				wr_addr.append(addr); | ||||
|  | @ -414,7 +414,7 @@ void Mem::coalesce_inits() { | |||
| 			if (!init.en.is_fully_ones()) { | ||||
| 				for (int i = 0; i < GetSize(init.data); i++) | ||||
| 					if (init.en[i % width] != State::S1) | ||||
| 						init.data[i] = State::Sx; | ||||
| 						init.data.bits()[i] = State::Sx; | ||||
| 				init.en = Const(State::S1, width); | ||||
| 			} | ||||
| 			continue; | ||||
|  | @ -427,7 +427,7 @@ void Mem::coalesce_inits() { | |||
| 			log_assert(offset + GetSize(init.data) <= GetSize(cdata)); | ||||
| 			for (int i = 0; i < GetSize(init.data); i++) | ||||
| 				if (init.en[i % width] == State::S1) | ||||
| 					cdata.bits[i+offset] = init.data.bits[i]; | ||||
| 					cdata.bits()[i+offset] = init.data[i]; | ||||
| 			init.removed = true; | ||||
| 		} | ||||
| 		MemInit new_init; | ||||
|  | @ -446,7 +446,7 @@ Const Mem::get_init_data() const { | |||
| 		int offset = (init.addr.as_int() - start_offset) * width; | ||||
| 		for (int i = 0; i < GetSize(init.data); i++) | ||||
| 			if (0 <= i+offset && i+offset < GetSize(init_data) && init.en[i % width] == State::S1) | ||||
| 				init_data.bits[i+offset] = init.data.bits[i]; | ||||
| 				init_data.bits()[i+offset] = init.data[i]; | ||||
| 	} | ||||
| 	return init_data; | ||||
| } | ||||
|  | @ -1702,7 +1702,7 @@ MemContents::MemContents(Mem *mem) : | |||
| 				RTLIL::Const previous = (*this)[addr + i]; | ||||
| 				for(int j = 0; j < _data_width; j++) | ||||
| 					if(init.en[j] != State::S1) | ||||
| 						data[_data_width * i + j] = previous[j]; | ||||
| 						data.bits()[_data_width * i + j] = previous[j]; | ||||
| 			} | ||||
| 			insert_concatenated(init.addr.as_int(), data); | ||||
| 		} | ||||
|  | @ -1848,7 +1848,7 @@ std::map<addr_t, RTLIL::Const>::iterator MemContents::_reserve_range(addr_t begi | |||
| 		// we have two different ranges touching at either end, we need to merge them
 | ||||
| 		auto upper_end = _range_end(upper_it); | ||||
| 		// make range bigger (maybe reserve here instead of resize?)
 | ||||
| 		lower_it->second.bits.resize(_range_offset(lower_it, upper_end), State::Sx); | ||||
| 		lower_it->second.bits().resize(_range_offset(lower_it, upper_end), State::Sx); | ||||
| 		// copy only the data beyond our range
 | ||||
| 		std::copy(_range_data(upper_it, end_addr), _range_data(upper_it, upper_end), _range_data(lower_it, end_addr)); | ||||
| 		// keep lower_it, but delete upper_it
 | ||||
|  | @ -1856,7 +1856,7 @@ std::map<addr_t, RTLIL::Const>::iterator MemContents::_reserve_range(addr_t begi | |||
| 		return lower_it; | ||||
| 	} else if (lower_touch) { | ||||
| 		// we have a range to the left, just make it bigger and delete any other that may exist.
 | ||||
| 		lower_it->second.bits.resize(_range_offset(lower_it, end_addr), State::Sx); | ||||
| 		lower_it->second.bits().resize(_range_offset(lower_it, end_addr), State::Sx); | ||||
| 		// keep lower_it and upper_it
 | ||||
| 		_values.erase(std::next(lower_it), upper_it); | ||||
| 		return lower_it; | ||||
|  | @ -1865,7 +1865,7 @@ std::map<addr_t, RTLIL::Const>::iterator MemContents::_reserve_range(addr_t begi | |||
| 		// since we need to erase and reinsert to a new address, steal the data
 | ||||
| 		RTLIL::Const data = std::move(upper_it->second); | ||||
| 		// note that begin_addr is not in upper_it, otherwise the whole range covered check would have tripped
 | ||||
| 		data.bits.insert(data.bits.begin(), (_range_begin(upper_it) - begin_addr) * _data_width, State::Sx); | ||||
| 		data.bits().insert(data.bits().begin(), (_range_begin(upper_it) - begin_addr) * _data_width, State::Sx); | ||||
| 		// delete lower_it and upper_it, then reinsert
 | ||||
| 		_values.erase(lower_it, std::next(upper_it)); | ||||
| 		return _values.emplace(begin_addr, std::move(data)).first; | ||||
|  | @ -1883,14 +1883,14 @@ void MemContents::insert_concatenated(addr_t addr, RTLIL::Const const &values) { | |||
| 	log_assert(words <= (addr_t)(1<<_addr_width) - addr); | ||||
| 	auto it = _reserve_range(addr, addr + words); | ||||
| 	auto to_begin = _range_data(it, addr); | ||||
| 	std::copy(values.bits.begin(), values.bits.end(), to_begin); | ||||
| 	std::copy(values.begin(), values.end(), to_begin); | ||||
| 	// if values is not word-aligned, fill any missing bits with 0
 | ||||
| 	std::fill(to_begin + values.size(), to_begin + words * _data_width, State::S0); | ||||
| } | ||||
| 
 | ||||
| std::vector<State>::iterator MemContents::_range_write(std::vector<State>::iterator it, RTLIL::Const const &word) { | ||||
| 	auto from_end = word.size() <= _data_width ? word.bits.end() : word.bits.begin() + _data_width; | ||||
| 	auto to_end = std::copy(word.bits.begin(), from_end, it); | ||||
| 	auto from_end = word.size() <= _data_width ? word.end() : word.begin() + _data_width; | ||||
| 	auto to_end = std::copy(word.begin(), from_end, it); | ||||
| 	auto it_next = std::next(it, _data_width); | ||||
| 	std::fill(to_end, it_next, State::S0); | ||||
| 	return it_next; | ||||
|  |  | |||
|  | @ -255,7 +255,7 @@ private: | |||
| 	// return the offset the addr would have in the range at `it`
 | ||||
| 	size_t _range_offset(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) const { return (addr - it->first) * _data_width; } | ||||
| 	// assuming _range_contains(it, addr), return an iterator pointing to the data at addr
 | ||||
| 	std::vector<State>::iterator _range_data(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) { return it->second.bits.begin() + _range_offset(it, addr); } | ||||
| 	std::vector<State>::iterator _range_data(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) { return it->second.bits().begin() + _range_offset(it, addr); } | ||||
| 	// internal version of reserve_range that returns an iterator to the range
 | ||||
| 	std::map<addr_t, RTLIL::Const>::iterator _reserve_range(addr_t begin_addr, addr_t end_addr); | ||||
| 	// write a single word at addr, return iterator to next word
 | ||||
|  |  | |||
							
								
								
									
										304
									
								
								kernel/rtlil.cc
									
										
									
									
									
								
							
							
						
						
									
										304
									
								
								kernel/rtlil.cc
									
										
									
									
									
								
							|  | @ -202,25 +202,34 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() { | |||
| 	return res; | ||||
| } | ||||
| 
 | ||||
| #define check(condition) log_assert(condition && "malformed Const union") | ||||
| 
 | ||||
| Const::bitvectype& Const::get_bits() const { | ||||
| 	check(is_bits()); | ||||
| 	return *get_if_bits(); | ||||
| } | ||||
| 
 | ||||
| std::string& Const::get_str() const { | ||||
| 	check(is_str()); | ||||
| 	return *get_if_str(); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const::Const(const std::string &str) | ||||
| { | ||||
| 	flags = RTLIL::CONST_FLAG_STRING; | ||||
| 	bits.reserve(str.size() * 8); | ||||
| 	for (int i = str.size()-1; i >= 0; i--) { | ||||
| 		unsigned char ch = str[i]; | ||||
| 		for (int j = 0; j < 8; j++) { | ||||
| 			bits.push_back((ch & 1) != 0 ? State::S1 : State::S0); | ||||
| 			ch = ch >> 1; | ||||
| 		} | ||||
| 	} | ||||
| 	new ((void*)&str_) std::string(str); | ||||
| 	tag = backing_tag::string; | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const::Const(long long val, int width) | ||||
| { | ||||
| 	flags = RTLIL::CONST_FLAG_NONE; | ||||
| 	bits.reserve(width); | ||||
| 	new ((void*)&bits_) bitvectype(); | ||||
| 	tag = backing_tag::bits; | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 	bv.reserve(width); | ||||
| 	for (int i = 0; i < width; i++) { | ||||
| 		bits.push_back((val & 1) != 0 ? State::S1 : State::S0); | ||||
| 		bv.push_back((val & 1) != 0 ? State::S1 : State::S0); | ||||
| 		val = val >> 1; | ||||
| 	} | ||||
| } | ||||
|  | @ -228,77 +237,167 @@ RTLIL::Const::Const(long long val, int width) | |||
| RTLIL::Const::Const(RTLIL::State bit, int width) | ||||
| { | ||||
| 	flags = RTLIL::CONST_FLAG_NONE; | ||||
| 	bits.reserve(width); | ||||
| 	new ((void*)&bits_) bitvectype(); | ||||
| 	tag = backing_tag::bits; | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 	bv.reserve(width); | ||||
| 	for (int i = 0; i < width; i++) | ||||
| 		bits.push_back(bit); | ||||
| 		bv.push_back(bit); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const::Const(const std::vector<bool> &bits) | ||||
| { | ||||
| 	flags = RTLIL::CONST_FLAG_NONE; | ||||
| 	this->bits.reserve(bits.size()); | ||||
| 	new ((void*)&bits_) bitvectype(); | ||||
| 	tag = backing_tag::bits; | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 	bv.reserve(bits.size()); | ||||
| 	for (const auto &b : bits) | ||||
| 		this->bits.emplace_back(b ? State::S1 : State::S0); | ||||
| 		bv.emplace_back(b ? State::S1 : State::S0); | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Const::operator <(const RTLIL::Const &other) const | ||||
| RTLIL::Const::Const(const RTLIL::Const &other) { | ||||
| 	tag = other.tag; | ||||
| 	flags = other.flags; | ||||
| 	if (is_str()) | ||||
| 		new ((void*)&str_) std::string(other.get_str()); | ||||
| 	else if (is_bits()) | ||||
| 		new ((void*)&bits_) bitvectype(other.get_bits()); | ||||
| 	else | ||||
| 		check(false); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const::Const(RTLIL::Const &&other) { | ||||
| 	tag = other.tag; | ||||
| 	flags = other.flags; | ||||
| 	if (is_str()) | ||||
| 		new ((void*)&str_) std::string(std::move(other.get_str())); | ||||
| 	else if (is_bits()) | ||||
| 		new ((void*)&bits_) bitvectype(std::move(other.get_bits())); | ||||
| 	else | ||||
| 		check(false); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const &RTLIL::Const::operator =(const RTLIL::Const &other) { | ||||
| 	flags = other.flags; | ||||
| 	if (other.is_str()) { | ||||
| 		if (!is_str()) { | ||||
| 			// sketchy zone
 | ||||
| 			check(is_bits()); | ||||
| 			bits_.~bitvectype(); | ||||
| 			(void)new ((void*)&str_) std::string(); | ||||
| 		} | ||||
| 		tag = other.tag; | ||||
| 		get_str() = other.get_str(); | ||||
| 	} else if (other.is_bits()) { | ||||
| 		if (!is_bits()) { | ||||
| 			// sketchy zone
 | ||||
| 			check(is_str()); | ||||
| 			str_.~string(); | ||||
| 			(void)new ((void*)&bits_) bitvectype(); | ||||
| 		} | ||||
| 		tag = other.tag; | ||||
| 		get_bits() = other.get_bits(); | ||||
| 	} else { | ||||
| 		check(false); | ||||
| 	} | ||||
| 	return *this; | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const::~Const() { | ||||
| 	if (is_bits()) | ||||
| 		bits_.~bitvectype(); | ||||
| 	else if (is_str()) | ||||
| 		str_.~string(); | ||||
| 	else | ||||
| 		check(false); | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Const::operator<(const RTLIL::Const &other) const | ||||
| { | ||||
| 	if (bits.size() != other.bits.size()) | ||||
| 		return bits.size() < other.bits.size(); | ||||
| 	for (size_t i = 0; i < bits.size(); i++) | ||||
| 		if (bits[i] != other.bits[i]) | ||||
| 			return bits[i] < other.bits[i]; | ||||
| 	if (size() != other.size()) | ||||
| 		return size() < other.size(); | ||||
| 
 | ||||
| 	for (int i = 0; i < size(); i++) | ||||
| 		if ((*this)[i] != other[i]) | ||||
| 			return (*this)[i] < other[i]; | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Const::operator ==(const RTLIL::Const &other) const | ||||
| { | ||||
| 	return bits == other.bits; | ||||
| 	if (size() != other.size()) | ||||
| 		return false; | ||||
| 
 | ||||
| 	for (int i = 0; i < size(); i++) | ||||
| 	if ((*this)[i] != other[i]) | ||||
| 		return false; | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Const::operator !=(const RTLIL::Const &other) const | ||||
| { | ||||
| 	return bits != other.bits; | ||||
| 	return !(*this == other); | ||||
| } | ||||
| 
 | ||||
| std::vector<RTLIL::State>& RTLIL::Const::bits() | ||||
| { | ||||
| 	bitvectorize(); | ||||
| 	return get_bits(); | ||||
| } | ||||
| 
 | ||||
| std::vector<RTLIL::State> RTLIL::Const::to_bits() const | ||||
| { | ||||
| 	std::vector<State> v; | ||||
| 	for (auto bit : *this) | ||||
| 		v.push_back(bit); | ||||
| 	return v; | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Const::as_bool() const | ||||
| { | ||||
| 	for (size_t i = 0; i < bits.size(); i++) | ||||
| 		if (bits[i] == State::S1) | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 	for (size_t i = 0; i < bv.size(); i++) | ||||
| 		if (bv[i] == State::S1) | ||||
| 			return true; | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| int RTLIL::Const::as_int(bool is_signed) const | ||||
| { | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 	int32_t ret = 0; | ||||
| 	for (size_t i = 0; i < bits.size() && i < 32; i++) | ||||
| 		if (bits[i] == State::S1) | ||||
| 	for (size_t i = 0; i < bv.size() && i < 32; i++) | ||||
| 		if (bv[i] == State::S1) | ||||
| 			ret |= 1 << i; | ||||
| 	if (is_signed && bits.back() == State::S1) | ||||
| 		for (size_t i = bits.size(); i < 32; i++) | ||||
| 	if (is_signed && bv.back() == State::S1) | ||||
| 		for (size_t i = bv.size(); i < 32; i++) | ||||
| 			ret |= 1 << i; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| size_t RTLIL::Const::get_min_size(bool is_signed) const | ||||
| { | ||||
| 	if (bits.empty()) return 0; | ||||
| 	if (empty()) return 0; | ||||
| 
 | ||||
| 	// back to front (MSB to LSB)
 | ||||
| 	RTLIL::State leading_bit; | ||||
| 	if (is_signed) | ||||
| 		leading_bit = (bits.back() == RTLIL::State::Sx) ? RTLIL::State::S0 : bits.back(); | ||||
| 		leading_bit = (back() == RTLIL::State::Sx) ? RTLIL::State::S0 : back(); | ||||
| 	else | ||||
| 		leading_bit = RTLIL::State::S0; | ||||
| 
 | ||||
| 	size_t idx = bits.size(); | ||||
| 	while (idx > 0 && bits[idx -1] == leading_bit) { | ||||
| 	size_t idx = size(); | ||||
| 	while (idx > 0 && (*this)[idx -1] == leading_bit) { | ||||
| 		idx--; | ||||
| 	} | ||||
| 
 | ||||
| 	// signed needs one leading bit
 | ||||
| 	if (is_signed && idx < bits.size()) { | ||||
| 	if (is_signed && idx < size()) { | ||||
| 		idx++; | ||||
| 	} | ||||
| 	// must be at least one bit
 | ||||
|  | @ -308,7 +407,7 @@ size_t RTLIL::Const::get_min_size(bool is_signed) const | |||
| void RTLIL::Const::compress(bool is_signed) | ||||
| { | ||||
| 	size_t idx = get_min_size(is_signed); | ||||
| 	bits.erase(bits.begin() + idx, bits.end()); | ||||
| 	bits().erase(bits().begin() + idx, bits().end()); | ||||
| } | ||||
| 
 | ||||
| std::optional<int> RTLIL::Const::as_int_compress(bool is_signed) const | ||||
|  | @ -316,28 +415,30 @@ std::optional<int> RTLIL::Const::as_int_compress(bool is_signed) const | |||
| 	size_t size = get_min_size(is_signed); | ||||
| 	if(size == 0 || size > 32) | ||||
| 		return std::nullopt; | ||||
| 		 | ||||
| 
 | ||||
| 	int32_t ret = 0; | ||||
| 	for (size_t i = 0; i < size && i < 32; i++) | ||||
| 		if (bits[i] == State::S1) | ||||
| 		if ((*this)[i] == State::S1) | ||||
| 			ret |= 1 << i; | ||||
| 	if (is_signed && bits[size-1] == State::S1) | ||||
| 	if (is_signed && (*this)[size-1] == State::S1) | ||||
| 		for (size_t i = size; i < 32; i++) | ||||
| 			ret |= 1 << i; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| std::string RTLIL::Const::as_string() const | ||||
| std::string RTLIL::Const::as_string(const char* any) const | ||||
| { | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 	std::string ret; | ||||
| 	ret.reserve(bits.size()); | ||||
| 	for (size_t i = bits.size(); i > 0; i--) | ||||
| 		switch (bits[i-1]) { | ||||
| 	ret.reserve(bv.size()); | ||||
| 	for (size_t i = bv.size(); i > 0; i--) | ||||
| 		switch (bv[i-1]) { | ||||
| 			case S0: ret += "0"; break; | ||||
| 			case S1: ret += "1"; break; | ||||
| 			case Sx: ret += "x"; break; | ||||
| 			case Sz: ret += "z"; break; | ||||
| 			case Sa: ret += "-"; break; | ||||
| 			case Sa: ret += any; break; | ||||
| 			case Sm: ret += "m"; break; | ||||
| 		} | ||||
| 	return ret; | ||||
|  | @ -346,22 +447,28 @@ std::string RTLIL::Const::as_string() const | |||
| RTLIL::Const RTLIL::Const::from_string(const std::string &str) | ||||
| { | ||||
| 	Const c; | ||||
| 	c.bits.reserve(str.size()); | ||||
| 	bitvectype& bv = c.get_bits(); | ||||
| 	bv.reserve(str.size()); | ||||
| 	for (auto it = str.rbegin(); it != str.rend(); it++) | ||||
| 		switch (*it) { | ||||
| 			case '0': c.bits.push_back(State::S0); break; | ||||
| 			case '1': c.bits.push_back(State::S1); break; | ||||
| 			case 'x': c.bits.push_back(State::Sx); break; | ||||
| 			case 'z': c.bits.push_back(State::Sz); break; | ||||
| 			case 'm': c.bits.push_back(State::Sm); break; | ||||
| 			default: c.bits.push_back(State::Sa); | ||||
| 			case '0': bv.push_back(State::S0); break; | ||||
| 			case '1': bv.push_back(State::S1); break; | ||||
| 			case 'x': bv.push_back(State::Sx); break; | ||||
| 			case 'z': bv.push_back(State::Sz); break; | ||||
| 			case 'm': bv.push_back(State::Sm); break; | ||||
| 			default: bv.push_back(State::Sa); | ||||
| 		} | ||||
| 	return c; | ||||
| } | ||||
| 
 | ||||
| std::string RTLIL::Const::decode_string() const | ||||
| { | ||||
| 	const int n = GetSize(bits); | ||||
| 	if (auto str = get_if_str()) | ||||
| 		return *str; | ||||
| 
 | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 	const int n = GetSize(bv); | ||||
| 	const int n_over_8 = n / 8; | ||||
| 	std::string s; | ||||
| 	s.reserve(n_over_8); | ||||
|  | @ -369,7 +476,7 @@ std::string RTLIL::Const::decode_string() const | |||
| 	if (i < n) { | ||||
| 		char ch = 0; | ||||
| 		for (int j = 0; j < (n - i); j++) { | ||||
| 			if (bits[i + j] == RTLIL::State::S1) { | ||||
| 			if (bv[i + j] == RTLIL::State::S1) { | ||||
| 				ch |= 1 << j; | ||||
| 			} | ||||
| 		} | ||||
|  | @ -380,7 +487,7 @@ std::string RTLIL::Const::decode_string() const | |||
| 	for (; i >= 0; i -= 8) { | ||||
| 		char ch = 0; | ||||
| 		for (int j = 0; j < 8; j++) { | ||||
| 			if (bits[i + j] == RTLIL::State::S1) { | ||||
| 			if (bv[i + j] == RTLIL::State::S1) { | ||||
| 				ch |= 1 << j; | ||||
| 			} | ||||
| 		} | ||||
|  | @ -390,11 +497,65 @@ std::string RTLIL::Const::decode_string() const | |||
| 	return s; | ||||
| } | ||||
| 
 | ||||
| int RTLIL::Const::size() const { | ||||
| 	if (is_str()) | ||||
| 		return 8 * str_.size(); | ||||
| 	else { | ||||
| 		check(is_bits()); | ||||
| 		return bits_.size(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Const::empty() const { | ||||
| 	if (is_str()) | ||||
| 		return str_.empty(); | ||||
| 	else { | ||||
| 		check(is_bits()); | ||||
| 		return bits_.empty(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void RTLIL::Const::bitvectorize() const { | ||||
| 	if (tag == backing_tag::bits) | ||||
| 		return; | ||||
| 
 | ||||
| 	check(is_str()); | ||||
| 
 | ||||
| 	bitvectype new_bits; | ||||
| 
 | ||||
| 	new_bits.reserve(str_.size() * 8); | ||||
| 	for (int i = str_.size() - 1; i >= 0; i--) { | ||||
| 		unsigned char ch = str_[i]; | ||||
| 		for (int j = 0; j < 8; j++) { | ||||
| 			new_bits.push_back((ch & 1) != 0 ? State::S1 : State::S0); | ||||
| 			ch = ch >> 1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	{ | ||||
| 		// sketchy zone
 | ||||
| 		str_.~string(); | ||||
| 		(void)new ((void*)&bits_) bitvectype(std::move(new_bits)); | ||||
| 		tag = backing_tag::bits; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| RTLIL::State RTLIL::Const::const_iterator::operator*() const { | ||||
| 	if (auto bv = parent.get_if_bits()) | ||||
| 		return (*bv)[idx]; | ||||
| 
 | ||||
| 	int char_idx = parent.get_str().size() - idx / 8 - 1; | ||||
| 	bool bit = (parent.get_str()[char_idx] & (1 << (idx % 8))); | ||||
| 	return bit ? State::S1 : State::S0; | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Const::is_fully_zero() const | ||||
| { | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 	cover("kernel.rtlil.const.is_fully_zero"); | ||||
| 
 | ||||
| 	for (const auto &bit : bits) | ||||
| 	for (const auto &bit : bv) | ||||
| 		if (bit != RTLIL::State::S0) | ||||
| 			return false; | ||||
| 
 | ||||
|  | @ -403,9 +564,11 @@ bool RTLIL::Const::is_fully_zero() const | |||
| 
 | ||||
| bool RTLIL::Const::is_fully_ones() const | ||||
| { | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 	cover("kernel.rtlil.const.is_fully_ones"); | ||||
| 
 | ||||
| 	for (const auto &bit : bits) | ||||
| 	for (const auto &bit : bv) | ||||
| 		if (bit != RTLIL::State::S1) | ||||
| 			return false; | ||||
| 
 | ||||
|  | @ -416,7 +579,10 @@ bool RTLIL::Const::is_fully_def() const | |||
| { | ||||
| 	cover("kernel.rtlil.const.is_fully_def"); | ||||
| 
 | ||||
| 	for (const auto &bit : bits) | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 
 | ||||
| 	for (const auto &bit : bv) | ||||
| 		if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) | ||||
| 			return false; | ||||
| 
 | ||||
|  | @ -427,7 +593,10 @@ bool RTLIL::Const::is_fully_undef() const | |||
| { | ||||
| 	cover("kernel.rtlil.const.is_fully_undef"); | ||||
| 
 | ||||
| 	for (const auto &bit : bits) | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 
 | ||||
| 	for (const auto &bit : bv) | ||||
| 		if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz) | ||||
| 			return false; | ||||
| 
 | ||||
|  | @ -438,7 +607,10 @@ bool RTLIL::Const::is_fully_undef_x_only() const | |||
| { | ||||
| 	cover("kernel.rtlil.const.is_fully_undef_x_only"); | ||||
| 
 | ||||
| 	for (const auto &bit : bits) | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 
 | ||||
| 	for (const auto &bit : bv) | ||||
| 		if (bit != RTLIL::State::Sx) | ||||
| 			return false; | ||||
| 
 | ||||
|  | @ -449,9 +621,12 @@ bool RTLIL::Const::is_onehot(int *pos) const | |||
| { | ||||
| 	cover("kernel.rtlil.const.is_onehot"); | ||||
| 
 | ||||
| 	bitvectorize(); | ||||
| 	bitvectype& bv = get_bits(); | ||||
| 
 | ||||
| 	bool found = false; | ||||
| 	for (int i = 0; i < GetSize(*this); i++) { | ||||
| 		auto &bit = bits[i]; | ||||
| 		auto &bit = bv[i]; | ||||
| 		if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) | ||||
| 			return false; | ||||
| 		if (bit == RTLIL::State::S1) { | ||||
|  | @ -465,6 +640,15 @@ bool RTLIL::Const::is_onehot(int *pos) const | |||
| 	return found; | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const RTLIL::Const::extract(int offset, int len, RTLIL::State padding) const { | ||||
| 	bitvectype ret_bv; | ||||
| 	ret_bv.reserve(len); | ||||
| 	for (int i = offset; i < offset + len; i++) | ||||
| 		ret_bv.push_back(i < GetSize(*this) ? (*this)[i] : padding); | ||||
| 	return RTLIL::Const(ret_bv); | ||||
| } | ||||
| #undef check /* check(condition) for Const */ | ||||
| 
 | ||||
| bool RTLIL::AttrObject::has_attribute(const RTLIL::IdString &id) const | ||||
| { | ||||
| 	return attributes.count(id); | ||||
|  | @ -1112,7 +1296,7 @@ namespace { | |||
| 		void param_bits(const RTLIL::IdString& name, int width) | ||||
| 		{ | ||||
| 			param(name); | ||||
| 			if (GetSize(cell->parameters.at(name).bits) != width) | ||||
| 			if (GetSize(cell->parameters.at(name)) != width) | ||||
| 				error(__LINE__); | ||||
| 		} | ||||
| 
 | ||||
|  | @ -3940,7 +4124,7 @@ RTLIL::SigChunk::SigChunk(const RTLIL::SigBit &bit) | |||
| 	wire = bit.wire; | ||||
| 	offset = 0; | ||||
| 	if (wire == NULL) | ||||
| 		data = RTLIL::Const(bit.data).bits; | ||||
| 		data = {bit.data}; | ||||
| 	else | ||||
| 		offset = bit.offset; | ||||
| 	width = 1; | ||||
|  |  | |||
							
								
								
									
										136
									
								
								kernel/rtlil.h
									
										
									
									
									
								
							
							
						
						
									
										136
									
								
								kernel/rtlil.h
									
										
									
									
									
								
							|  | @ -47,13 +47,21 @@ namespace RTLIL | |||
| 		STi = 7  // init
 | ||||
| 	}; | ||||
| 
 | ||||
| 	// Semantic metadata - how can this constant be interpreted?
 | ||||
| 	// Values may be generally non-exclusive
 | ||||
| 	enum ConstFlags : unsigned char { | ||||
| 		CONST_FLAG_NONE   = 0, | ||||
| 		CONST_FLAG_STRING = 1, | ||||
| 		CONST_FLAG_SIGNED = 2,  // only used for parameters
 | ||||
| 		CONST_FLAG_REAL   = 4   // only used for parameters
 | ||||
| 		CONST_FLAG_REAL   = 4,  // only used for parameters
 | ||||
| 	}; | ||||
| 
 | ||||
| 	// // Union discriminator. Values are exclusive
 | ||||
| 	// enum ConstRepr : unsigned char {
 | ||||
| 	// 	CONST_REPR_BITS   = 1,
 | ||||
| 	// 	CONST_REPR_STRING = 2,
 | ||||
| 	// };
 | ||||
| 
 | ||||
| 	struct Const; | ||||
| 	struct AttrObject; | ||||
| 	struct Selection; | ||||
|  | @ -658,35 +666,115 @@ namespace RTLIL | |||
| 
 | ||||
| struct RTLIL::Const | ||||
| { | ||||
| 	int flags; | ||||
| 	std::vector<RTLIL::State> bits; | ||||
| 	short flags; | ||||
| private: | ||||
| 	friend class KernelRtlilTest; | ||||
| 	FRIEND_TEST(KernelRtlilTest, ConstStr); | ||||
| 	using bitvectype = std::vector<RTLIL::State>; | ||||
| 	enum class backing_tag: bool { bits, string }; | ||||
| 	// Do not access the union or tag even in Const methods unless necessary
 | ||||
| 	mutable backing_tag tag; | ||||
| 	union { | ||||
| 		mutable bitvectype bits_; | ||||
| 		mutable std::string str_; | ||||
| 	}; | ||||
| 
 | ||||
| 	Const() : flags(RTLIL::CONST_FLAG_NONE) {} | ||||
| 	// Use these private utilities instead
 | ||||
| 	bool is_bits() const { return tag == backing_tag::bits; } | ||||
| 	bool is_str() const { return tag == backing_tag::string; } | ||||
| 
 | ||||
| 	bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; } | ||||
| 	std::string* get_if_str() const { return is_str() ? &str_ : NULL; } | ||||
| 
 | ||||
| 	bitvectype& get_bits() const; | ||||
| 	std::string& get_str() const; | ||||
| public: | ||||
| 	Const() : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::vector<RTLIL::State>()) {} | ||||
| 	Const(const std::string &str); | ||||
| 	Const(long long val, int width = 32); | ||||
| 	Const(RTLIL::State bit, int width = 1); | ||||
| 	Const(const std::vector<RTLIL::State> &bits) : bits(bits) { flags = CONST_FLAG_NONE; } | ||||
| 	Const(const std::vector<RTLIL::State> &bits) : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(bits) {} | ||||
| 	Const(const std::vector<bool> &bits); | ||||
| 	Const(const RTLIL::Const &c) = default; | ||||
| 	RTLIL::Const &operator =(const RTLIL::Const &other) = default; | ||||
| 	Const(const RTLIL::Const &other); | ||||
| 	Const(RTLIL::Const &&other); | ||||
| 	RTLIL::Const &operator =(const RTLIL::Const &other); | ||||
| 	~Const(); | ||||
| 
 | ||||
| 	bool operator <(const RTLIL::Const &other) const; | ||||
| 	bool operator ==(const RTLIL::Const &other) const; | ||||
| 	bool operator !=(const RTLIL::Const &other) const; | ||||
| 
 | ||||
| 	std::vector<RTLIL::State>& bits(); | ||||
| 	bool as_bool() const; | ||||
| 	int as_int(bool is_signed = false) const; | ||||
| 	std::string as_string() const; | ||||
| 	std::string as_string(const char* any = "-") const; | ||||
| 	static Const from_string(const std::string &str); | ||||
| 	std::vector<RTLIL::State> to_bits() const; | ||||
| 
 | ||||
| 	std::string decode_string() const; | ||||
| 	int size() const; | ||||
| 	bool empty() const; | ||||
| 	void bitvectorize() const; | ||||
| 
 | ||||
| 	inline int size() const { return bits.size(); } | ||||
| 	inline bool empty() const { return bits.empty(); } | ||||
| 	inline RTLIL::State &operator[](int index) { return bits.at(index); } | ||||
| 	inline const RTLIL::State &operator[](int index) const { return bits.at(index); } | ||||
| 	inline decltype(bits)::iterator begin() { return bits.begin(); } | ||||
| 	inline decltype(bits)::iterator end() { return bits.end(); } | ||||
| 	class const_iterator { | ||||
| 	private: | ||||
| 		const Const& parent; | ||||
| 		size_t idx; | ||||
| 
 | ||||
| 	public: | ||||
| 		using iterator_category = std::input_iterator_tag; | ||||
| 		using value_type = State; | ||||
| 		using difference_type = std::ptrdiff_t; | ||||
| 		using pointer = const State*; | ||||
| 		using reference = const State&; | ||||
| 
 | ||||
| 		const_iterator(const Const& c, size_t i) : parent(c), idx(i) {} | ||||
| 
 | ||||
| 		State operator*() const; | ||||
| 
 | ||||
| 		const_iterator& operator++() { ++idx; return *this; } | ||||
| 		const_iterator& operator--() { --idx; return *this; } | ||||
| 		const_iterator& operator++(int) { ++idx; return *this; } | ||||
| 		const_iterator& operator--(int) { --idx; return *this; } | ||||
| 		const_iterator& operator+=(int i) { idx += i; return *this; } | ||||
| 
 | ||||
| 		const_iterator operator+(int add) { | ||||
| 			return const_iterator(parent, idx + add); | ||||
| 		} | ||||
| 		const_iterator operator-(int sub) { | ||||
| 			return const_iterator(parent, idx - sub); | ||||
| 		} | ||||
| 		int operator-(const const_iterator& other) { | ||||
| 			return idx - other.idx; | ||||
| 		} | ||||
| 
 | ||||
| 		bool operator==(const const_iterator& other) const { | ||||
| 			return idx == other.idx; | ||||
| 		} | ||||
| 
 | ||||
| 		bool operator!=(const const_iterator& other) const { | ||||
| 			return !(*this == other); | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	const_iterator begin() const { | ||||
| 		return const_iterator(*this, 0); | ||||
| 	} | ||||
| 	const_iterator end() const { | ||||
| 		return const_iterator(*this, size()); | ||||
| 	} | ||||
| 	State back() const { | ||||
| 		return *(end() - 1); | ||||
| 	} | ||||
| 	State front() const { | ||||
| 		return *begin(); | ||||
| 	} | ||||
| 	State at(size_t i) const { | ||||
| 		return *const_iterator(*this, i); | ||||
| 	} | ||||
| 	State operator[](size_t i) const { | ||||
| 		return *const_iterator(*this, i); | ||||
| 	} | ||||
| 
 | ||||
| 	bool is_fully_zero() const; | ||||
| 	bool is_fully_ones() const; | ||||
|  | @ -695,13 +783,7 @@ struct RTLIL::Const | |||
| 	bool is_fully_undef_x_only() const; | ||||
| 	bool is_onehot(int *pos = nullptr) const; | ||||
| 
 | ||||
| 	inline RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const { | ||||
| 		RTLIL::Const ret; | ||||
| 		ret.bits.reserve(len); | ||||
| 		for (int i = offset; i < offset + len; i++) | ||||
| 			ret.bits.push_back(i < GetSize(bits) ? bits[i] : padding); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const; | ||||
| 
 | ||||
| 	// find the MSB without redundant leading bits
 | ||||
| 	size_t get_min_size(bool is_signed) const; | ||||
|  | @ -712,16 +794,18 @@ struct RTLIL::Const | |||
| 	std::optional<int> as_int_compress(bool is_signed) const; | ||||
| 
 | ||||
| 	void extu(int width) { | ||||
| 		bits.resize(width, RTLIL::State::S0); | ||||
| 		bits().resize(width, RTLIL::State::S0); | ||||
| 	} | ||||
| 
 | ||||
| 	void exts(int width) { | ||||
| 		bits.resize(width, bits.empty() ? RTLIL::State::Sx : bits.back()); | ||||
| 		bitvectype& bv = bits(); | ||||
| 		bv.resize(width, bv.empty() ? RTLIL::State::Sx : bv.back()); | ||||
| 	} | ||||
| 
 | ||||
| 	inline unsigned int hash() const { | ||||
| 		unsigned int h = mkhash_init; | ||||
| 		for (auto b : bits) | ||||
| 
 | ||||
| 		for (State b : *this) | ||||
| 			h = mkhash(h, b); | ||||
| 		return h; | ||||
| 	} | ||||
|  | @ -768,8 +852,8 @@ struct RTLIL::SigChunk | |||
| 	int width, offset; | ||||
| 
 | ||||
| 	SigChunk() : wire(nullptr), width(0), offset(0) {} | ||||
| 	SigChunk(const RTLIL::Const &value) : wire(nullptr), data(value.bits), width(GetSize(data)), offset(0) {} | ||||
| 	SigChunk(RTLIL::Const &&value) : wire(nullptr), data(std::move(value.bits)), width(GetSize(data)), offset(0) {} | ||||
| 	SigChunk(const RTLIL::Const &value) : wire(nullptr), data(value.to_bits()), width(GetSize(data)), offset(0) {} | ||||
| 	SigChunk(RTLIL::Const &&value) : wire(nullptr), data(value.to_bits()), width(GetSize(data)), offset(0) {} | ||||
| 	SigChunk(RTLIL::Wire *wire) : wire(wire), width(GetSize(wire)), offset(0) {} | ||||
| 	SigChunk(RTLIL::Wire *wire, int offset, int width = 1) : wire(wire), width(width), offset(offset) {} | ||||
| 	SigChunk(const std::string &str) : SigChunk(RTLIL::Const(str)) {} | ||||
|  |  | |||
|  | @ -922,7 +922,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep) | |||
| 		std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); | ||||
| 
 | ||||
| 		std::vector<int> lut; | ||||
| 		for (auto bit : cell->getParam(ID::LUT).bits) | ||||
| 		for (auto bit : cell->getParam(ID::LUT)) | ||||
| 			lut.push_back(bit == State::S1 ? ez->CONST_TRUE : ez->CONST_FALSE); | ||||
| 		while (GetSize(lut) < (1 << GetSize(a))) | ||||
| 			lut.push_back(ez->CONST_FALSE); | ||||
|  | @ -974,7 +974,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep) | |||
| 		int width = cell->getParam(ID::WIDTH).as_int(); | ||||
| 		int depth = cell->getParam(ID::DEPTH).as_int(); | ||||
| 
 | ||||
| 		vector<State> table_raw = cell->getParam(ID::TABLE).bits; | ||||
| 		vector<State> table_raw = cell->getParam(ID::TABLE).to_bits(); | ||||
| 		while (GetSize(table_raw) < 2*width*depth) | ||||
| 			table_raw.push_back(State::S0); | ||||
| 
 | ||||
|  |  | |||
|  | @ -62,6 +62,9 @@ | |||
|          defines the Yosys Makefile would set for your build configuration. | ||||
| #endif | ||||
| 
 | ||||
| #define FRIEND_TEST(test_case_name, test_name) \ | ||||
|   friend class test_case_name##_##test_name##_Test | ||||
| 
 | ||||
| #ifdef YOSYS_ENABLE_TCL | ||||
| #  include <tcl.h> | ||||
| #  ifdef YOSYS_MXE_HACKS | ||||
|  |  | |||
|  | @ -185,7 +185,7 @@ RTLIL::Const ReadWitness::get_bits(int t, int bits_offset, int width) const | |||
| 	const std::string &bits = steps[t].bits; | ||||
| 
 | ||||
| 	RTLIL::Const result(State::Sa, width); | ||||
| 	result.bits.reserve(width); | ||||
| 	result.bits().reserve(width); | ||||
| 
 | ||||
| 	int read_begin = GetSize(bits) - 1 - bits_offset; | ||||
| 	int read_end = max(-1, read_begin - width); | ||||
|  | @ -200,7 +200,7 @@ RTLIL::Const ReadWitness::get_bits(int t, int bits_offset, int width) const | |||
| 			default: | ||||
| 				log_abort(); | ||||
| 		} | ||||
| 		result.bits[j] = bit; | ||||
| 		result.bits()[j] = bit; | ||||
| 	} | ||||
| 
 | ||||
| 	return result; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue