mult.s 5.19 KB

/*	
 * mult.s			Mon Apr 25 13:06:24 PDT 1994
 *	
 * this is a simple RSP program that tests the permutations of
 * multiplies that you might want to do...
 *
 * Notation:
 *	I	- signed integer
 *	F	- unsigned fraction
 *	SF	- signed fraction
 *
 * so 'IF' is a 32-bit number:	a 16-bit signed integer with a 16-bit
 * unsigned fraction.
 *
 * Notice that since multiplication is communitive, I have not
 * bothered to layout the possibilities with the terms reversed.
 *
 */


 #
 # define some symbolic registers to make this clearer: (I hope)
 #
.name	s_int,		$v2
.name	s_frac,		$v3
.name	t_int,		$v4
.name	t_frac,		$v5
.name	res_int,	$v6
.name	res_frac,	$v7
.name	dev_null,	$v0	
.name	vconst,		$v31

.name	in_base,	$20	
.name	in_sip,		$21	
.name	in_sfp,		$22	
.name	in_tip,		$23	
.name	in_tfp,		$24
.name	out_ip,		$25
.name	out_fp,		$26

#define	TASKDATABASE	0x0000

	.base 	0x04001000

	vxor	vconst, vconst, vconst
	
	addi	in_base, $0, TASKDATABASE
	addi	in_sip, in_base, 0	# s int
	addi	in_sfp, in_base, 2	# s frac
	addi	in_tip, in_base, 4	# t int
	addi	in_tfp, in_base, 6	# t frac
	addi	out_ip, in_base, 16	# result hi
	addi	out_fp, in_base, 18	# result lo

	addi	$1, $0, 1
	mtc2	$0, vconst[2]
	mtc2	$1, vconst[2]
	addi	$1, $0, 2
	mtc2	$1, vconst[4]
	addi	$1, $0, 2
	mtc2	$1, vconst[6]
	
main:	# get s and t:	
	lsv	s_int[0], 0(in_sip)
	lsv	s_frac[0], 0(in_sfp)
	lsv	t_int[0], 0(in_tip)
	lsv	t_frac[0], 0(in_tfp)

	nop
	nop
	nop
	nop

 #
 # enable the one you want to test:	
 #	
 # 	jal	IFxIF
 # 	jal	IFxI
 #	jal	IxIF
 #	jal	IFxF
 #	jal	IxI
 # 	jal	IxF
 # 	jal	FxF
 # 	jal	SFxSF
 # 	jal	SFxI
 	jal	SFxIF
	
	nop
	break
	nop

IFxIF:		
 #
 # double precision multiply:	
 #	IF * IF = IF
 #	
	vmudl	res_frac, s_frac,   t_frac
	vmadm	res_frac, s_int,   t_frac
	vmadn	res_frac, s_frac,  t_int
	vmadh	res_int, s_int,  t_int		# leaves answer-lo in res_frac
	vmadn	res_frac,  dev_null, dev_null[0]# 'extra' nop mult gets answer-hi
	
 # store 32-bit answer...	
	nop		
	nop		
	nop		
	nop		
	nop		
	ssv	res_int[0], 0(out_ip)	# store the hi I
	ssv	res_frac[0], 0(out_fp)	# store the lo F

	jr	$31
	nop

IFxI:	
 #
 # mixed precision multiply:
 #	IF * I = IF
 #	
	vmudn	res_frac, s_frac,  t_int
	vmadh	res_int, s_int,   t_int		# leaves answer-hi in res_int
 	vmadn	res_frac,  dev_null, dev_null[0]# 'extra' nop mult gets answer-lo
	
 # store 32-bit answer...	
	ssv	res_int[0], 0(out_ip)	# store the hi I
	ssv	res_frac[0], 0(out_fp)	# store the lo F

	nop
	nop
	jr	$31
	nop

IxIF:	
 #
 # mixed precision multiply:
 #	I * IF = IF
 #	
	vmudm	res_frac, s_int,    t_frac
	vmadh	res_int,  s_int,    t_int
 	vmadn	res_frac, dev_null, dev_null[0]
	
 # store 32-bit answer...	
	ssv	res_int[0], 0(out_ip)	# store the hi I
	ssv	res_frac[0], 0(out_fp)	# store the lo F

	nop
	nop
	jr	$31
	nop

