155714Skris.rdata
279998Skris.asciiz	"mips3.s, Version 1.1"
355714Skris.asciiz	"MIPS III/IV ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
455714Skris
555714Skris/*
655714Skris * ====================================================================
755714Skris * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
855714Skris * project.
955714Skris *
1055714Skris * Rights for redistribution and usage in source and binary forms are
1155714Skris * granted according to the OpenSSL license. Warranty of any kind is
1255714Skris * disclaimed.
1355714Skris * ====================================================================
1455714Skris */
1555714Skris
1655714Skris/*
1755714Skris * This is my modest contributon to the OpenSSL project (see
1855714Skris * http://www.openssl.org/ for more information about it) and is
1955714Skris * a drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c
2055714Skris * module. For updates see http://fy.chalmers.se/~appro/hpe/.
2155714Skris *
2255714Skris * The module is designed to work with either of the "new" MIPS ABI(5),
2355714Skris * namely N32 or N64, offered by IRIX 6.x. It's not ment to work under
2455714Skris * IRIX 5.x not only because it doesn't support new ABIs but also
2555714Skris * because 5.x kernels put R4x00 CPU into 32-bit mode and all those
2655714Skris * 64-bit instructions (daddu, dmultu, etc.) found below gonna only
2755714Skris * cause illegal instruction exception:-(
2855714Skris *
2955714Skris * In addition the code depends on preprocessor flags set up by MIPSpro
3055714Skris * compiler driver (either as or cc) and therefore (probably?) can't be
3155714Skris * compiled by the GNU assembler. GNU C driver manages fine though...
3255714Skris * I mean as long as -mmips-as is specified or is the default option,
3355714Skris * because then it simply invokes /usr/bin/as which in turn takes
3455714Skris * perfect care of the preprocessor definitions. Another neat feature
3555714Skris * offered by the MIPSpro assembler is an optimization pass. This gave
3655714Skris * me the opportunity to have the code looking more regular as all those
3755714Skris * architecture dependent instruction rescheduling details were left to
3855714Skris * the assembler. Cool, huh?
3955714Skris *
4055714Skris * Performance improvement is astonishing! 'apps/openssl speed rsa dsa'
4155714Skris * goes way over 3 times faster!
4255714Skris *
4355714Skris *					<appro@fy.chalmers.se>
4455714Skris */
4555714Skris#include <asm.h>
4655714Skris#include <regdef.h>
4755714Skris
4855714Skris#if _MIPS_ISA>=4
4955714Skris#define	MOVNZ(cond,dst,src)	\
5055714Skris	movn	dst,src,cond
5155714Skris#else
5255714Skris#define	MOVNZ(cond,dst,src)	\
5355714Skris	.set	noreorder;	\
5455714Skris	bnezl	cond,.+8;	\
5555714Skris	move	dst,src;	\
5655714Skris	.set	reorder
5755714Skris#endif
5855714Skris
5955714Skris.text
6055714Skris
6155714Skris.set	noat
6255714Skris.set	reorder
6355714Skris
6455714Skris#define	MINUS4	v1
6555714Skris
6655714Skris.align	5
6755714SkrisLEAF(bn_mul_add_words)
6855714Skris	.set	noreorder
6955714Skris	bgtzl	a2,.L_bn_mul_add_words_proceed
7055714Skris	ld	t0,0(a1)
7155714Skris	jr	ra
7255714Skris	move	v0,zero
7355714Skris	.set	reorder
7455714Skris
7555714Skris.L_bn_mul_add_words_proceed:
7655714Skris	li	MINUS4,-4
7755714Skris	and	ta0,a2,MINUS4
7855714Skris	move	v0,zero
7955714Skris	beqz	ta0,.L_bn_mul_add_words_tail
8055714Skris
8155714Skris.L_bn_mul_add_words_loop:
8255714Skris	dmultu	t0,a3
8355714Skris	ld	t1,0(a0)
8455714Skris	ld	t2,8(a1)
8555714Skris	ld	t3,8(a0)
8655714Skris	ld	ta0,16(a1)
8755714Skris	ld	ta1,16(a0)
8855714Skris	daddu	t1,v0
8955714Skris	sltu	v0,t1,v0	/* All manuals say it "compares 32-bit
9055714Skris				 * values", but it seems to work fine
9155714Skris				 * even on 64-bit registers. */
9255714Skris	mflo	AT
9355714Skris	mfhi	t0
9455714Skris	daddu	t1,AT
9555714Skris	daddu	v0,t0
9655714Skris	sltu	AT,t1,AT
9755714Skris	sd	t1,0(a0)
9855714Skris	daddu	v0,AT
9955714Skris
10055714Skris	dmultu	t2,a3
10155714Skris	ld	ta2,24(a1)
10255714Skris	ld	ta3,24(a0)
10355714Skris	daddu	t3,v0
10455714Skris	sltu	v0,t3,v0
10555714Skris	mflo	AT
10655714Skris	mfhi	t2
10755714Skris	daddu	t3,AT
10855714Skris	daddu	v0,t2
10955714Skris	sltu	AT,t3,AT
11055714Skris	sd	t3,8(a0)
11155714Skris	daddu	v0,AT
11255714Skris
11355714Skris	dmultu	ta0,a3
11455714Skris	subu	a2,4
11555714Skris	PTR_ADD	a0,32
11655714Skris	PTR_ADD	a1,32
11755714Skris	daddu	ta1,v0
11855714Skris	sltu	v0,ta1,v0
11955714Skris	mflo	AT
12055714Skris	mfhi	ta0
12155714Skris	daddu	ta1,AT
12255714Skris	daddu	v0,ta0
12355714Skris	sltu	AT,ta1,AT
12455714Skris	sd	ta1,-16(a0)
12555714Skris	daddu	v0,AT
12655714Skris
12755714Skris
12855714Skris	dmultu	ta2,a3
12955714Skris	and	ta0,a2,MINUS4
13055714Skris	daddu	ta3,v0
13155714Skris	sltu	v0,ta3,v0
13255714Skris	mflo	AT
13355714Skris	mfhi	ta2
13455714Skris	daddu	ta3,AT
13555714Skris	daddu	v0,ta2
13655714Skris	sltu	AT,ta3,AT
13755714Skris	sd	ta3,-8(a0)
13855714Skris	daddu	v0,AT
13955714Skris	.set	noreorder
14055714Skris	bgtzl	ta0,.L_bn_mul_add_words_loop
14155714Skris	ld	t0,0(a1)
14255714Skris
14355714Skris	bnezl	a2,.L_bn_mul_add_words_tail
14455714Skris	ld	t0,0(a1)
14555714Skris	.set	reorder
14655714Skris
14755714Skris.L_bn_mul_add_words_return:
14855714Skris	jr	ra
14955714Skris
15055714Skris.L_bn_mul_add_words_tail:
15155714Skris	dmultu	t0,a3
15255714Skris	ld	t1,0(a0)
15355714Skris	subu	a2,1
15455714Skris	daddu	t1,v0
15555714Skris	sltu	v0,t1,v0
15655714Skris	mflo	AT
15755714Skris	mfhi	t0
15855714Skris	daddu	t1,AT
15955714Skris	daddu	v0,t0
16055714Skris	sltu	AT,t1,AT
16155714Skris	sd	t1,0(a0)
16255714Skris	daddu	v0,AT
16355714Skris	beqz	a2,.L_bn_mul_add_words_return
16455714Skris
16555714Skris	ld	t0,8(a1)
16655714Skris	dmultu	t0,a3
16755714Skris	ld	t1,8(a0)
16855714Skris	subu	a2,1
16955714Skris	daddu	t1,v0
17055714Skris	sltu	v0,t1,v0
17155714Skris	mflo	AT
17255714Skris	mfhi	t0
17355714Skris	daddu	t1,AT
17455714Skris	daddu	v0,t0
17555714Skris	sltu	AT,t1,AT
17655714Skris	sd	t1,8(a0)
17755714Skris	daddu	v0,AT
17855714Skris	beqz	a2,.L_bn_mul_add_words_return
17955714Skris
18055714Skris	ld	t0,16(a1)
18155714Skris	dmultu	t0,a3
18255714Skris	ld	t1,16(a0)
18355714Skris	daddu	t1,v0
18455714Skris	sltu	v0,t1,v0
18555714Skris	mflo	AT
18655714Skris	mfhi	t0
18755714Skris	daddu	t1,AT
18855714Skris	daddu	v0,t0
18955714Skris	sltu	AT,t1,AT
19055714Skris	sd	t1,16(a0)
19155714Skris	daddu	v0,AT
19255714Skris	jr	ra
19355714SkrisEND(bn_mul_add_words)
19455714Skris
19555714Skris.align	5
19655714SkrisLEAF(bn_mul_words)
19755714Skris	.set	noreorder
19855714Skris	bgtzl	a2,.L_bn_mul_words_proceed
19955714Skris	ld	t0,0(a1)
20055714Skris	jr	ra
20155714Skris	move	v0,zero
20255714Skris	.set	reorder
20355714Skris
20455714Skris.L_bn_mul_words_proceed:
20555714Skris	li	MINUS4,-4
20655714Skris	and	ta0,a2,MINUS4
20755714Skris	move	v0,zero
20855714Skris	beqz	ta0,.L_bn_mul_words_tail
20955714Skris
21055714Skris.L_bn_mul_words_loop:
21155714Skris	dmultu	t0,a3
21255714Skris	ld	t2,8(a1)
21355714Skris	ld	ta0,16(a1)
21455714Skris	ld	ta2,24(a1)
21555714Skris	mflo	AT
21655714Skris	mfhi	t0
21755714Skris	daddu	v0,AT
21855714Skris	sltu	t1,v0,AT
21955714Skris	sd	v0,0(a0)
22055714Skris	daddu	v0,t1,t0
22155714Skris
22255714Skris	dmultu	t2,a3
22355714Skris	subu	a2,4
22455714Skris	PTR_ADD	a0,32
22555714Skris	PTR_ADD	a1,32
22655714Skris	mflo	AT
22755714Skris	mfhi	t2
22855714Skris	daddu	v0,AT
22955714Skris	sltu	t3,v0,AT
23055714Skris	sd	v0,-24(a0)
23155714Skris	daddu	v0,t3,t2
23255714Skris
23355714Skris	dmultu	ta0,a3
23455714Skris	mflo	AT
23555714Skris	mfhi	ta0
23655714Skris	daddu	v0,AT
23755714Skris	sltu	ta1,v0,AT
23855714Skris	sd	v0,-16(a0)
23955714Skris	daddu	v0,ta1,ta0
24055714Skris
24155714Skris
24255714Skris	dmultu	ta2,a3
24355714Skris	and	ta0,a2,MINUS4
24455714Skris	mflo	AT
24555714Skris	mfhi	ta2
24655714Skris	daddu	v0,AT
24755714Skris	sltu	ta3,v0,AT
24855714Skris	sd	v0,-8(a0)
24955714Skris	daddu	v0,ta3,ta2
25055714Skris	.set	noreorder
25155714Skris	bgtzl	ta0,.L_bn_mul_words_loop
25255714Skris	ld	t0,0(a1)
25355714Skris
25455714Skris	bnezl	a2,.L_bn_mul_words_tail
25555714Skris	ld	t0,0(a1)
25655714Skris	.set	reorder
25755714Skris
25855714Skris.L_bn_mul_words_return:
25955714Skris	jr	ra
26055714Skris
26155714Skris.L_bn_mul_words_tail:
26255714Skris	dmultu	t0,a3
26355714Skris	subu	a2,1
26455714Skris	mflo	AT
26555714Skris	mfhi	t0
26655714Skris	daddu	v0,AT
26755714Skris	sltu	t1,v0,AT
26855714Skris	sd	v0,0(a0)
26955714Skris	daddu	v0,t1,t0
27055714Skris	beqz	a2,.L_bn_mul_words_return
27155714Skris
27255714Skris	ld	t0,8(a1)
27355714Skris	dmultu	t0,a3
27455714Skris	subu	a2,1
27555714Skris	mflo	AT
27655714Skris	mfhi	t0
27755714Skris	daddu	v0,AT
27855714Skris	sltu	t1,v0,AT
27955714Skris	sd	v0,8(a0)
28055714Skris	daddu	v0,t1,t0
28155714Skris	beqz	a2,.L_bn_mul_words_return
28255714Skris
28355714Skris	ld	t0,16(a1)
28455714Skris	dmultu	t0,a3
28555714Skris	mflo	AT
28655714Skris	mfhi	t0
28755714Skris	daddu	v0,AT
28855714Skris	sltu	t1,v0,AT
28955714Skris	sd	v0,16(a0)
29055714Skris	daddu	v0,t1,t0
29155714Skris	jr	ra
29255714SkrisEND(bn_mul_words)
29355714Skris
29455714Skris.align	5
29555714SkrisLEAF(bn_sqr_words)
29655714Skris	.set	noreorder
29755714Skris	bgtzl	a2,.L_bn_sqr_words_proceed
29855714Skris	ld	t0,0(a1)
29955714Skris	jr	ra
30055714Skris	move	v0,zero
30155714Skris	.set	reorder
30255714Skris
30355714Skris.L_bn_sqr_words_proceed:
30455714Skris	li	MINUS4,-4
30555714Skris	and	ta0,a2,MINUS4
30655714Skris	move	v0,zero
30755714Skris	beqz	ta0,.L_bn_sqr_words_tail
30855714Skris
30955714Skris.L_bn_sqr_words_loop:
31055714Skris	dmultu	t0,t0
31155714Skris	ld	t2,8(a1)
31255714Skris	ld	ta0,16(a1)
31355714Skris	ld	ta2,24(a1)
31455714Skris	mflo	t1
31555714Skris	mfhi	t0
31655714Skris	sd	t1,0(a0)
31755714Skris	sd	t0,8(a0)
31855714Skris
31955714Skris	dmultu	t2,t2
32055714Skris	subu	a2,4
32155714Skris	PTR_ADD	a0,64
32255714Skris	PTR_ADD	a1,32
32355714Skris	mflo	t3
32455714Skris	mfhi	t2
32555714Skris	sd	t3,-48(a0)
32655714Skris	sd	t2,-40(a0)
32755714Skris
32855714Skris	dmultu	ta0,ta0
32955714Skris	mflo	ta1
33055714Skris	mfhi	ta0
33155714Skris	sd	ta1,-32(a0)
33255714Skris	sd	ta0,-24(a0)
33355714Skris
33455714Skris
33555714Skris	dmultu	ta2,ta2
33655714Skris	and	ta0,a2,MINUS4
33755714Skris	mflo	ta3
33855714Skris	mfhi	ta2
33955714Skris	sd	ta3,-16(a0)
34055714Skris	sd	ta2,-8(a0)
34155714Skris
34255714Skris	.set	noreorder
34355714Skris	bgtzl	ta0,.L_bn_sqr_words_loop
34455714Skris	ld	t0,0(a1)
34555714Skris
34655714Skris	bnezl	a2,.L_bn_sqr_words_tail
34755714Skris	ld	t0,0(a1)
34855714Skris	.set	reorder
34955714Skris
35055714Skris.L_bn_sqr_words_return:
35155714Skris	move	v0,zero
35255714Skris	jr	ra
35355714Skris
35455714Skris.L_bn_sqr_words_tail:
35555714Skris	dmultu	t0,t0
35655714Skris	subu	a2,1
35755714Skris	mflo	t1
35855714Skris	mfhi	t0
35955714Skris	sd	t1,0(a0)
36055714Skris	sd	t0,8(a0)
36155714Skris	beqz	a2,.L_bn_sqr_words_return
36255714Skris
36355714Skris	ld	t0,8(a1)
36455714Skris	dmultu	t0,t0
36555714Skris	subu	a2,1
36655714Skris	mflo	t1
36755714Skris	mfhi	t0
36855714Skris	sd	t1,16(a0)
36955714Skris	sd	t0,24(a0)
37055714Skris	beqz	a2,.L_bn_sqr_words_return
37155714Skris
37255714Skris	ld	t0,16(a1)
37355714Skris	dmultu	t0,t0
37455714Skris	mflo	t1
37555714Skris	mfhi	t0
37655714Skris	sd	t1,32(a0)
37755714Skris	sd	t0,40(a0)
37855714Skris	jr	ra
37955714SkrisEND(bn_sqr_words)
38055714Skris
38155714Skris.align	5
38255714SkrisLEAF(bn_add_words)
38355714Skris	.set	noreorder
38455714Skris	bgtzl	a3,.L_bn_add_words_proceed
38555714Skris	ld	t0,0(a1)
38655714Skris	jr	ra
38755714Skris	move	v0,zero
38855714Skris	.set	reorder
38955714Skris
39055714Skris.L_bn_add_words_proceed:
39155714Skris	li	MINUS4,-4
39255714Skris	and	AT,a3,MINUS4
39355714Skris	move	v0,zero
39455714Skris	beqz	AT,.L_bn_add_words_tail
39555714Skris
39655714Skris.L_bn_add_words_loop:
39755714Skris	ld	ta0,0(a2)
39859191Skris	subu	a3,4
39955714Skris	ld	t1,8(a1)
40059191Skris	and	AT,a3,MINUS4
40155714Skris	ld	t2,16(a1)
40259191Skris	PTR_ADD	a2,32
40355714Skris	ld	t3,24(a1)
40459191Skris	PTR_ADD	a0,32
40559191Skris	ld	ta1,-24(a2)
40659191Skris	PTR_ADD	a1,32
40759191Skris	ld	ta2,-16(a2)
40859191Skris	ld	ta3,-8(a2)
40955714Skris	daddu	ta0,t0
41055714Skris	sltu	t8,ta0,t0
41155714Skris	daddu	t0,ta0,v0
41255714Skris	sltu	v0,t0,ta0
41355714Skris	sd	t0,-32(a0)
41455714Skris	daddu	v0,t8
41555714Skris
41655714Skris	daddu	ta1,t1
41755714Skris	sltu	t9,ta1,t1
41855714Skris	daddu	t1,ta1,v0
41955714Skris	sltu	v0,t1,ta1
42055714Skris	sd	t1,-24(a0)
42155714Skris	daddu	v0,t9
42255714Skris
42355714Skris	daddu	ta2,t2
42455714Skris	sltu	t8,ta2,t2
42555714Skris	daddu	t2,ta2,v0
42655714Skris	sltu	v0,t2,ta2
42755714Skris	sd	t2,-16(a0)
42855714Skris	daddu	v0,t8
42955714Skris
43055714Skris	daddu	ta3,t3
43155714Skris	sltu	t9,ta3,t3
43255714Skris	daddu	t3,ta3,v0
43355714Skris	sltu	v0,t3,ta3
43455714Skris	sd	t3,-8(a0)
43555714Skris	daddu	v0,t9
43655714Skris
43755714Skris	.set	noreorder
43855714Skris	bgtzl	AT,.L_bn_add_words_loop
43955714Skris	ld	t0,0(a1)
44055714Skris
44155714Skris	bnezl	a3,.L_bn_add_words_tail
44255714Skris	ld	t0,0(a1)
44355714Skris	.set	reorder
44455714Skris
44555714Skris.L_bn_add_words_return:
44655714Skris	jr	ra
44755714Skris
44855714Skris.L_bn_add_words_tail:
44955714Skris	ld	ta0,0(a2)
45055714Skris	daddu	ta0,t0
45155714Skris	subu	a3,1
45255714Skris	sltu	t8,ta0,t0
45355714Skris	daddu	t0,ta0,v0
45455714Skris	sltu	v0,t0,ta0
45555714Skris	sd	t0,0(a0)
45655714Skris	daddu	v0,t8
45755714Skris	beqz	a3,.L_bn_add_words_return
45855714Skris
45955714Skris	ld	t1,8(a1)
46055714Skris	ld	ta1,8(a2)
46155714Skris	daddu	ta1,t1
46255714Skris	subu	a3,1
46355714Skris	sltu	t9,ta1,t1
46455714Skris	daddu	t1,ta1,v0
46555714Skris	sltu	v0,t1,ta1
46655714Skris	sd	t1,8(a0)
46755714Skris	daddu	v0,t9
46855714Skris	beqz	a3,.L_bn_add_words_return
46955714Skris
47055714Skris	ld	t2,16(a1)
47155714Skris	ld	ta2,16(a2)
47255714Skris	daddu	ta2,t2
47355714Skris	sltu	t8,ta2,t2
47455714Skris	daddu	t2,ta2,v0
47555714Skris	sltu	v0,t2,ta2
47655714Skris	sd	t2,16(a0)
47755714Skris	daddu	v0,t8
47855714Skris	jr	ra
47955714SkrisEND(bn_add_words)
48055714Skris
48155714Skris.align	5
48255714SkrisLEAF(bn_sub_words)
48355714Skris	.set	noreorder
48455714Skris	bgtzl	a3,.L_bn_sub_words_proceed
48555714Skris	ld	t0,0(a1)
48655714Skris	jr	ra
48755714Skris	move	v0,zero
48855714Skris	.set	reorder
48955714Skris
49055714Skris.L_bn_sub_words_proceed:
49155714Skris	li	MINUS4,-4
49255714Skris	and	AT,a3,MINUS4
49355714Skris	move	v0,zero
49455714Skris	beqz	AT,.L_bn_sub_words_tail
49555714Skris
49655714Skris.L_bn_sub_words_loop:
49755714Skris	ld	ta0,0(a2)
49859191Skris	subu	a3,4
49955714Skris	ld	t1,8(a1)
50059191Skris	and	AT,a3,MINUS4
50155714Skris	ld	t2,16(a1)
50259191Skris	PTR_ADD	a2,32
50355714Skris	ld	t3,24(a1)
50459191Skris	PTR_ADD	a0,32
50559191Skris	ld	ta1,-24(a2)
50659191Skris	PTR_ADD	a1,32
50759191Skris	ld	ta2,-16(a2)
50859191Skris	ld	ta3,-8(a2)
50955714Skris	sltu	t8,t0,ta0
51055714Skris	dsubu	t0,ta0
51155714Skris	dsubu	ta0,t0,v0
51259191Skris	sd	ta0,-32(a0)
51355714Skris	MOVNZ	(t0,v0,t8)
51455714Skris
51555714Skris	sltu	t9,t1,ta1
51655714Skris	dsubu	t1,ta1
51755714Skris	dsubu	ta1,t1,v0
51855714Skris	sd	ta1,-24(a0)
51955714Skris	MOVNZ	(t1,v0,t9)
52055714Skris
52155714Skris
52255714Skris	sltu	t8,t2,ta2
52355714Skris	dsubu	t2,ta2
52455714Skris	dsubu	ta2,t2,v0
52555714Skris	sd	ta2,-16(a0)
52655714Skris	MOVNZ	(t2,v0,t8)
52755714Skris
52855714Skris	sltu	t9,t3,ta3
52955714Skris	dsubu	t3,ta3
53055714Skris	dsubu	ta3,t3,v0
53155714Skris	sd	ta3,-8(a0)
53255714Skris	MOVNZ	(t3,v0,t9)
53355714Skris
53455714Skris	.set	noreorder
53555714Skris	bgtzl	AT,.L_bn_sub_words_loop
53655714Skris	ld	t0,0(a1)
53755714Skris
53855714Skris	bnezl	a3,.L_bn_sub_words_tail
53955714Skris	ld	t0,0(a1)
54055714Skris	.set	reorder
54155714Skris
54255714Skris.L_bn_sub_words_return:
54355714Skris	jr	ra
54455714Skris
54555714Skris.L_bn_sub_words_tail:
54655714Skris	ld	ta0,0(a2)
54755714Skris	subu	a3,1
54855714Skris	sltu	t8,t0,ta0
54955714Skris	dsubu	t0,ta0
55055714Skris	dsubu	ta0,t0,v0
55155714Skris	MOVNZ	(t0,v0,t8)
55255714Skris	sd	ta0,0(a0)
55355714Skris	beqz	a3,.L_bn_sub_words_return
55455714Skris
55555714Skris	ld	t1,8(a1)
55655714Skris	subu	a3,1
55755714Skris	ld	ta1,8(a2)
55855714Skris	sltu	t9,t1,ta1
55955714Skris	dsubu	t1,ta1
56055714Skris	dsubu	ta1,t1,v0
56155714Skris	MOVNZ	(t1,v0,t9)
56255714Skris	sd	ta1,8(a0)
56355714Skris	beqz	a3,.L_bn_sub_words_return
56455714Skris
56555714Skris	ld	t2,16(a1)
56655714Skris	ld	ta2,16(a2)
56755714Skris	sltu	t8,t2,ta2
56855714Skris	dsubu	t2,ta2
56955714Skris	dsubu	ta2,t2,v0
57055714Skris	MOVNZ	(t2,v0,t8)
57155714Skris	sd	ta2,16(a0)
57255714Skris	jr	ra
57355714SkrisEND(bn_sub_words)
57455714Skris
57555714Skris#undef	MINUS4
57655714Skris
57759191Skris.align 5
57859191SkrisLEAF(bn_div_3_words)
57959191Skris	.set	reorder
58059191Skris	move	a3,a0		/* we know that bn_div_words doesn't
58159191Skris				 * touch a3, ta2, ta3 and preserves a2
58259191Skris				 * so that we can save two arguments
58359191Skris				 * and return address in registers
58459191Skris				 * instead of stack:-)
58559191Skris				 */
58659191Skris	ld	a0,(a3)
58759191Skris	move	ta2,a1
58859191Skris	ld	a1,-8(a3)
58976866Skris	bne	a0,a2,.L_bn_div_3_words_proceed
59076866Skris	li	v0,-1
59176866Skris	jr	ra
59276866Skris.L_bn_div_3_words_proceed:
59359191Skris	move	ta3,ra
59459191Skris	bal	bn_div_words
59559191Skris	move	ra,ta3
59659191Skris	dmultu	ta2,v0
59759191Skris	ld	t2,-16(a3)
59859191Skris	move	ta0,zero
59959191Skris	mfhi	t1
60059191Skris	mflo	t0
60159191Skris	sltu	t8,t1,v1
60259191Skris.L_bn_div_3_words_inner_loop:
60359191Skris	bnez	t8,.L_bn_div_3_words_inner_loop_done
60459191Skris	sgeu	AT,t2,t0
60559191Skris	seq	t9,t1,v1
60659191Skris	and	AT,t9
60759191Skris	sltu	t3,t0,ta2
60859191Skris	daddu	v1,a2
60959191Skris	dsubu	t1,t3
61059191Skris	dsubu	t0,ta2
61159191Skris	sltu	t8,t1,v1
61259191Skris	sltu	ta0,v1,a2
61359191Skris	or	t8,ta0
61459191Skris	.set	noreorder
61559191Skris	beqzl	AT,.L_bn_div_3_words_inner_loop
61659191Skris	dsubu	v0,1
61759191Skris	.set	reorder
61859191Skris.L_bn_div_3_words_inner_loop_done:
61959191Skris	jr	ra
62059191SkrisEND(bn_div_3_words)
62159191Skris
62255714Skris.align	5
62355714SkrisLEAF(bn_div_words)
62455714Skris	.set	noreorder
62555714Skris	bnezl	a2,.L_bn_div_words_proceed
62655714Skris	move	v1,zero
62755714Skris	jr	ra
62855714Skris	li	v0,-1		/* I'd rather signal div-by-zero
62955714Skris				 * which can be done with 'break 7' */
63055714Skris
63155714Skris.L_bn_div_words_proceed:
63255714Skris	bltz	a2,.L_bn_div_words_body
63355714Skris	move	t9,v1
63455714Skris	dsll	a2,1
63555714Skris	bgtz	a2,.-4
63655714Skris	addu	t9,1
63755714Skris
63855714Skris	.set	reorder
63955714Skris	negu	t1,t9
64055714Skris	li	t2,-1
64155714Skris	dsll	t2,t1
64255714Skris	and	t2,a0
64355714Skris	dsrl	AT,a1,t1
64455714Skris	.set	noreorder
64555714Skris	bnezl	t2,.+8
64655714Skris	break	6		/* signal overflow */
64755714Skris	.set	reorder
64855714Skris	dsll	a0,t9
64955714Skris	dsll	a1,t9
65055714Skris	or	a0,AT
65155714Skris
65255714Skris#define	QT	ta0
65355714Skris#define	HH	ta1
65455714Skris#define	DH	v1
65555714Skris.L_bn_div_words_body:
65655714Skris	dsrl	DH,a2,32
65755714Skris	sgeu	AT,a0,a2
65855714Skris	.set	noreorder
65955714Skris	bnezl	AT,.+8
66055714Skris	dsubu	a0,a2
66155714Skris	.set	reorder
66255714Skris
66355714Skris	li	QT,-1
66455714Skris	dsrl	HH,a0,32
66555714Skris	dsrl	QT,32	/* q=0xffffffff */
66655714Skris	beq	DH,HH,.L_bn_div_words_skip_div1
66755714Skris	ddivu	zero,a0,DH
66855714Skris	mflo	QT
66955714Skris.L_bn_div_words_skip_div1:
67055714Skris	dmultu	a2,QT
67155714Skris	dsll	t3,a0,32
67255714Skris	dsrl	AT,a1,32
67355714Skris	or	t3,AT
67455714Skris	mflo	t0
67555714Skris	mfhi	t1
67655714Skris.L_bn_div_words_inner_loop1:
67755714Skris	sltu	t2,t3,t0
67855714Skris	seq	t8,HH,t1
67955714Skris	sltu	AT,HH,t1
68055714Skris	and	t2,t8
68159191Skris	sltu	v0,t0,a2
68255714Skris	or	AT,t2
68355714Skris	.set	noreorder
68455714Skris	beqz	AT,.L_bn_div_words_inner_loop1_done
68559191Skris	dsubu	t1,v0
68655714Skris	dsubu	t0,a2
68755714Skris	b	.L_bn_div_words_inner_loop1
68859191Skris	dsubu	QT,1
68959191Skris	.set	reorder
69059191Skris.L_bn_div_words_inner_loop1_done:
69155714Skris
69255714Skris	dsll	a1,32
69355714Skris	dsubu	a0,t3,t0
69455714Skris	dsll	v0,QT,32
69555714Skris
69655714Skris	li	QT,-1
69755714Skris	dsrl	HH,a0,32
69855714Skris	dsrl	QT,32	/* q=0xffffffff */
69955714Skris	beq	DH,HH,.L_bn_div_words_skip_div2
70055714Skris	ddivu	zero,a0,DH
70155714Skris	mflo	QT
70255714Skris.L_bn_div_words_skip_div2:
70359191Skris#undef	DH
70455714Skris	dmultu	a2,QT
70555714Skris	dsll	t3,a0,32
70655714Skris	dsrl	AT,a1,32
70755714Skris	or	t3,AT
70855714Skris	mflo	t0
70955714Skris	mfhi	t1
71055714Skris.L_bn_div_words_inner_loop2:
71155714Skris	sltu	t2,t3,t0
71255714Skris	seq	t8,HH,t1
71355714Skris	sltu	AT,HH,t1
71455714Skris	and	t2,t8
71559191Skris	sltu	v1,t0,a2
71655714Skris	or	AT,t2
71755714Skris	.set	noreorder
71855714Skris	beqz	AT,.L_bn_div_words_inner_loop2_done
71959191Skris	dsubu	t1,v1
72055714Skris	dsubu	t0,a2
72155714Skris	b	.L_bn_div_words_inner_loop2
72259191Skris	dsubu	QT,1
72359191Skris	.set	reorder
72455714Skris.L_bn_div_words_inner_loop2_done:
72559191Skris#undef	HH
72655714Skris
72755714Skris	dsubu	a0,t3,t0
72855714Skris	or	v0,QT
72955714Skris	dsrl	v1,a0,t9	/* v1 contains remainder if anybody wants it */
73055714Skris	dsrl	a2,t9		/* restore a2 */
73155714Skris	jr	ra
73255714Skris#undef	QT
73355714SkrisEND(bn_div_words)
73455714Skris
73555714Skris#define	a_0	t0
73655714Skris#define	a_1	t1
73755714Skris#define	a_2	t2
73855714Skris#define	a_3	t3
73955714Skris#define	b_0	ta0
74055714Skris#define	b_1	ta1
74155714Skris#define	b_2	ta2
74255714Skris#define	b_3	ta3
74355714Skris
74455714Skris#define	a_4	s0
74555714Skris#define	a_5	s2
74655714Skris#define	a_6	s4
74755714Skris#define	a_7	a1	/* once we load a[7] we don't need a anymore */
74855714Skris#define	b_4	s1
74955714Skris#define	b_5	s3
75055714Skris#define	b_6	s5
75155714Skris#define	b_7	a2	/* once we load b[7] we don't need b anymore */
75255714Skris
75355714Skris#define	t_1	t8
75455714Skris#define	t_2	t9
75555714Skris
75655714Skris#define	c_1	v0
75755714Skris#define	c_2	v1
75855714Skris#define	c_3	a3
75955714Skris
76055714Skris#define	FRAME_SIZE	48
76155714Skris
76255714Skris.align	5
76355714SkrisLEAF(bn_mul_comba8)
76455714Skris	.set	noreorder
76555714Skris	PTR_SUB	sp,FRAME_SIZE
76655714Skris	.frame	sp,64,ra
76755714Skris	.set	reorder
76855714Skris	ld	a_0,0(a1)	/* If compiled with -mips3 option on
76955714Skris				 * R5000 box assembler barks on this
77055714Skris				 * line with "shouldn't have mult/div
77155714Skris				 * as last instruction in bb (R10K
77255714Skris				 * bug)" warning. If anybody out there
77355714Skris				 * has a clue about how to circumvent
77455714Skris				 * this do send me a note.
77555714Skris				 *		<appro@fy.chalmers.se>
77655714Skris				 */
77755714Skris	ld	b_0,0(a2)
77855714Skris	ld	a_1,8(a1)
77955714Skris	ld	a_2,16(a1)
78055714Skris	ld	a_3,24(a1)
78155714Skris	ld	b_1,8(a2)
78255714Skris	ld	b_2,16(a2)
78355714Skris	ld	b_3,24(a2)
78455714Skris	dmultu	a_0,b_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
78555714Skris	sd	s0,0(sp)
78655714Skris	sd	s1,8(sp)
78755714Skris	sd	s2,16(sp)
78855714Skris	sd	s3,24(sp)
78955714Skris	sd	s4,32(sp)
79055714Skris	sd	s5,40(sp)
79155714Skris	mflo	c_1
79255714Skris	mfhi	c_2
79355714Skris
79455714Skris	dmultu	a_0,b_1		/* mul_add_c(a[0],b[1],c2,c3,c1); */
79555714Skris	ld	a_4,32(a1)
79655714Skris	ld	a_5,40(a1)
79755714Skris	ld	a_6,48(a1)
79855714Skris	ld	a_7,56(a1)
79955714Skris	ld	b_4,32(a2)
80055714Skris	ld	b_5,40(a2)
80155714Skris	mflo	t_1
80255714Skris	mfhi	t_2
80355714Skris	daddu	c_2,t_1
80455714Skris	sltu	AT,c_2,t_1
80555714Skris	daddu	c_3,t_2,AT
80655714Skris	dmultu	a_1,b_0		/* mul_add_c(a[1],b[0],c2,c3,c1); */
80755714Skris	ld	b_6,48(a2)
80855714Skris	ld	b_7,56(a2)
80955714Skris	sd	c_1,0(a0)	/* r[0]=c1; */
81055714Skris	mflo	t_1
81155714Skris	mfhi	t_2
81255714Skris	daddu	c_2,t_1
81355714Skris	sltu	AT,c_2,t_1
81455714Skris	daddu	t_2,AT
81555714Skris	daddu	c_3,t_2
81655714Skris	sltu	c_1,c_3,t_2
81755714Skris	sd	c_2,8(a0)	/* r[1]=c2; */
81855714Skris
81955714Skris	dmultu	a_2,b_0		/* mul_add_c(a[2],b[0],c3,c1,c2); */
82055714Skris	mflo	t_1
82155714Skris	mfhi	t_2
82255714Skris	daddu	c_3,t_1
82355714Skris	sltu	AT,c_3,t_1
82455714Skris	daddu	t_2,AT
82555714Skris	daddu	c_1,t_2
82655714Skris	dmultu	a_1,b_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
82755714Skris	mflo	t_1
82855714Skris	mfhi	t_2
82955714Skris	daddu	c_3,t_1
83055714Skris	sltu	AT,c_3,t_1
83155714Skris	daddu	t_2,AT
83255714Skris	daddu	c_1,t_2
83355714Skris	sltu	c_2,c_1,t_2
83455714Skris	dmultu	a_0,b_2		/* mul_add_c(a[0],b[2],c3,c1,c2); */
83555714Skris	mflo	t_1
83655714Skris	mfhi	t_2
83755714Skris	daddu	c_3,t_1
83855714Skris	sltu	AT,c_3,t_1
83955714Skris	daddu	t_2,AT
84055714Skris	daddu	c_1,t_2
84155714Skris	sltu	AT,c_1,t_2
84255714Skris	daddu	c_2,AT
84355714Skris	sd	c_3,16(a0)	/* r[2]=c3; */
84455714Skris
84555714Skris	dmultu	a_0,b_3		/* mul_add_c(a[0],b[3],c1,c2,c3); */
84655714Skris	mflo	t_1
84755714Skris	mfhi	t_2
84855714Skris	daddu	c_1,t_1
84955714Skris	sltu	AT,c_1,t_1
85055714Skris	daddu	t_2,AT
85155714Skris	daddu	c_2,t_2
85279998Skris	sltu	c_3,c_2,t_2
85355714Skris	dmultu	a_1,b_2		/* mul_add_c(a[1],b[2],c1,c2,c3); */
85455714Skris	mflo	t_1
85555714Skris	mfhi	t_2
85655714Skris	daddu	c_1,t_1
85755714Skris	sltu	AT,c_1,t_1
85855714Skris	daddu	t_2,AT
85955714Skris	daddu	c_2,t_2
86079998Skris	sltu	AT,c_2,t_2
86179998Skris	daddu	c_3,AT
86255714Skris	dmultu	a_2,b_1		/* mul_add_c(a[2],b[1],c1,c2,c3); */
86355714Skris	mflo	t_1
86455714Skris	mfhi	t_2
86555714Skris	daddu	c_1,t_1
86655714Skris	sltu	AT,c_1,t_1
86755714Skris	daddu	t_2,AT
86855714Skris	daddu	c_2,t_2
86955714Skris	sltu	AT,c_2,t_2
87055714Skris	daddu	c_3,AT
87155714Skris	dmultu	a_3,b_0		/* mul_add_c(a[3],b[0],c1,c2,c3); */
87255714Skris	mflo	t_1
87355714Skris	mfhi	t_2
87455714Skris	daddu	c_1,t_1
87555714Skris	sltu	AT,c_1,t_1
87655714Skris	daddu	t_2,AT
87755714Skris	daddu	c_2,t_2
87855714Skris	sltu	AT,c_2,t_2
87955714Skris	daddu	c_3,AT
88055714Skris	sd	c_1,24(a0)	/* r[3]=c1; */
88155714Skris
88255714Skris	dmultu	a_4,b_0		/* mul_add_c(a[4],b[0],c2,c3,c1); */
88355714Skris	mflo	t_1
88455714Skris	mfhi	t_2
88555714Skris	daddu	c_2,t_1
88655714Skris	sltu	AT,c_2,t_1
88755714Skris	daddu	t_2,AT
88855714Skris	daddu	c_3,t_2
88979998Skris	sltu	c_1,c_3,t_2
89055714Skris	dmultu	a_3,b_1		/* mul_add_c(a[3],b[1],c2,c3,c1); */
89155714Skris	mflo	t_1
89255714Skris	mfhi	t_2
89355714Skris	daddu	c_2,t_1
89455714Skris	sltu	AT,c_2,t_1
89555714Skris	daddu	t_2,AT
89655714Skris	daddu	c_3,t_2
89779998Skris	sltu	AT,c_3,t_2
89879998Skris	daddu	c_1,AT
89955714Skris	dmultu	a_2,b_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
90055714Skris	mflo	t_1
90155714Skris	mfhi	t_2
90255714Skris	daddu	c_2,t_1
90355714Skris	sltu	AT,c_2,t_1
90455714Skris	daddu	t_2,AT
90555714Skris	daddu	c_3,t_2
90655714Skris	sltu	AT,c_3,t_2
90755714Skris	daddu	c_1,AT
90855714Skris	dmultu	a_1,b_3		/* mul_add_c(a[1],b[3],c2,c3,c1); */
90955714Skris	mflo	t_1
91055714Skris	mfhi	t_2
91155714Skris	daddu	c_2,t_1
91255714Skris	sltu	AT,c_2,t_1
91355714Skris	daddu	t_2,AT
91455714Skris	daddu	c_3,t_2
91555714Skris	sltu	AT,c_3,t_2
91655714Skris	daddu	c_1,AT
91755714Skris	dmultu	a_0,b_4		/* mul_add_c(a[0],b[4],c2,c3,c1); */
91855714Skris	mflo	t_1
91955714Skris	mfhi	t_2
92055714Skris	daddu	c_2,t_1
92155714Skris	sltu	AT,c_2,t_1
92255714Skris	daddu	t_2,AT
92355714Skris	daddu	c_3,t_2
92455714Skris	sltu	AT,c_3,t_2
92555714Skris	daddu	c_1,AT
92655714Skris	sd	c_2,32(a0)	/* r[4]=c2; */
92755714Skris
92855714Skris	dmultu	a_0,b_5		/* mul_add_c(a[0],b[5],c3,c1,c2); */
92955714Skris	mflo	t_1
93055714Skris	mfhi	t_2
93155714Skris	daddu	c_3,t_1
93255714Skris	sltu	AT,c_3,t_1
93355714Skris	daddu	t_2,AT
93455714Skris	daddu	c_1,t_2
93579998Skris	sltu	c_2,c_1,t_2
93655714Skris	dmultu	a_1,b_4		/* mul_add_c(a[1],b[4],c3,c1,c2); */
93755714Skris	mflo	t_1
93855714Skris	mfhi	t_2
93955714Skris	daddu	c_3,t_1
94055714Skris	sltu	AT,c_3,t_1
94155714Skris	daddu	t_2,AT
94255714Skris	daddu	c_1,t_2
94379998Skris	sltu	AT,c_1,t_2
94479998Skris	daddu	c_2,AT
94555714Skris	dmultu	a_2,b_3		/* mul_add_c(a[2],b[3],c3,c1,c2); */
94655714Skris	mflo	t_1
94755714Skris	mfhi	t_2
94855714Skris	daddu	c_3,t_1
94955714Skris	sltu	AT,c_3,t_1
95055714Skris	daddu	t_2,AT
95155714Skris	daddu	c_1,t_2
95255714Skris	sltu	AT,c_1,t_2
95355714Skris	daddu	c_2,AT
95455714Skris	dmultu	a_3,b_2		/* mul_add_c(a[3],b[2],c3,c1,c2); */
95555714Skris	mflo	t_1
95655714Skris	mfhi	t_2
95755714Skris	daddu	c_3,t_1
95855714Skris	sltu	AT,c_3,t_1
95955714Skris	daddu	t_2,AT
96055714Skris	daddu	c_1,t_2
96155714Skris	sltu	AT,c_1,t_2
96255714Skris	daddu	c_2,AT
96355714Skris	dmultu	a_4,b_1		/* mul_add_c(a[4],b[1],c3,c1,c2); */
96455714Skris	mflo	t_1
96555714Skris	mfhi	t_2
96655714Skris	daddu	c_3,t_1
96755714Skris	sltu	AT,c_3,t_1
96855714Skris	daddu	t_2,AT
96955714Skris	daddu	c_1,t_2
97055714Skris	sltu	AT,c_1,t_2
97155714Skris	daddu	c_2,AT
97255714Skris	dmultu	a_5,b_0		/* mul_add_c(a[5],b[0],c3,c1,c2); */
97355714Skris	mflo	t_1
97455714Skris	mfhi	t_2
97555714Skris	daddu	c_3,t_1
97655714Skris	sltu	AT,c_3,t_1
97755714Skris	daddu	t_2,AT
97855714Skris	daddu	c_1,t_2
97955714Skris	sltu	AT,c_1,t_2
98055714Skris	daddu	c_2,AT
98155714Skris	sd	c_3,40(a0)	/* r[5]=c3; */
98255714Skris
98355714Skris	dmultu	a_6,b_0		/* mul_add_c(a[6],b[0],c1,c2,c3); */
98455714Skris	mflo	t_1
98555714Skris	mfhi	t_2
98655714Skris	daddu	c_1,t_1
98755714Skris	sltu	AT,c_1,t_1
98855714Skris	daddu	t_2,AT
98955714Skris	daddu	c_2,t_2
99079998Skris	sltu	c_3,c_2,t_2
99155714Skris	dmultu	a_5,b_1		/* mul_add_c(a[5],b[1],c1,c2,c3); */
99255714Skris	mflo	t_1
99355714Skris	mfhi	t_2
99455714Skris	daddu	c_1,t_1
99555714Skris	sltu	AT,c_1,t_1
99655714Skris	daddu	t_2,AT
99755714Skris	daddu	c_2,t_2
99879998Skris	sltu	AT,c_2,t_2
99979998Skris	daddu	c_3,AT
100055714Skris	dmultu	a_4,b_2		/* mul_add_c(a[4],b[2],c1,c2,c3); */
100155714Skris	mflo	t_1
100255714Skris	mfhi	t_2
100355714Skris	daddu	c_1,t_1
100455714Skris	sltu	AT,c_1,t_1
100555714Skris	daddu	t_2,AT
100655714Skris	daddu	c_2,t_2
100755714Skris	sltu	AT,c_2,t_2
100855714Skris	daddu	c_3,AT
100955714Skris	dmultu	a_3,b_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
101055714Skris	mflo	t_1
101155714Skris	mfhi	t_2
101255714Skris	daddu	c_1,t_1
101355714Skris	sltu	AT,c_1,t_1
101455714Skris	daddu	t_2,AT
101555714Skris	daddu	c_2,t_2
101655714Skris	sltu	AT,c_2,t_2
101755714Skris	daddu	c_3,AT
101855714Skris	dmultu	a_2,b_4		/* mul_add_c(a[2],b[4],c1,c2,c3); */
101955714Skris	mflo	t_1
102055714Skris	mfhi	t_2
102155714Skris	daddu	c_1,t_1
102255714Skris	sltu	AT,c_1,t_1
102355714Skris	daddu	t_2,AT
102455714Skris	daddu	c_2,t_2
102555714Skris	sltu	AT,c_2,t_2
102655714Skris	daddu	c_3,AT
102755714Skris	dmultu	a_1,b_5		/* mul_add_c(a[1],b[5],c1,c2,c3); */
102855714Skris	mflo	t_1
102955714Skris	mfhi	t_2
103055714Skris	daddu	c_1,t_1
103155714Skris	sltu	AT,c_1,t_1
103255714Skris	daddu	t_2,AT
103355714Skris	daddu	c_2,t_2
103455714Skris	sltu	AT,c_2,t_2
103555714Skris	daddu	c_3,AT
103655714Skris	dmultu	a_0,b_6		/* mul_add_c(a[0],b[6],c1,c2,c3); */
103755714Skris	mflo	t_1
103855714Skris	mfhi	t_2
103955714Skris	daddu	c_1,t_1
104055714Skris	sltu	AT,c_1,t_1
104155714Skris	daddu	t_2,AT
104255714Skris	daddu	c_2,t_2
104355714Skris	sltu	AT,c_2,t_2
104455714Skris	daddu	c_3,AT
104555714Skris	sd	c_1,48(a0)	/* r[6]=c1; */
104655714Skris
104755714Skris	dmultu	a_0,b_7		/* mul_add_c(a[0],b[7],c2,c3,c1); */
104855714Skris	mflo	t_1
104955714Skris	mfhi	t_2
105055714Skris	daddu	c_2,t_1
105155714Skris	sltu	AT,c_2,t_1
105255714Skris	daddu	t_2,AT
105355714Skris	daddu	c_3,t_2
105479998Skris	sltu	c_1,c_3,t_2
105555714Skris	dmultu	a_1,b_6		/* mul_add_c(a[1],b[6],c2,c3,c1); */
105655714Skris	mflo	t_1
105755714Skris	mfhi	t_2
105855714Skris	daddu	c_2,t_1
105955714Skris	sltu	AT,c_2,t_1
106055714Skris	daddu	t_2,AT
106155714Skris	daddu	c_3,t_2
106279998Skris	sltu	AT,c_3,t_2
106379998Skris	daddu	c_1,AT
106455714Skris	dmultu	a_2,b_5		/* mul_add_c(a[2],b[5],c2,c3,c1); */
106555714Skris	mflo	t_1
106655714Skris	mfhi	t_2
106755714Skris	daddu	c_2,t_1
106855714Skris	sltu	AT,c_2,t_1
106955714Skris	daddu	t_2,AT
107055714Skris	daddu	c_3,t_2
107155714Skris	sltu	AT,c_3,t_2
107255714Skris	daddu	c_1,AT
107355714Skris	dmultu	a_3,b_4		/* mul_add_c(a[3],b[4],c2,c3,c1); */
107455714Skris	mflo	t_1
107555714Skris	mfhi	t_2
107655714Skris	daddu	c_2,t_1
107755714Skris	sltu	AT,c_2,t_1
107855714Skris	daddu	t_2,AT
107955714Skris	daddu	c_3,t_2
108055714Skris	sltu	AT,c_3,t_2
108155714Skris	daddu	c_1,AT
108255714Skris	dmultu	a_4,b_3		/* mul_add_c(a[4],b[3],c2,c3,c1); */
108355714Skris	mflo	t_1
108455714Skris	mfhi	t_2
108555714Skris	daddu	c_2,t_1
108655714Skris	sltu	AT,c_2,t_1
108755714Skris	daddu	t_2,AT
108855714Skris	daddu	c_3,t_2
108955714Skris	sltu	AT,c_3,t_2
109055714Skris	daddu	c_1,AT
109155714Skris	dmultu	a_5,b_2		/* mul_add_c(a[5],b[2],c2,c3,c1); */
109255714Skris	mflo	t_1
109355714Skris	mfhi	t_2
109455714Skris	daddu	c_2,t_1
109555714Skris	sltu	AT,c_2,t_1
109655714Skris	daddu	t_2,AT
109755714Skris	daddu	c_3,t_2
109855714Skris	sltu	AT,c_3,t_2
109955714Skris	daddu	c_1,AT
110055714Skris	dmultu	a_6,b_1		/* mul_add_c(a[6],b[1],c2,c3,c1); */
110155714Skris	mflo	t_1
110255714Skris	mfhi	t_2
110355714Skris	daddu	c_2,t_1
110455714Skris	sltu	AT,c_2,t_1
110555714Skris	daddu	t_2,AT
110655714Skris	daddu	c_3,t_2
110755714Skris	sltu	AT,c_3,t_2
110855714Skris	daddu	c_1,AT
110955714Skris	dmultu	a_7,b_0		/* mul_add_c(a[7],b[0],c2,c3,c1); */
111055714Skris	mflo	t_1
111155714Skris	mfhi	t_2
111255714Skris	daddu	c_2,t_1
111355714Skris	sltu	AT,c_2,t_1
111455714Skris	daddu	t_2,AT
111555714Skris	daddu	c_3,t_2
111655714Skris	sltu	AT,c_3,t_2
111755714Skris	daddu	c_1,AT
111855714Skris	sd	c_2,56(a0)	/* r[7]=c2; */
111955714Skris
112055714Skris	dmultu	a_7,b_1		/* mul_add_c(a[7],b[1],c3,c1,c2); */
112155714Skris	mflo	t_1
112255714Skris	mfhi	t_2
112355714Skris	daddu	c_3,t_1
112455714Skris	sltu	AT,c_3,t_1
112555714Skris	daddu	t_2,AT
112655714Skris	daddu	c_1,t_2
112779998Skris	sltu	c_2,c_1,t_2
112855714Skris	dmultu	a_6,b_2		/* mul_add_c(a[6],b[2],c3,c1,c2); */
112955714Skris	mflo	t_1
113055714Skris	mfhi	t_2
113155714Skris	daddu	c_3,t_1
113255714Skris	sltu	AT,c_3,t_1
113355714Skris	daddu	t_2,AT
113455714Skris	daddu	c_1,t_2
113579998Skris	sltu	AT,c_1,t_2
113679998Skris	daddu	c_2,AT
113755714Skris	dmultu	a_5,b_3		/* mul_add_c(a[5],b[3],c3,c1,c2); */
113855714Skris	mflo	t_1
113955714Skris	mfhi	t_2
114055714Skris	daddu	c_3,t_1
114155714Skris	sltu	AT,c_3,t_1
114255714Skris	daddu	t_2,AT
114355714Skris	daddu	c_1,t_2
114455714Skris	sltu	AT,c_1,t_2
114555714Skris	daddu	c_2,AT
114655714Skris	dmultu	a_4,b_4		/* mul_add_c(a[4],b[4],c3,c1,c2); */
114755714Skris	mflo	t_1
114855714Skris	mfhi	t_2
114955714Skris	daddu	c_3,t_1
115055714Skris	sltu	AT,c_3,t_1
115155714Skris	daddu	t_2,AT
115255714Skris	daddu	c_1,t_2
115355714Skris	sltu	AT,c_1,t_2
115455714Skris	daddu	c_2,AT
115555714Skris	dmultu	a_3,b_5		/* mul_add_c(a[3],b[5],c3,c1,c2); */
115655714Skris	mflo	t_1
115755714Skris	mfhi	t_2
115855714Skris	daddu	c_3,t_1
115955714Skris	sltu	AT,c_3,t_1
116055714Skris	daddu	t_2,AT
116155714Skris	daddu	c_1,t_2
116255714Skris	sltu	AT,c_1,t_2
116355714Skris	daddu	c_2,AT
116455714Skris	dmultu	a_2,b_6		/* mul_add_c(a[2],b[6],c3,c1,c2); */
116555714Skris	mflo	t_1
116655714Skris	mfhi	t_2
116755714Skris	daddu	c_3,t_1
116855714Skris	sltu	AT,c_3,t_1
116955714Skris	daddu	t_2,AT
117055714Skris	daddu	c_1,t_2
117155714Skris	sltu	AT,c_1,t_2
117255714Skris	daddu	c_2,AT
117355714Skris	dmultu	a_1,b_7		/* mul_add_c(a[1],b[7],c3,c1,c2); */
117455714Skris	mflo	t_1
117555714Skris	mfhi	t_2
117655714Skris	daddu	c_3,t_1
117755714Skris	sltu	AT,c_3,t_1
117855714Skris	daddu	t_2,AT
117955714Skris	daddu	c_1,t_2
118055714Skris	sltu	AT,c_1,t_2
118155714Skris	daddu	c_2,AT
118255714Skris	sd	c_3,64(a0)	/* r[8]=c3; */
118355714Skris
118455714Skris	dmultu	a_2,b_7		/* mul_add_c(a[2],b[7],c1,c2,c3); */
118555714Skris	mflo	t_1
118655714Skris	mfhi	t_2
118755714Skris	daddu	c_1,t_1
118855714Skris	sltu	AT,c_1,t_1
118955714Skris	daddu	t_2,AT
119055714Skris	daddu	c_2,t_2
119179998Skris	sltu	c_3,c_2,t_2
119255714Skris	dmultu	a_3,b_6		/* mul_add_c(a[3],b[6],c1,c2,c3); */
119355714Skris	mflo	t_1
119455714Skris	mfhi	t_2
119555714Skris	daddu	c_1,t_1
119655714Skris	sltu	AT,c_1,t_1
119755714Skris	daddu	t_2,AT
119855714Skris	daddu	c_2,t_2
119979998Skris	sltu	AT,c_2,t_2
120079998Skris	daddu	c_3,AT
120155714Skris	dmultu	a_4,b_5		/* mul_add_c(a[4],b[5],c1,c2,c3); */
120255714Skris	mflo	t_1
120355714Skris	mfhi	t_2
120455714Skris	daddu	c_1,t_1
120555714Skris	sltu	AT,c_1,t_1
120655714Skris	daddu	t_2,AT
120755714Skris	daddu	c_2,t_2
120855714Skris	sltu	AT,c_2,t_2
120955714Skris	daddu	c_3,AT
121055714Skris	dmultu	a_5,b_4		/* mul_add_c(a[5],b[4],c1,c2,c3); */
121155714Skris	mflo	t_1
121255714Skris	mfhi	t_2
121355714Skris	daddu	c_1,t_1
121455714Skris	sltu	AT,c_1,t_1
121555714Skris	daddu	t_2,AT
121655714Skris	daddu	c_2,t_2
121755714Skris	sltu	AT,c_2,t_2
121855714Skris	daddu	c_3,AT
121955714Skris	dmultu	a_6,b_3		/* mul_add_c(a[6],b[3],c1,c2,c3); */
122055714Skris	mflo	t_1
122155714Skris	mfhi	t_2
122255714Skris	daddu	c_1,t_1
122355714Skris	sltu	AT,c_1,t_1
122455714Skris	daddu	t_2,AT
122555714Skris	daddu	c_2,t_2
122655714Skris	sltu	AT,c_2,t_2
122755714Skris	daddu	c_3,AT
122855714Skris	dmultu	a_7,b_2		/* mul_add_c(a[7],b[2],c1,c2,c3); */
122955714Skris	mflo	t_1
123055714Skris	mfhi	t_2
123155714Skris	daddu	c_1,t_1
123255714Skris	sltu	AT,c_1,t_1
123355714Skris	daddu	t_2,AT
123455714Skris	daddu	c_2,t_2
123555714Skris	sltu	AT,c_2,t_2
123655714Skris	daddu	c_3,AT
123755714Skris	sd	c_1,72(a0)	/* r[9]=c1; */
123855714Skris
123955714Skris	dmultu	a_7,b_3		/* mul_add_c(a[7],b[3],c2,c3,c1); */
124055714Skris	mflo	t_1
124155714Skris	mfhi	t_2
124255714Skris	daddu	c_2,t_1
124355714Skris	sltu	AT,c_2,t_1
124455714Skris	daddu	t_2,AT
124555714Skris	daddu	c_3,t_2
124679998Skris	sltu	c_1,c_3,t_2
124755714Skris	dmultu	a_6,b_4		/* mul_add_c(a[6],b[4],c2,c3,c1); */
124855714Skris	mflo	t_1
124955714Skris	mfhi	t_2
125055714Skris	daddu	c_2,t_1
125155714Skris	sltu	AT,c_2,t_1
125255714Skris	daddu	t_2,AT
125355714Skris	daddu	c_3,t_2
125479998Skris	sltu	AT,c_3,t_2
125579998Skris	daddu	c_1,AT
125655714Skris	dmultu	a_5,b_5		/* mul_add_c(a[5],b[5],c2,c3,c1); */
125755714Skris	mflo	t_1
125855714Skris	mfhi	t_2
125955714Skris	daddu	c_2,t_1
126055714Skris	sltu	AT,c_2,t_1
126155714Skris	daddu	t_2,AT
126255714Skris	daddu	c_3,t_2
126355714Skris	sltu	AT,c_3,t_2
126455714Skris	daddu	c_1,AT
126555714Skris	dmultu	a_4,b_6		/* mul_add_c(a[4],b[6],c2,c3,c1); */
126655714Skris	mflo	t_1
126755714Skris	mfhi	t_2
126855714Skris	daddu	c_2,t_1
126955714Skris	sltu	AT,c_2,t_1
127055714Skris	daddu	t_2,AT
127155714Skris	daddu	c_3,t_2
127255714Skris	sltu	AT,c_3,t_2
127355714Skris	daddu	c_1,AT
127455714Skris	dmultu	a_3,b_7		/* mul_add_c(a[3],b[7],c2,c3,c1); */
127555714Skris	mflo	t_1
127655714Skris	mfhi	t_2
127755714Skris	daddu	c_2,t_1
127855714Skris	sltu	AT,c_2,t_1
127955714Skris	daddu	t_2,AT
128055714Skris	daddu	c_3,t_2
128155714Skris	sltu	AT,c_3,t_2
128255714Skris	daddu	c_1,AT
128355714Skris	sd	c_2,80(a0)	/* r[10]=c2; */
128455714Skris
128555714Skris	dmultu	a_4,b_7		/* mul_add_c(a[4],b[7],c3,c1,c2); */
128655714Skris	mflo	t_1
128755714Skris	mfhi	t_2
128855714Skris	daddu	c_3,t_1
128955714Skris	sltu	AT,c_3,t_1
129055714Skris	daddu	t_2,AT
129155714Skris	daddu	c_1,t_2
129279998Skris	sltu	c_2,c_1,t_2
129355714Skris	dmultu	a_5,b_6		/* mul_add_c(a[5],b[6],c3,c1,c2); */
129455714Skris	mflo	t_1
129555714Skris	mfhi	t_2
129655714Skris	daddu	c_3,t_1
129755714Skris	sltu	AT,c_3,t_1
129855714Skris	daddu	t_2,AT
129955714Skris	daddu	c_1,t_2
130079998Skris	sltu	AT,c_1,t_2
130179998Skris	daddu	c_2,AT
130255714Skris	dmultu	a_6,b_5		/* mul_add_c(a[6],b[5],c3,c1,c2); */
130355714Skris	mflo	t_1
130455714Skris	mfhi	t_2
130555714Skris	daddu	c_3,t_1
130655714Skris	sltu	AT,c_3,t_1
130755714Skris	daddu	t_2,AT
130855714Skris	daddu	c_1,t_2
130955714Skris	sltu	AT,c_1,t_2
131055714Skris	daddu	c_2,AT
131155714Skris	dmultu	a_7,b_4		/* mul_add_c(a[7],b[4],c3,c1,c2); */
131255714Skris	mflo	t_1
131355714Skris	mfhi	t_2
131455714Skris	daddu	c_3,t_1
131555714Skris	sltu	AT,c_3,t_1
131655714Skris	daddu	t_2,AT
131755714Skris	daddu	c_1,t_2
131855714Skris	sltu	AT,c_1,t_2
131955714Skris	daddu	c_2,AT
132055714Skris	sd	c_3,88(a0)	/* r[11]=c3; */
132155714Skris
132255714Skris	dmultu	a_7,b_5		/* mul_add_c(a[7],b[5],c1,c2,c3); */
132355714Skris	mflo	t_1
132455714Skris	mfhi	t_2
132555714Skris	daddu	c_1,t_1
132655714Skris	sltu	AT,c_1,t_1
132755714Skris	daddu	t_2,AT
132855714Skris	daddu	c_2,t_2
132979998Skris	sltu	c_3,c_2,t_2
133055714Skris	dmultu	a_6,b_6		/* mul_add_c(a[6],b[6],c1,c2,c3); */
133155714Skris	mflo	t_1
133255714Skris	mfhi	t_2
133355714Skris	daddu	c_1,t_1
133455714Skris	sltu	AT,c_1,t_1
133555714Skris	daddu	t_2,AT
133655714Skris	daddu	c_2,t_2
133779998Skris	sltu	AT,c_2,t_2
133879998Skris	daddu	c_3,AT
133955714Skris	dmultu	a_5,b_7		/* mul_add_c(a[5],b[7],c1,c2,c3); */
134055714Skris	mflo	t_1
134155714Skris	mfhi	t_2
134255714Skris	daddu	c_1,t_1
134355714Skris	sltu	AT,c_1,t_1
134455714Skris	daddu	t_2,AT
134555714Skris	daddu	c_2,t_2
134655714Skris	sltu	AT,c_2,t_2
134755714Skris	daddu	c_3,AT
134855714Skris	sd	c_1,96(a0)	/* r[12]=c1; */
134955714Skris
135055714Skris	dmultu	a_6,b_7		/* mul_add_c(a[6],b[7],c2,c3,c1); */
135155714Skris	mflo	t_1
135255714Skris	mfhi	t_2
135355714Skris	daddu	c_2,t_1
135455714Skris	sltu	AT,c_2,t_1
135555714Skris	daddu	t_2,AT
135655714Skris	daddu	c_3,t_2
135779998Skris	sltu	c_1,c_3,t_2
135855714Skris	dmultu	a_7,b_6		/* mul_add_c(a[7],b[6],c2,c3,c1); */
135955714Skris	mflo	t_1
136055714Skris	mfhi	t_2
136155714Skris	daddu	c_2,t_1
136255714Skris	sltu	AT,c_2,t_1
136355714Skris	daddu	t_2,AT
136455714Skris	daddu	c_3,t_2
136579998Skris	sltu	AT,c_3,t_2
136679998Skris	daddu	c_1,AT
136755714Skris	sd	c_2,104(a0)	/* r[13]=c2; */
136855714Skris
136955714Skris	dmultu	a_7,b_7		/* mul_add_c(a[7],b[7],c3,c1,c2); */
137055714Skris	ld	s0,0(sp)
137155714Skris	ld	s1,8(sp)
137255714Skris	ld	s2,16(sp)
137355714Skris	ld	s3,24(sp)
137455714Skris	ld	s4,32(sp)
137555714Skris	ld	s5,40(sp)
137655714Skris	mflo	t_1
137755714Skris	mfhi	t_2
137855714Skris	daddu	c_3,t_1
137955714Skris	sltu	AT,c_3,t_1
138055714Skris	daddu	t_2,AT
138155714Skris	daddu	c_1,t_2
138255714Skris	sd	c_3,112(a0)	/* r[14]=c3; */
138355714Skris	sd	c_1,120(a0)	/* r[15]=c1; */
138455714Skris
138555714Skris	PTR_ADD	sp,FRAME_SIZE
138655714Skris
138755714Skris	jr	ra
138855714SkrisEND(bn_mul_comba8)
138955714Skris
139055714Skris.align	5
139155714SkrisLEAF(bn_mul_comba4)
139255714Skris	.set	reorder
139355714Skris	ld	a_0,0(a1)
139455714Skris	ld	b_0,0(a2)
139555714Skris	ld	a_1,8(a1)
139655714Skris	ld	a_2,16(a1)
139755714Skris	dmultu	a_0,b_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
139855714Skris	ld	a_3,24(a1)
139955714Skris	ld	b_1,8(a2)
140055714Skris	ld	b_2,16(a2)
140155714Skris	ld	b_3,24(a2)
140255714Skris	mflo	c_1
140355714Skris	mfhi	c_2
140455714Skris	sd	c_1,0(a0)
140555714Skris
140655714Skris	dmultu	a_0,b_1		/* mul_add_c(a[0],b[1],c2,c3,c1); */
140755714Skris	mflo	t_1
140855714Skris	mfhi	t_2
140955714Skris	daddu	c_2,t_1
141055714Skris	sltu	AT,c_2,t_1
141155714Skris	daddu	c_3,t_2,AT
141255714Skris	dmultu	a_1,b_0		/* mul_add_c(a[1],b[0],c2,c3,c1); */
141355714Skris	mflo	t_1
141455714Skris	mfhi	t_2
141555714Skris	daddu	c_2,t_1
141655714Skris	sltu	AT,c_2,t_1
141755714Skris	daddu	t_2,AT
141855714Skris	daddu	c_3,t_2
141955714Skris	sltu	c_1,c_3,t_2
142055714Skris	sd	c_2,8(a0)
142155714Skris
142255714Skris	dmultu	a_2,b_0		/* mul_add_c(a[2],b[0],c3,c1,c2); */
142355714Skris	mflo	t_1
142455714Skris	mfhi	t_2
142555714Skris	daddu	c_3,t_1
142655714Skris	sltu	AT,c_3,t_1
142755714Skris	daddu	t_2,AT
142855714Skris	daddu	c_1,t_2
142955714Skris	dmultu	a_1,b_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
143055714Skris	mflo	t_1
143155714Skris	mfhi	t_2
143255714Skris	daddu	c_3,t_1
143355714Skris	sltu	AT,c_3,t_1
143455714Skris	daddu	t_2,AT
143555714Skris	daddu	c_1,t_2
143655714Skris	sltu	c_2,c_1,t_2
143755714Skris	dmultu	a_0,b_2		/* mul_add_c(a[0],b[2],c3,c1,c2); */
143855714Skris	mflo	t_1
143955714Skris	mfhi	t_2
144055714Skris	daddu	c_3,t_1
144155714Skris	sltu	AT,c_3,t_1
144255714Skris	daddu	t_2,AT
144355714Skris	daddu	c_1,t_2
144455714Skris	sltu	AT,c_1,t_2
144555714Skris	daddu	c_2,AT
144655714Skris	sd	c_3,16(a0)
144755714Skris
144855714Skris	dmultu	a_0,b_3		/* mul_add_c(a[0],b[3],c1,c2,c3); */
144955714Skris	mflo	t_1
145055714Skris	mfhi	t_2
145155714Skris	daddu	c_1,t_1
145255714Skris	sltu	AT,c_1,t_1
145355714Skris	daddu	t_2,AT
145455714Skris	daddu	c_2,t_2
145579998Skris	sltu	c_3,c_2,t_2
145655714Skris	dmultu	a_1,b_2		/* mul_add_c(a[1],b[2],c1,c2,c3); */
145755714Skris	mflo	t_1
145855714Skris	mfhi	t_2
145955714Skris	daddu	c_1,t_1
146055714Skris	sltu	AT,c_1,t_1
146155714Skris	daddu	t_2,AT
146255714Skris	daddu	c_2,t_2
146379998Skris	sltu	AT,c_2,t_2
146479998Skris	daddu	c_3,AT
146555714Skris	dmultu	a_2,b_1		/* mul_add_c(a[2],b[1],c1,c2,c3); */
146655714Skris	mflo	t_1
146755714Skris	mfhi	t_2
146855714Skris	daddu	c_1,t_1
146955714Skris	sltu	AT,c_1,t_1
147055714Skris	daddu	t_2,AT
147155714Skris	daddu	c_2,t_2
147255714Skris	sltu	AT,c_2,t_2
147355714Skris	daddu	c_3,AT
147455714Skris	dmultu	a_3,b_0		/* mul_add_c(a[3],b[0],c1,c2,c3); */
147555714Skris	mflo	t_1
147655714Skris	mfhi	t_2
147755714Skris	daddu	c_1,t_1
147855714Skris	sltu	AT,c_1,t_1
147955714Skris	daddu	t_2,AT
148055714Skris	daddu	c_2,t_2
148155714Skris	sltu	AT,c_2,t_2
148255714Skris	daddu	c_3,AT
148355714Skris	sd	c_1,24(a0)
148455714Skris
148555714Skris	dmultu	a_3,b_1		/* mul_add_c(a[3],b[1],c2,c3,c1); */
148655714Skris	mflo	t_1
148755714Skris	mfhi	t_2
148855714Skris	daddu	c_2,t_1
148955714Skris	sltu	AT,c_2,t_1
149055714Skris	daddu	t_2,AT
149155714Skris	daddu	c_3,t_2
149279998Skris	sltu	c_1,c_3,t_2
149355714Skris	dmultu	a_2,b_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
149455714Skris	mflo	t_1
149555714Skris	mfhi	t_2
149655714Skris	daddu	c_2,t_1
149755714Skris	sltu	AT,c_2,t_1
149855714Skris	daddu	t_2,AT
149955714Skris	daddu	c_3,t_2
150079998Skris	sltu	AT,c_3,t_2
150179998Skris	daddu	c_1,AT
150255714Skris	dmultu	a_1,b_3		/* mul_add_c(a[1],b[3],c2,c3,c1); */
150355714Skris	mflo	t_1
150455714Skris	mfhi	t_2
150555714Skris	daddu	c_2,t_1
150655714Skris	sltu	AT,c_2,t_1
150755714Skris	daddu	t_2,AT
150855714Skris	daddu	c_3,t_2
150955714Skris	sltu	AT,c_3,t_2
151055714Skris	daddu	c_1,AT
151155714Skris	sd	c_2,32(a0)
151255714Skris
151355714Skris	dmultu	a_2,b_3		/* mul_add_c(a[2],b[3],c3,c1,c2); */
151455714Skris	mflo	t_1
151555714Skris	mfhi	t_2
151655714Skris	daddu	c_3,t_1
151755714Skris	sltu	AT,c_3,t_1
151855714Skris	daddu	t_2,AT
151955714Skris	daddu	c_1,t_2
152079998Skris	sltu	c_2,c_1,t_2
152155714Skris	dmultu	a_3,b_2		/* mul_add_c(a[3],b[2],c3,c1,c2); */
152255714Skris	mflo	t_1
152355714Skris	mfhi	t_2
152455714Skris	daddu	c_3,t_1
152555714Skris	sltu	AT,c_3,t_1
152655714Skris	daddu	t_2,AT
152755714Skris	daddu	c_1,t_2
152879998Skris	sltu	AT,c_1,t_2
152979998Skris	daddu	c_2,AT
153055714Skris	sd	c_3,40(a0)
153155714Skris
153255714Skris	dmultu	a_3,b_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
153355714Skris	mflo	t_1
153455714Skris	mfhi	t_2
153555714Skris	daddu	c_1,t_1
153655714Skris	sltu	AT,c_1,t_1
153755714Skris	daddu	t_2,AT
153855714Skris	daddu	c_2,t_2
153955714Skris	sd	c_1,48(a0)
154055714Skris	sd	c_2,56(a0)
154155714Skris
154255714Skris	jr	ra
154355714SkrisEND(bn_mul_comba4)
154455714Skris
154555714Skris#undef	a_4
154655714Skris#undef	a_5
154755714Skris#undef	a_6
154855714Skris#undef	a_7
154955714Skris#define	a_4	b_0
155055714Skris#define	a_5	b_1
155155714Skris#define	a_6	b_2
155255714Skris#define	a_7	b_3
155355714Skris
155455714Skris.align	5
155555714SkrisLEAF(bn_sqr_comba8)
155655714Skris	.set	reorder
155755714Skris	ld	a_0,0(a1)
155855714Skris	ld	a_1,8(a1)
155955714Skris	ld	a_2,16(a1)
156055714Skris	ld	a_3,24(a1)
156155714Skris
156255714Skris	dmultu	a_0,a_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
156355714Skris	ld	a_4,32(a1)
156455714Skris	ld	a_5,40(a1)
156555714Skris	ld	a_6,48(a1)
156655714Skris	ld	a_7,56(a1)
156755714Skris	mflo	c_1
156855714Skris	mfhi	c_2
156955714Skris	sd	c_1,0(a0)
157055714Skris
157155714Skris	dmultu	a_0,a_1		/* mul_add_c2(a[0],b[1],c2,c3,c1); */
157255714Skris	mflo	t_1
157355714Skris	mfhi	t_2
157479998Skris	slt	c_1,t_2,zero
157579998Skris	dsll	t_2,1
157679998Skris	slt	a2,t_1,zero
157779998Skris	daddu	t_2,a2
157879998Skris	dsll	t_1,1
157955714Skris	daddu	c_2,t_1
158055714Skris	sltu	AT,c_2,t_1
158155714Skris	daddu	c_3,t_2,AT
158255714Skris	sd	c_2,8(a0)
158355714Skris
158455714Skris	dmultu	a_2,a_0		/* mul_add_c2(a[2],b[0],c3,c1,c2); */
158555714Skris	mflo	t_1
158655714Skris	mfhi	t_2
158755714Skris	daddu	c_3,t_1
158855714Skris	sltu	AT,c_3,t_1
1589277195Sdelphij	daddu	c_3,t_1
1590277195Sdelphij	daddu	AT,t_2
1591277195Sdelphij	sltu	t_1,c_3,t_1
1592277195Sdelphij	daddu	c_1,AT
1593277195Sdelphij	daddu	t_2,t_1
1594277195Sdelphij	sltu	c_2,c_1,AT
159555714Skris	daddu	c_1,t_2
1596277195Sdelphij	sltu	t_2,c_1,t_2
1597277195Sdelphij	daddu	c_2,t_2
159855714Skris	dmultu	a_1,a_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
159955714Skris	mflo	t_1
160055714Skris	mfhi	t_2
160155714Skris	daddu	c_3,t_1
160255714Skris	sltu	AT,c_3,t_1
160355714Skris	daddu	t_2,AT
160455714Skris	daddu	c_1,t_2
160555714Skris	sltu	AT,c_1,t_2
160655714Skris	daddu	c_2,AT
160755714Skris	sd	c_3,16(a0)
160855714Skris
160955714Skris	dmultu	a_0,a_3		/* mul_add_c2(a[0],b[3],c1,c2,c3); */
161055714Skris	mflo	t_1
161155714Skris	mfhi	t_2
161255714Skris	daddu	c_1,t_1
161355714Skris	sltu	AT,c_1,t_1
1614277195Sdelphij	daddu	c_1,t_1
1615277195Sdelphij	daddu	AT,t_2
1616277195Sdelphij	sltu	t_1,c_1,t_1
1617277195Sdelphij	daddu	c_2,AT
1618277195Sdelphij	daddu	t_2,t_1
1619277195Sdelphij	sltu	c_3,c_2,AT
162055714Skris	daddu	c_2,t_2
1621277195Sdelphij	sltu	t_2,c_2,t_2
1622277195Sdelphij	daddu	c_3,t_2
162355714Skris	dmultu	a_1,a_2		/* mul_add_c2(a[1],b[2],c1,c2,c3); */
162455714Skris	mflo	t_1
162555714Skris	mfhi	t_2
162655714Skris	daddu	c_1,t_1
162755714Skris	sltu	AT,c_1,t_1
1628277195Sdelphij	daddu	c_1,t_1
1629277195Sdelphij	daddu	AT,t_2
1630277195Sdelphij	sltu	t_1,c_1,t_1
1631277195Sdelphij	daddu	c_2,AT
1632277195Sdelphij	daddu	t_2,t_1
1633277195Sdelphij	sltu	AT,c_2,AT
163455714Skris	daddu	c_2,t_2
163555714Skris	daddu	c_3,AT
1636277195Sdelphij	sltu	t_2,c_2,t_2
1637277195Sdelphij	daddu	c_3,t_2
163855714Skris	sd	c_1,24(a0)
163955714Skris
164055714Skris	dmultu	a_4,a_0		/* mul_add_c2(a[4],b[0],c2,c3,c1); */
164155714Skris	mflo	t_1
164255714Skris	mfhi	t_2
164355714Skris	daddu	c_2,t_1
164455714Skris	sltu	AT,c_2,t_1
1645277195Sdelphij	daddu	c_2,t_1
1646277195Sdelphij	daddu	AT,t_2
1647277195Sdelphij	sltu	t_1,c_2,t_1
1648277195Sdelphij	daddu	c_3,AT
1649277195Sdelphij	daddu	t_2,t_1
1650277195Sdelphij	sltu	c_1,c_3,AT
165155714Skris	daddu	c_3,t_2
1652277195Sdelphij	sltu	t_2,c_3,t_2
1653277195Sdelphij	daddu	c_1,t_2
165455714Skris	dmultu	a_3,a_1		/* mul_add_c2(a[3],b[1],c2,c3,c1); */
165555714Skris	mflo	t_1
165655714Skris	mfhi	t_2
165755714Skris	daddu	c_2,t_1
165855714Skris	sltu	AT,c_2,t_1
1659277195Sdelphij	daddu	c_2,t_1
1660277195Sdelphij	daddu	AT,t_2
1661277195Sdelphij	sltu	t_1,c_2,t_1
1662277195Sdelphij	daddu	c_3,AT
1663277195Sdelphij	daddu	t_2,t_1
1664277195Sdelphij	sltu	AT,c_3,AT
166555714Skris	daddu	c_3,t_2
166655714Skris	daddu	c_1,AT
1667277195Sdelphij	sltu	t_2,c_3,t_2
1668277195Sdelphij	daddu	c_1,t_2
166955714Skris	dmultu	a_2,a_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
167055714Skris	mflo	t_1
167155714Skris	mfhi	t_2
167255714Skris	daddu	c_2,t_1
167355714Skris	sltu	AT,c_2,t_1
167455714Skris	daddu	t_2,AT
167555714Skris	daddu	c_3,t_2
167655714Skris	sltu	AT,c_3,t_2
167755714Skris	daddu	c_1,AT
167855714Skris	sd	c_2,32(a0)
167955714Skris
168055714Skris	dmultu	a_0,a_5		/* mul_add_c2(a[0],b[5],c3,c1,c2); */
168155714Skris	mflo	t_1
168255714Skris	mfhi	t_2
168355714Skris	daddu	c_3,t_1
168455714Skris	sltu	AT,c_3,t_1
1685277195Sdelphij	daddu	c_3,t_1
1686277195Sdelphij	daddu	AT,t_2
1687277195Sdelphij	sltu	t_1,c_3,t_1
1688277195Sdelphij	daddu	c_1,AT
1689277195Sdelphij	daddu	t_2,t_1
1690277195Sdelphij	sltu	c_2,c_1,AT
169155714Skris	daddu	c_1,t_2
1692277195Sdelphij	sltu	t_2,c_1,t_2
1693277195Sdelphij	daddu	c_2,t_2
169455714Skris	dmultu	a_1,a_4		/* mul_add_c2(a[1],b[4],c3,c1,c2); */
169555714Skris	mflo	t_1
169655714Skris	mfhi	t_2
169755714Skris	daddu	c_3,t_1
169855714Skris	sltu	AT,c_3,t_1
1699277195Sdelphij	daddu	c_3,t_1
1700277195Sdelphij	daddu	AT,t_2
1701277195Sdelphij	sltu	t_1,c_3,t_1
1702277195Sdelphij	daddu	c_1,AT
1703277195Sdelphij	daddu	t_2,t_1
1704277195Sdelphij	sltu	AT,c_1,AT
170555714Skris	daddu	c_1,t_2
170655714Skris	daddu	c_2,AT
1707277195Sdelphij	sltu	t_2,c_1,t_2
1708277195Sdelphij	daddu	c_2,t_2
170955714Skris	dmultu	a_2,a_3		/* mul_add_c2(a[2],b[3],c3,c1,c2); */
171055714Skris	mflo	t_1
171155714Skris	mfhi	t_2
171255714Skris	daddu	c_3,t_1
171355714Skris	sltu	AT,c_3,t_1
1714277195Sdelphij	daddu	c_3,t_1
1715277195Sdelphij	daddu	AT,t_2
1716277195Sdelphij	sltu	t_1,c_3,t_1
1717277195Sdelphij	daddu	c_1,AT
1718277195Sdelphij	daddu	t_2,t_1
1719277195Sdelphij	sltu	AT,c_1,AT
172055714Skris	daddu	c_1,t_2
172155714Skris	daddu	c_2,AT
1722277195Sdelphij	sltu	t_2,c_1,t_2
1723277195Sdelphij	daddu	c_2,t_2
172455714Skris	sd	c_3,40(a0)
172555714Skris
172655714Skris	dmultu	a_6,a_0		/* mul_add_c2(a[6],b[0],c1,c2,c3); */
172755714Skris	mflo	t_1
172855714Skris	mfhi	t_2
172955714Skris	daddu	c_1,t_1
173055714Skris	sltu	AT,c_1,t_1
1731277195Sdelphij	daddu	c_1,t_1
1732277195Sdelphij	daddu	AT,t_2
1733277195Sdelphij	sltu	t_1,c_1,t_1
1734277195Sdelphij	daddu	c_2,AT
1735277195Sdelphij	daddu	t_2,t_1
1736277195Sdelphij	sltu	c_3,c_2,AT
173755714Skris	daddu	c_2,t_2
1738277195Sdelphij	sltu	t_2,c_2,t_2
1739277195Sdelphij	daddu	c_3,t_2
174055714Skris	dmultu	a_5,a_1		/* mul_add_c2(a[5],b[1],c1,c2,c3); */
174155714Skris	mflo	t_1
174255714Skris	mfhi	t_2
174355714Skris	daddu	c_1,t_1
174455714Skris	sltu	AT,c_1,t_1
1745277195Sdelphij	daddu	c_1,t_1
1746277195Sdelphij	daddu	AT,t_2
1747277195Sdelphij	sltu	t_1,c_1,t_1
1748277195Sdelphij	daddu	c_2,AT
1749277195Sdelphij	daddu	t_2,t_1
1750277195Sdelphij	sltu	AT,c_2,AT
175155714Skris	daddu	c_2,t_2
175255714Skris	daddu	c_3,AT
1753277195Sdelphij	sltu	t_2,c_2,t_2
1754277195Sdelphij	daddu	c_3,t_2
175555714Skris	dmultu	a_4,a_2		/* mul_add_c2(a[4],b[2],c1,c2,c3); */
175655714Skris	mflo	t_1
175755714Skris	mfhi	t_2
175855714Skris	daddu	c_1,t_1
175955714Skris	sltu	AT,c_1,t_1
1760277195Sdelphij	daddu	c_1,t_1
1761277195Sdelphij	daddu	AT,t_2
1762277195Sdelphij	sltu	t_1,c_1,t_1
1763277195Sdelphij	daddu	c_2,AT
1764277195Sdelphij	daddu	t_2,t_1
1765277195Sdelphij	sltu	AT,c_2,AT
176655714Skris	daddu	c_2,t_2
176755714Skris	daddu	c_3,AT
1768277195Sdelphij	sltu	t_2,c_2,t_2
1769277195Sdelphij	daddu	c_3,t_2
177055714Skris	dmultu	a_3,a_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
177155714Skris	mflo	t_1
177255714Skris	mfhi	t_2
177355714Skris	daddu	c_1,t_1
177455714Skris	sltu	AT,c_1,t_1
177555714Skris	daddu	t_2,AT
177655714Skris	daddu	c_2,t_2
177755714Skris	sltu	AT,c_2,t_2
177855714Skris	daddu	c_3,AT
177955714Skris	sd	c_1,48(a0)
178055714Skris
178155714Skris	dmultu	a_0,a_7		/* mul_add_c2(a[0],b[7],c2,c3,c1); */
178255714Skris	mflo	t_1
178355714Skris	mfhi	t_2
178455714Skris	daddu	c_2,t_1
178555714Skris	sltu	AT,c_2,t_1
1786277195Sdelphij	daddu	c_2,t_1
1787277195Sdelphij	daddu	AT,t_2
1788277195Sdelphij	sltu	t_1,c_2,t_1
1789277195Sdelphij	daddu	c_3,AT
1790277195Sdelphij	daddu	t_2,t_1
1791277195Sdelphij	sltu	c_1,c_3,AT
179255714Skris	daddu	c_3,t_2
1793277195Sdelphij	sltu	t_2,c_3,t_2
1794277195Sdelphij	daddu	c_1,t_2
179555714Skris	dmultu	a_1,a_6		/* mul_add_c2(a[1],b[6],c2,c3,c1); */
179655714Skris	mflo	t_1
179755714Skris	mfhi	t_2
179855714Skris	daddu	c_2,t_1
179955714Skris	sltu	AT,c_2,t_1
1800277195Sdelphij	daddu	c_2,t_1
1801277195Sdelphij	daddu	AT,t_2
1802277195Sdelphij	sltu	t_1,c_2,t_1
1803277195Sdelphij	daddu	c_3,AT
1804277195Sdelphij	daddu	t_2,t_1
1805277195Sdelphij	sltu	AT,c_3,AT
180655714Skris	daddu	c_3,t_2
180755714Skris	daddu	c_1,AT
1808277195Sdelphij	sltu	t_2,c_3,t_2
1809277195Sdelphij	daddu	c_1,t_2
181055714Skris	dmultu	a_2,a_5		/* mul_add_c2(a[2],b[5],c2,c3,c1); */
181155714Skris	mflo	t_1
181255714Skris	mfhi	t_2
181355714Skris	daddu	c_2,t_1
181455714Skris	sltu	AT,c_2,t_1
1815277195Sdelphij	daddu	c_2,t_1
1816277195Sdelphij	daddu	AT,t_2
1817277195Sdelphij	sltu	t_1,c_2,t_1
1818277195Sdelphij	daddu	c_3,AT
1819277195Sdelphij	daddu	t_2,t_1
1820277195Sdelphij	sltu	AT,c_3,AT
182155714Skris	daddu	c_3,t_2
182255714Skris	daddu	c_1,AT
1823277195Sdelphij	sltu	t_2,c_3,t_2
1824277195Sdelphij	daddu	c_1,t_2
182555714Skris	dmultu	a_3,a_4		/* mul_add_c2(a[3],b[4],c2,c3,c1); */
182655714Skris	mflo	t_1
182755714Skris	mfhi	t_2
182855714Skris	daddu	c_2,t_1
182955714Skris	sltu	AT,c_2,t_1
1830277195Sdelphij	daddu	c_2,t_1
1831277195Sdelphij	daddu	AT,t_2
1832277195Sdelphij	sltu	t_1,c_2,t_1
1833277195Sdelphij	daddu	c_3,AT
1834277195Sdelphij	daddu	t_2,t_1
1835277195Sdelphij	sltu	AT,c_3,AT
183655714Skris	daddu	c_3,t_2
183755714Skris	daddu	c_1,AT
1838277195Sdelphij	sltu	t_2,c_3,t_2
1839277195Sdelphij	daddu	c_1,t_2
184055714Skris	sd	c_2,56(a0)
184155714Skris
184255714Skris	dmultu	a_7,a_1		/* mul_add_c2(a[7],b[1],c3,c1,c2); */
184355714Skris	mflo	t_1
184455714Skris	mfhi	t_2
184555714Skris	daddu	c_3,t_1
184655714Skris	sltu	AT,c_3,t_1
1847277195Sdelphij	daddu	c_3,t_1
1848277195Sdelphij	daddu	AT,t_2
1849277195Sdelphij	sltu	t_1,c_3,t_1
1850277195Sdelphij	daddu	c_1,AT
1851277195Sdelphij	daddu	t_2,t_1
1852277195Sdelphij	sltu	c_2,c_1,AT
185355714Skris	daddu	c_1,t_2
1854277195Sdelphij	sltu	t_2,c_1,t_2
1855277195Sdelphij	daddu	c_2,t_2
185655714Skris	dmultu	a_6,a_2		/* mul_add_c2(a[6],b[2],c3,c1,c2); */
185755714Skris	mflo	t_1
185855714Skris	mfhi	t_2
185955714Skris	daddu	c_3,t_1
186055714Skris	sltu	AT,c_3,t_1
1861277195Sdelphij	daddu	c_3,t_1
1862277195Sdelphij	daddu	AT,t_2
1863277195Sdelphij	sltu	t_1,c_3,t_1
1864277195Sdelphij	daddu	c_1,AT
1865277195Sdelphij	daddu	t_2,t_1
1866277195Sdelphij	sltu	AT,c_1,AT
186755714Skris	daddu	c_1,t_2
186855714Skris	daddu	c_2,AT
1869277195Sdelphij	sltu	t_2,c_1,t_2
1870277195Sdelphij	daddu	c_2,t_2
187155714Skris	dmultu	a_5,a_3		/* mul_add_c2(a[5],b[3],c3,c1,c2); */
187255714Skris	mflo	t_1
187355714Skris	mfhi	t_2
187455714Skris	daddu	c_3,t_1
187555714Skris	sltu	AT,c_3,t_1
1876277195Sdelphij	daddu	c_3,t_1
1877277195Sdelphij	daddu	AT,t_2
1878277195Sdelphij	sltu	t_1,c_3,t_1
1879277195Sdelphij	daddu	c_1,AT
1880277195Sdelphij	daddu	t_2,t_1
1881277195Sdelphij	sltu	AT,c_1,AT
188255714Skris	daddu	c_1,t_2
188355714Skris	daddu	c_2,AT
1884277195Sdelphij	sltu	t_2,c_1,t_2
1885277195Sdelphij	daddu	c_2,t_2
188655714Skris	dmultu	a_4,a_4		/* mul_add_c(a[4],b[4],c3,c1,c2); */
188755714Skris	mflo	t_1
188855714Skris	mfhi	t_2
188955714Skris	daddu	c_3,t_1
189055714Skris	sltu	AT,c_3,t_1
189155714Skris	daddu	t_2,AT
189255714Skris	daddu	c_1,t_2
189355714Skris	sltu	AT,c_1,t_2
189455714Skris	daddu	c_2,AT
189555714Skris	sd	c_3,64(a0)
189655714Skris
189755714Skris	dmultu	a_2,a_7		/* mul_add_c2(a[2],b[7],c1,c2,c3); */
189855714Skris	mflo	t_1
189955714Skris	mfhi	t_2
190055714Skris	daddu	c_1,t_1
190155714Skris	sltu	AT,c_1,t_1
1902277195Sdelphij	daddu	c_1,t_1
1903277195Sdelphij	daddu	AT,t_2
1904277195Sdelphij	sltu	t_1,c_1,t_1
1905277195Sdelphij	daddu	c_2,AT
1906277195Sdelphij	daddu	t_2,t_1
1907277195Sdelphij	sltu	c_3,c_2,AT
190855714Skris	daddu	c_2,t_2
1909277195Sdelphij	sltu	t_2,c_2,t_2
1910277195Sdelphij	daddu	c_3,t_2
191155714Skris	dmultu	a_3,a_6		/* mul_add_c2(a[3],b[6],c1,c2,c3); */
191255714Skris	mflo	t_1
191355714Skris	mfhi	t_2
191455714Skris	daddu	c_1,t_1
191555714Skris	sltu	AT,c_1,t_1
1916277195Sdelphij	daddu	c_1,t_1
1917277195Sdelphij	daddu	AT,t_2
1918277195Sdelphij	sltu	t_1,c_1,t_1
1919277195Sdelphij	daddu	c_2,AT
1920277195Sdelphij	daddu	t_2,t_1
1921277195Sdelphij	sltu	AT,c_2,AT
192255714Skris	daddu	c_2,t_2
192355714Skris	daddu	c_3,AT
1924277195Sdelphij	sltu	t_2,c_2,t_2
1925277195Sdelphij	daddu	c_3,t_2
192655714Skris	dmultu	a_4,a_5		/* mul_add_c2(a[4],b[5],c1,c2,c3); */
192755714Skris	mflo	t_1
192855714Skris	mfhi	t_2
192955714Skris	daddu	c_1,t_1
193055714Skris	sltu	AT,c_1,t_1
1931277195Sdelphij	daddu	c_1,t_1
1932277195Sdelphij	daddu	AT,t_2
1933277195Sdelphij	sltu	t_1,c_1,t_1
1934277195Sdelphij	daddu	c_2,AT
1935277195Sdelphij	daddu	t_2,t_1
1936277195Sdelphij	sltu	AT,c_2,AT
193755714Skris	daddu	c_2,t_2
193855714Skris	daddu	c_3,AT
1939277195Sdelphij	sltu	t_2,c_2,t_2
1940277195Sdelphij	daddu	c_3,t_2
194155714Skris	sd	c_1,72(a0)
194255714Skris
194355714Skris	dmultu	a_7,a_3		/* mul_add_c2(a[7],b[3],c2,c3,c1); */
194455714Skris	mflo	t_1
194555714Skris	mfhi	t_2
194655714Skris	daddu	c_2,t_1
194755714Skris	sltu	AT,c_2,t_1
1948277195Sdelphij	daddu	c_2,t_1
1949277195Sdelphij	daddu	AT,t_2
1950277195Sdelphij	sltu	t_1,c_2,t_1
1951277195Sdelphij	daddu	c_3,AT
1952277195Sdelphij	daddu	t_2,t_1
1953277195Sdelphij	sltu	c_1,c_3,AT
195455714Skris	daddu	c_3,t_2
1955277195Sdelphij	sltu	t_2,c_3,t_2
1956277195Sdelphij	daddu	c_1,t_2
195755714Skris	dmultu	a_6,a_4		/* mul_add_c2(a[6],b[4],c2,c3,c1); */
195855714Skris	mflo	t_1
195955714Skris	mfhi	t_2
196055714Skris	daddu	c_2,t_1
196155714Skris	sltu	AT,c_2,t_1
1962277195Sdelphij	daddu	c_2,t_1
1963277195Sdelphij	daddu	AT,t_2
1964277195Sdelphij	sltu	t_1,c_2,t_1
1965277195Sdelphij	daddu	c_3,AT
1966277195Sdelphij	daddu	t_2,t_1
1967277195Sdelphij	sltu	AT,c_3,AT
196855714Skris	daddu	c_3,t_2
196955714Skris	daddu	c_1,AT
1970277195Sdelphij	sltu	t_2,c_3,t_2
1971277195Sdelphij	daddu	c_1,t_2
197255714Skris	dmultu	a_5,a_5		/* mul_add_c(a[5],b[5],c2,c3,c1); */
197355714Skris	mflo	t_1
197455714Skris	mfhi	t_2
197555714Skris	daddu	c_2,t_1
197655714Skris	sltu	AT,c_2,t_1
197755714Skris	daddu	t_2,AT
197855714Skris	daddu	c_3,t_2
197955714Skris	sltu	AT,c_3,t_2
198055714Skris	daddu	c_1,AT
198155714Skris	sd	c_2,80(a0)
198255714Skris
198355714Skris	dmultu	a_4,a_7		/* mul_add_c2(a[4],b[7],c3,c1,c2); */
198455714Skris	mflo	t_1
198555714Skris	mfhi	t_2
198655714Skris	daddu	c_3,t_1
198755714Skris	sltu	AT,c_3,t_1
1988277195Sdelphij	daddu	c_3,t_1
1989277195Sdelphij	daddu	AT,t_2
1990277195Sdelphij	sltu	t_1,c_3,t_1
1991277195Sdelphij	daddu	c_1,AT
1992277195Sdelphij	daddu	t_2,t_1
1993277195Sdelphij	sltu	c_2,c_1,AT
199455714Skris	daddu	c_1,t_2
1995277195Sdelphij	sltu	t_2,c_1,t_2
1996277195Sdelphij	daddu	c_2,t_2
199755714Skris	dmultu	a_5,a_6		/* mul_add_c2(a[5],b[6],c3,c1,c2); */
199855714Skris	mflo	t_1
199955714Skris	mfhi	t_2
200055714Skris	daddu	c_3,t_1
200155714Skris	sltu	AT,c_3,t_1
2002277195Sdelphij	daddu	c_3,t_1
2003277195Sdelphij	daddu	AT,t_2
2004277195Sdelphij	sltu	t_1,c_3,t_1
2005277195Sdelphij	daddu	c_1,AT
2006277195Sdelphij	daddu	t_2,t_1
2007277195Sdelphij	sltu	AT,c_1,AT
200855714Skris	daddu	c_1,t_2
200955714Skris	daddu	c_2,AT
2010277195Sdelphij	sltu	t_2,c_1,t_2
2011277195Sdelphij	daddu	c_2,t_2
201255714Skris	sd	c_3,88(a0)
201355714Skris
201455714Skris	dmultu	a_7,a_5		/* mul_add_c2(a[7],b[5],c1,c2,c3); */
201555714Skris	mflo	t_1
201655714Skris	mfhi	t_2
201755714Skris	daddu	c_1,t_1
201855714Skris	sltu	AT,c_1,t_1
2019277195Sdelphij	daddu	c_1,t_1
2020277195Sdelphij	daddu	AT,t_2
2021277195Sdelphij	sltu	t_1,c_1,t_1
2022277195Sdelphij	daddu	c_2,AT
2023277195Sdelphij	daddu	t_2,t_1
2024277195Sdelphij	sltu	c_3,c_2,AT
202555714Skris	daddu	c_2,t_2
2026277195Sdelphij	sltu	t_2,c_2,t_2
2027277195Sdelphij	daddu	c_3,t_2
202855714Skris	dmultu	a_6,a_6		/* mul_add_c(a[6],b[6],c1,c2,c3); */
202955714Skris	mflo	t_1
203055714Skris	mfhi	t_2
203155714Skris	daddu	c_1,t_1
203255714Skris	sltu	AT,c_1,t_1
203355714Skris	daddu	t_2,AT
203455714Skris	daddu	c_2,t_2
203555714Skris	sltu	AT,c_2,t_2
203655714Skris	daddu	c_3,AT
203755714Skris	sd	c_1,96(a0)
203855714Skris
203955714Skris	dmultu	a_6,a_7		/* mul_add_c2(a[6],b[7],c2,c3,c1); */
204055714Skris	mflo	t_1
204155714Skris	mfhi	t_2
204255714Skris	daddu	c_2,t_1
204355714Skris	sltu	AT,c_2,t_1
2044277195Sdelphij	daddu	c_2,t_1
2045277195Sdelphij	daddu	AT,t_2
2046277195Sdelphij	sltu	t_1,c_2,t_1
2047277195Sdelphij	daddu	c_3,AT
2048277195Sdelphij	daddu	t_2,t_1
2049277195Sdelphij	sltu	c_1,c_3,AT
205055714Skris	daddu	c_3,t_2
2051277195Sdelphij	sltu	t_2,c_3,t_2
2052277195Sdelphij	daddu	c_1,t_2
205355714Skris	sd	c_2,104(a0)
205455714Skris
205555714Skris	dmultu	a_7,a_7		/* mul_add_c(a[7],b[7],c3,c1,c2); */
205655714Skris	mflo	t_1
205755714Skris	mfhi	t_2
205855714Skris	daddu	c_3,t_1
205955714Skris	sltu	AT,c_3,t_1
206055714Skris	daddu	t_2,AT
206155714Skris	daddu	c_1,t_2
206255714Skris	sd	c_3,112(a0)
206355714Skris	sd	c_1,120(a0)
206455714Skris
206555714Skris	jr	ra
206655714SkrisEND(bn_sqr_comba8)
206755714Skris
206855714Skris.align	5
206955714SkrisLEAF(bn_sqr_comba4)
207055714Skris	.set	reorder
207155714Skris	ld	a_0,0(a1)
207255714Skris	ld	a_1,8(a1)
2073277195Sdelphij	dmultu	a_0,a_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
207455714Skris	ld	a_2,16(a1)
207555714Skris	ld	a_3,24(a1)
207655714Skris	mflo	c_1
207755714Skris	mfhi	c_2
207855714Skris	sd	c_1,0(a0)
207955714Skris
208055714Skris	dmultu	a_0,a_1		/* mul_add_c2(a[0],b[1],c2,c3,c1); */
208155714Skris	mflo	t_1
208255714Skris	mfhi	t_2
208379998Skris	slt	c_1,t_2,zero
208479998Skris	dsll	t_2,1
208579998Skris	slt	a2,t_1,zero
208679998Skris	daddu	t_2,a2
208779998Skris	dsll	t_1,1
208855714Skris	daddu	c_2,t_1
208955714Skris	sltu	AT,c_2,t_1
209055714Skris	daddu	c_3,t_2,AT
209155714Skris	sd	c_2,8(a0)
209255714Skris
209355714Skris	dmultu	a_2,a_0		/* mul_add_c2(a[2],b[0],c3,c1,c2); */
209455714Skris	mflo	t_1
209555714Skris	mfhi	t_2
209655714Skris	daddu	c_3,t_1
209755714Skris	sltu	AT,c_3,t_1
2098277195Sdelphij	daddu	c_3,t_1
2099277195Sdelphij	daddu	AT,t_2
2100277195Sdelphij	sltu	t_1,c_3,t_1
2101277195Sdelphij	daddu	c_1,AT
2102277195Sdelphij	daddu	t_2,t_1
2103277195Sdelphij	sltu	c_2,c_1,AT
210455714Skris	daddu	c_1,t_2
2105277195Sdelphij	sltu	t_2,c_1,t_2
2106277195Sdelphij	daddu	c_2,t_2
210755714Skris	dmultu	a_1,a_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
210855714Skris	mflo	t_1
210955714Skris	mfhi	t_2
211055714Skris	daddu	c_3,t_1
211155714Skris	sltu	AT,c_3,t_1
211255714Skris	daddu	t_2,AT
211355714Skris	daddu	c_1,t_2
211455714Skris	sltu	AT,c_1,t_2
211555714Skris	daddu	c_2,AT
211655714Skris	sd	c_3,16(a0)
211755714Skris
211855714Skris	dmultu	a_0,a_3		/* mul_add_c2(a[0],b[3],c1,c2,c3); */
211955714Skris	mflo	t_1
212055714Skris	mfhi	t_2
212155714Skris	daddu	c_1,t_1
212255714Skris	sltu	AT,c_1,t_1
2123277195Sdelphij	daddu	c_1,t_1
2124277195Sdelphij	daddu	AT,t_2
2125277195Sdelphij	sltu	t_1,c_1,t_1
2126277195Sdelphij	daddu	c_2,AT
2127277195Sdelphij	daddu	t_2,t_1
2128277195Sdelphij	sltu	c_3,c_2,AT
212955714Skris	daddu	c_2,t_2
2130277195Sdelphij	sltu	t_2,c_2,t_2
2131277195Sdelphij	daddu	c_3,t_2
213255714Skris	dmultu	a_1,a_2		/* mul_add_c(a2[1],b[2],c1,c2,c3); */
213355714Skris	mflo	t_1
213455714Skris	mfhi	t_2
213555714Skris	daddu	c_1,t_1
213655714Skris	sltu	AT,c_1,t_1
2137277195Sdelphij	daddu	c_1,t_1
2138277195Sdelphij	daddu	AT,t_2
2139277195Sdelphij	sltu	t_1,c_1,t_1
2140277195Sdelphij	daddu	c_2,AT
2141277195Sdelphij	daddu	t_2,t_1
2142277195Sdelphij	sltu	AT,c_2,AT
214355714Skris	daddu	c_2,t_2
214455714Skris	daddu	c_3,AT
2145277195Sdelphij	sltu	t_2,c_2,t_2
2146277195Sdelphij	daddu	c_3,t_2
214755714Skris	sd	c_1,24(a0)
214855714Skris
214955714Skris	dmultu	a_3,a_1		/* mul_add_c2(a[3],b[1],c2,c3,c1); */
215055714Skris	mflo	t_1
215155714Skris	mfhi	t_2
215255714Skris	daddu	c_2,t_1
215355714Skris	sltu	AT,c_2,t_1
2154277195Sdelphij	daddu	c_2,t_1
2155277195Sdelphij	daddu	AT,t_2
2156277195Sdelphij	sltu	t_1,c_2,t_1
2157277195Sdelphij	daddu	c_3,AT
2158277195Sdelphij	daddu	t_2,t_1
2159277195Sdelphij	sltu	c_1,c_3,AT
216055714Skris	daddu	c_3,t_2
2161277195Sdelphij	sltu	t_2,c_3,t_2
2162277195Sdelphij	daddu	c_1,t_2
216355714Skris	dmultu	a_2,a_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
216455714Skris	mflo	t_1
216555714Skris	mfhi	t_2
216655714Skris	daddu	c_2,t_1
216755714Skris	sltu	AT,c_2,t_1
216855714Skris	daddu	t_2,AT
216955714Skris	daddu	c_3,t_2
217055714Skris	sltu	AT,c_3,t_2
217155714Skris	daddu	c_1,AT
217255714Skris	sd	c_2,32(a0)
217355714Skris
217455714Skris	dmultu	a_2,a_3		/* mul_add_c2(a[2],b[3],c3,c1,c2); */
217555714Skris	mflo	t_1
217655714Skris	mfhi	t_2
217755714Skris	daddu	c_3,t_1
217855714Skris	sltu	AT,c_3,t_1
2179277195Sdelphij	daddu	c_3,t_1
2180277195Sdelphij	daddu	AT,t_2
2181277195Sdelphij	sltu	t_1,c_3,t_1
2182277195Sdelphij	daddu	c_1,AT
2183277195Sdelphij	daddu	t_2,t_1
2184277195Sdelphij	sltu	c_2,c_1,AT
218555714Skris	daddu	c_1,t_2
2186277195Sdelphij	sltu	t_2,c_1,t_2
2187277195Sdelphij	daddu	c_2,t_2
218855714Skris	sd	c_3,40(a0)
218955714Skris
219055714Skris	dmultu	a_3,a_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
219155714Skris	mflo	t_1
219255714Skris	mfhi	t_2
219355714Skris	daddu	c_1,t_1
219455714Skris	sltu	AT,c_1,t_1
219555714Skris	daddu	t_2,AT
219655714Skris	daddu	c_2,t_2
219755714Skris	sd	c_1,48(a0)
219855714Skris	sd	c_2,56(a0)
219955714Skris
220055714Skris	jr	ra
220155714SkrisEND(bn_sqr_comba4)
2202