dnl $Id: l2c_util.m4 260 2010-03-01 16:23:11Z eb771 $
dnl --------------------------------------
dnl High Level Bitwise Operations

include(l2c_util.m4)

dnl MULTI_OR(operand1_prefix1, operand1_postfix, operand2_prefix, operand2_postfix, result_prefix, result_postfix, num_bits)
define(`MULTI_OR', `dnl
# l2c_bitwise::MULTI_OR, operand1_prefix = [$1], operand1_postfix = [$2],
# 	operand2_prefix = [$3], operand2_postfix = [$4],
# 	result_prefix = [$5], result_postfix = [$6],
#	num_bits = [$7]
	(
	FOR(`x', 0, eval($7-1), `dnl
		ifelse(x,0,,` . ')dnl
		(`$5'x`$6' <=> (`$1'x`$2' + `$3'x`$4') )
	')
	)dnl
')dnl

dnl MULTI_AND(operand_prefix1, operand_prefix2, result_prefix, num_bits)
define(`MULTI_AND', `dnl
# l2c_bitwise::MULTI_AND, operand1_prefix = [$1], operand1_postfix = [$2],
# 	operand2_prefix = [$3], operand2_postfix = [$4],
# 	result_prefix = [$5], result_postfix = [$6],
#	num_bits = [$7]
	(
	FOR(`x', 0, eval($7-1), `dnl
		ifelse(x,0,,` . ')dnl
		(`$5'x`$6' <=> (`$1'x`$2' . `$3'x`$4') )
	')
	)dnl
')dnl

dnl MULTI_XOR(operand1_prefix, operand1_postfix,
dnl operand2_prefix, operand2_postfix,
dnl result_prefix, result_postfix, num_bits)
define(`MULTI_XOR', `dnl
# l2c_bitwise::MULTI_XOR, operand1_prefix = [$1], operand1_postfix = [$2],
#	operand2_prefix = [$3], operand2_postfix = [$4],
#	result_prefix = [$5], result_postfix = [$6],
# 	num_bits = [$7]
	(
	FOR(`x', 0, eval($7-1), `dnl
		ifelse(x,0,,` . ')dnl
		(`$5'x`$6' <=> (`$1'x`$2' @ `$3'x`$4') )
	')
	)dnl
')dnl

dnl MULTI_NOT(operand_prefix, operand_postfix,
dnl result_prefix, result_postfix, num_bits)
define(`MULTI_NOT', `dnl
# l2c_bitwise::MULTI_NOT, operand_prefix = [$1], operand_postfix = [$2]
# 	result_prefix = [$3], result_postfix = [$4]
# 	num_bits = [$5]
	(
	FOR(`x', 0, eval($5-1), `dnl
		ifelse(x,0,,` . ')dnl
		(`$3'x`$4' <=> (~`$1'x`$2') )
	')
	)dnl
')dnl

dnl LEFT_SHIFTER(operand_prefix, operand_postfix,
dnl 	result_prefix, result_postfix,
dnl 	num_bits, num_shift)
define(`LEFT_SHIFTER', `dnl
# l2c_bitwise::LEFT_SHIFTER, prefix = [$1], postfix = [$2],
#	result_prefix = [$3], result_postfix = [$4],
# 	num_bits = [$5], num_shift = [$6]

	dnl check if we shift the whole number away.
	ifelse(eval($6>=$5),1,`errprint(`l2c_bitwise::LEFT_SHIFTER: warning: shifts greater than bitfield width')',)
	ifelse(eval($6<0),1,`errprint(`l2c_bitwise::LEFT_SHIFTER: warning: negative shift detected')',)
	(
	FOR(`x', 0, eval($6-1), `dnl loop to pad with zeros
		~`$3'x`$4'  dnl
		ifelse(x,eval($6-1),,` . ') dnl
	')
	) . (
	FOR(`x',$6, eval($5-1), `dnl loop mention the unused bits, stop symbol errors
		(`$1'x`$2' + `~$1'x`$2') dnl
		ifelse(x,eval($5-1),,` . ') dnl
	')
	) . (
	FOR(`x', $6, eval($5-1), `dnl loop to hook skewed inputs
		(`$3'x`$4' <=> (`$1'eval(x-$6)`$2') ) dnl
		ifelse(x,eval($5-1),,` . ') dnl
	')
	)
')dnl

dnl RIGHT_SHIFTER(operand_prefix, operand_postfix,
dnl 	result_prefix, result_postfix,
dnl 	num_bits, num_shift)
define(`RIGHT_SHIFTER', ` dnl
# l2c_bitwise::RIGHT_SHIFTER, operand_prefix = [$1], operand_postfix = [$2],
# 	result_prefix = [$3], result_postfix = [$4],
# 	num_bits = [$5], num_shift = [$6]

	dnl check if we shift the whole number away.
	ifelse(eval($6>=$5),1,`errprint(`l2c_bitwise::RIGHT_SHIFTER: warning: shifts greater than bitfield width')',)
	ifelse(eval($6<0),1,`errprint(`l2c_bitwise::RIGHT_SHIFTER: warning: negative shift detected')',)
	(
	FORI(`x', eval($5-1),eval($5-$6), `dnl loop to pad with zeros
		~`$3'x`$4'  dnl
		ifelse(x,eval($5-$6),,` . ') dnl
	')
	) . (
	FORI(`x',eval($5-$6), 0, `dnl loop mention the unused bits, stop symbol errors
		(`$1'x`$2' + `~$1'x`$2') dnl
		ifelse(x,0,,` . ') dnl
	')
	) . (
	FORI(`x',eval($5-$6-1),0, ` dnl loop to hook skewed inputs
	 	(`$3'eval(x)`$4' <=> (`$1'eval(x+$6)`$2' )) dnl
	 	ifelse(x,0,,` . ') dnl
	')
	)
')dnl