IFxF:	
 #
 # mixed precision multiply:	(what about signed F?)
 #	IF * F = IF
 #	
 	vmudl	res_frac, s_frac,  t_frac
 	vmadm	res_int, s_int,   t_frac
 	vmadn	res_frac,  dev_null, dev_null[0]
	
 # store 32-bit answer...	
	ssv	res_int[0], 0(out_ip)	# store the hi I
	ssv	res_frac[0], 0(out_fp)	# store the lo F

	nop
	nop
	jr	$31
	nop

IxI:	
 #
 # single precision integer multiply:	
 #	I * I = I
 #	
	vmudh	res_int, s_int, t_int
	
 # store 16-bit answer...	
	ssv	res_int[0], 0(out_ip)	# store the hi I
	
	nop
	nop
	jr	$31
	nop

IxF:	
 #
 # single precision multiply:	(what about signed F?)
 #	I * F = IF
 #	
	vmudm	res_int, s_int,  t_frac
 	vmadn	res_frac,  dev_null, dev_null[0]
	
 # store 32-bit answer...	
	ssv	res_int[0], 0(out_ip)	# store the hi I
	ssv	res_frac[0], 0(out_fp)	# store the lo F

	nop
	nop
	jr	$31
	nop

FxF:	
 #
 # single precision (unsigned fractional) multiply:	
 #	F * F = F
 #	
	vmudl	res_frac, s_frac, t_frac	# this does the work
	
 # store 16-bit answer...	
	ssv	res_frac[0], 0(out_ip)	# store the lo F
	
	nop
	nop
	jr	$31
	nop

SFxSF:	
 #
 # single precision (signed fractional) multiply:	
 #	SF * SF = SF
 #	
	vmulf	res_frac, s_frac, t_frac
	
 # store 16-bit answer...	
	ssv	res_frac[0], 0(out_ip)	# store the lo F
	
	nop
	nop
	jr	$31
	nop

SFxI:	
 #
 # single precision (signed fractional) multiply:	
 #	I * SF = IF
 #	S15. * .S15 = S15.16
 #	

#if 0
	mfc2	$1, t_frac[0]
	sll	$1, $1, 16
	sra	$1, $1, 15
	mtc2	$1, t_frac[0]
	sra	$1, $1, 16
	mtc2	$1, t_int[0]
	
	vmudn	res_frac, t_frac,  s_int
	vmadh	res_int, t_int,   s_int		# leaves answer-hi in res_int
 	vmadn	res_frac,  dev_null, dev_null[0]# 'extra' nop mult gets answer-lo
#endif
	
#if 0
 # 	vmudl	res_frac, s_frac, vconst[0]
 	vmudm	res_int,  s_frac, t_int
 	vmadn	res_frac,  vconst, vconst[0]
#endif
	vmudh	dev_null, s_frac, t_int
	vsaw	res_int, res_int, res_int[0]
	vsaw	res_frac, res_frac, res_frac[1]
	
	nop
	nop
	nop
	nop
	nop
	break
		
 # store 32-bit answer...	
	ssv	res_int[0], 0(out_ip)	# store the hi I
	ssv	res_frac[0], 0(out_fp)	# store the lo F
	
	nop
	break
		
	nop
	nop
	jr	$31
	nop

SFxIF:	
 #
 # mixed precision (signed fractional) multiply:	
 #	IF * SF = IF
 #	S15.16 * .S15 = S15.16
 #	

	# make s S15.16
 	vmudm	s_int,  s_frac, vconst[2]
 	vmadn	s_frac,  vconst, vconst[0]

	nop
	nop
	nop
	nop

	# multiply s by t
	vmudl	res_frac, s_frac,   t_frac
	vmadm	res_frac, s_int,   t_frac
	vmadn	res_frac, s_frac,  t_int
	vmadh	res_int, s_int,  t_int

	nop
	nop
	nop
	nop
	nop
	nop
	break	
	nop
	nop
	
 #
 # what about unsigned fractions? vmulu
 #