svn commit: r46203 - in head/share: security/advisories security/patches/SA-15:01 xml

Xin LI <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.doc
Message-ID <[email protected]>
Author: delphij
Date: Wed Jan 14 21:37:46 2015
New Revision: 46203
URL: https://svnweb.freebsd.org/changeset/doc/46203

Log:
  Add advisory and patches for SA-15:01.openssl.

Added:
  head/share/security/advisories/FreeBSD-SA-15:01.openssl.asc   (contents, props changed)
  head/share/security/patches/SA-15:01/
  head/share/security/patches/SA-15:01/openssl-10.0.patch   (contents, props changed)
  head/share/security/patches/SA-15:01/openssl-10.0.patch.asc   (contents, props changed)
  head/share/security/patches/SA-15:01/openssl-10.1.patch   (contents, props changed)
  head/share/security/patches/SA-15:01/openssl-10.1.patch.asc   (contents, props changed)
  head/share/security/patches/SA-15:01/openssl-9.3.patch   (contents, props changed)
  head/share/security/patches/SA-15:01/openssl-9.3.patch.asc   (contents, props changed)
Modified:
  head/share/xml/advisories.xml

Added: head/share/security/advisories/FreeBSD-SA-15:01.openssl.asc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/advisories/FreeBSD-SA-15:01.openssl.asc	Wed Jan 14 21:37:46 2015	(r46203)
@@ -0,0 +1,211 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-15:01.openssl                                    Security Advisory
+                                                          The FreeBSD Project
+
+Topic:          OpenSSL multiple vulnerabilities
+
+Category:       contrib
+Module:         openssl
+Announced:      2015-01-14
+Affects:        All supported versions of FreeBSD.
+Corrected:      2015-01-09 00:58:20 UTC (stable/10, 10.1-STABLE)
+                2015-01-14 21:27:46 UTC (releng/10.1, 10.1-RELEASE-p4)
+                2015-01-14 21:27:46 UTC (releng/10.0, 10.0-RELEASE-p16)
+                2015-01-09 01:11:43 UTC (stable/9, 9.3-STABLE)
+                2015-01-14 21:27:46 UTC (releng/9.3, 9.3-RELEASE-p8)
+                2015-01-09 01:11:43 UTC (stable/8, 8.4-STABLE)
+                2015-01-14 21:27:46 UTC (releng/8.4, 8.4-RELEASE-p22)
+CVE Name:       CVE-2014-3571, CVE-2015-0206, CVE-2014-3569, CVE-2014-3572
+                CVE-2015-0204, CVE-2015-0205, CVE-2014-8275, CVE-2014-3570
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit <URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+FreeBSD includes software from the OpenSSL Project.  The OpenSSL Project is
+a collaborative effort to develop a robust, commercial-grade, full-featured
+Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3)
+and Transport Layer Security (TLS v1) protocols as well as a full-strength
+general purpose cryptography library.
+
+II.  Problem Description
+
+A carefully crafted DTLS message can cause a segmentation fault in OpenSSL
+due to a NULL pointer dereference. [CVE-2014-3571]
+
+A memory leak can occur in the dtls1_buffer_record function under certain
+conditions. [CVE-2015-0206]
+
+When OpenSSL is built with the no-ssl3 option and a SSL v3 ClientHello is
+received the ssl method would be set to NULL which could later result in
+a NULL pointer dereference.  [CVE-2014-3569] This does not affect
+FreeBSD's default build.
+
+An OpenSSL client will accept a handshake using an ephemeral ECDH
+ciphersuite using an ECDSA certificate if the server key exchange message
+is omitted. [CVE-2014-3572]
+
+An OpenSSL client will accept the use of an RSA temporary key in a non-export
+RSA key exchange ciphersuite. [CVE-2015-0204]
+
+An OpenSSL server will accept a DH certificate for client authentication
+without the certificate verify message. [CVE-2015-0205]
+
+OpenSSL accepts several non-DER-variations of certificate signature
+algorithm and signature encodings.  OpenSSL also does not enforce a
+match between the signature algorithm between the signed and unsigned
+portions of the certificate. [CVE-2014-8275]
+
+Bignum squaring (BN_sqr) may produce incorrect results on some
+platforms, including x86_64. [CVE-2014-3570]
+
+III. Impact
+
+An attacker who can send a carefully crafted DTLS message can cause server
+daemons that uses OpenSSL to crash, resulting a Denial of Service.
+[CVE-2014-3571]
+
+An attacker who can send repeated DTLS records with the same sequence number
+but for the next epoch can exhaust the server's memory and result in a Denial of
+Service. [CVE-2015-0206]
+
+A server can remove forward secrecy from the ciphersuite.  [CVE-2014-3572]
+
+A server could present a weak temporary key and downgrade the security of
+the session. [CVE-2015-0204]
+
+A client could authenticate without the use of a private key.  This only
+affects servers which trust a client certificate authority which issues
+certificates containing DH keys, which is extremely rare.  [CVE-2015-0205]
+
+By modifying the contents of the signature algorithm or the encoding of
+the signature, it is possible to change the certificate's fingerprint.
+
+This does not allow an attacker to forge certificates, and does not
+affect certificate verification or OpenSSL servers/clients in any
+other way. It also does not affect common revocation mechanisms.  Only
+custom applications that rely on the uniqueness of the fingerprint
+(e.g. certificate blacklists) may be affected.  [CVE-2014-8275]
+
+IV.  Workaround
+
+No workaround is available.
+
+V.   Solution
+
+Perform one of the following:
+
+1) Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date.
+
+2) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+3) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 8.4 and FreeBSD 9.3]
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-9.3.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-9.3.patch.asc
+# gpg --verify openssl-9.3.patch.asc
+
+[FreeBSD 10.0]
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-10.0.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-10.0.patch.asc
+# gpg --verify openssl-10.0.patch.asc
+
+[FreeBSD 10.1]
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-10.1.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-10.1.patch.asc
+# gpg --verify openssl-10.1.patch.asc
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+Restart all deamons using the library, or reboot the system.
+
+VI.  Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path                                                      Revision
+- -------------------------------------------------------------------------
+stable/8/                                                         r276865
+releng/8.4/                                                       r277195
+stable/9/                                                         r276865
+releng/9.3/                                                       r277195
+stable/10/                                                        r276864
+releng/10.0/                                                      r277195
+releng/10.1/                                                      r277195
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+<URL:https://www.openssl.org/news/secadv_20150108.txt>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3569>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3570>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3571>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3572>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-8275>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0204>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0205>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0206>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-15:01.openssl.asc>
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.1.1 (FreeBSD)
+
+iQIcBAEBCgAGBQJUtuEaAAoJEO1n7NZdz2rnQCcP/A19v5HUUhjz5nMbUumRwAmB
+QCxNKEy6SbAuxtIwGNYJyyxKIK3R9vTHwlgyQZVb4q8FgMHcu4yABeRfov10mO5Q
+U7RkLOJyca6eqEngkrh+AFfbhqfxtccIMUQkDdegsQcqZd2Ya0VeNfjA8H0XIDoL
+JSEoCifmxjv6v8ZcpugahsUOBmEWx+vyHJUSPVSv/AsLubzV3hqi4iLpzLky3/dR
+4LHGzPny07NkGPVqOBU7mjTs76SzCTS2c4NIVfvbphx8UojMvREbZ8ogCMEVGBXY
+fIWesi7Y6lhqbSgWj1EXyZF9NTo/Z4nr7Oh1ER5VSAfmhZAdyhEEEGQrg4Jq0VL3
+DJ1Y35Up79xXmVjB14COxodI5UO+55wWnXb8r/zy/eh+wv0sHwlTz56wxo7SxAOa
+xOrQj0VJ7zghLhBO7azacbVYIKpfQkJafb7XRUOqu4wt2y3/jeL+0UkWJnNMROrq
+aQUB6SdGUVDwQsmodgF0rsGcQYXhaQBPu4KQo8yG8+rpqc2zewi537BJr/PWJvH0
+sJ6yYcD7VGyIleVRDpxsg7uBWelnGn+AqHignbyUcic4j/N9lYlF00AVgka2TdOp
+i5eZtp7m95v53S4fEX2HGwWpOv+AfCrSKQZGpvdNx+9JyD3LyOvFBxs4k0oZWa6J
+6FLFZ38YkLcUIzW6I6Kc
+=ztFk
+-----END PGP SIGNATURE-----

Added: head/share/security/patches/SA-15:01/openssl-10.0.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/patches/SA-15:01/openssl-10.0.patch	Wed Jan 14 21:37:46 2015	(r46203)
@@ -0,0 +1,2083 @@
+Index: crypto/openssl/crypto/asn1/a_bitstr.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_bitstr.c	(revision 276867)
++++ crypto/openssl/crypto/asn1/a_bitstr.c	(working copy)
+@@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRI
+ 
+ 	p= *pp;
+ 	i= *(p++);
++	if (i > 7)
++		{
++		i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
++		goto err;
++		}
+ 	/* We do this to preserve the settings.  If we modify
+ 	 * the settings, via the _set_bit function, we will recalculate
+ 	 * on output */
+ 	ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
+-	ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
++	ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */
+ 
+ 	if (len-- > 1) /* using one because of the bits left byte */
+ 		{
+Index: crypto/openssl/crypto/asn1/a_type.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_type.c	(revision 276867)
++++ crypto/openssl/crypto/asn1/a_type.c	(working copy)
+@@ -113,7 +113,7 @@ IMPLEMENT_STACK_OF(ASN1_TYPE)
+ IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
+ 
+ /* Returns 0 if they are equal, != 0 otherwise. */
+-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
++int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
+ 	{
+ 	int result = -1;
+ 
+Index: crypto/openssl/crypto/asn1/a_verify.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_verify.c	(revision 276867)
++++ crypto/openssl/crypto/asn1/a_verify.c	(working copy)
+@@ -90,6 +90,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, A
+ 		ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ 		goto err;
+ 		}
++
++	if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
++		{
++		ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
++		goto err;
++		}
+ 	
+ 	inl=i2d(data,NULL);
+ 	buf_in=OPENSSL_malloc((unsigned int)inl);
+@@ -146,6 +152,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALG
+ 		return -1;
+ 		}
+ 
++	if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
++		{
++		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
++		return -1;
++		}
++
+ 	EVP_MD_CTX_init(&ctx);
+ 
+ 	/* Convert signature OID into digest and public key OIDs */
+Index: crypto/openssl/crypto/asn1/asn1.h
+===================================================================
+--- crypto/openssl/crypto/asn1/asn1.h	(revision 276867)
++++ crypto/openssl/crypto/asn1/asn1.h	(working copy)
+@@ -776,7 +776,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY,
+ int ASN1_TYPE_get(ASN1_TYPE *a);
+ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+-int            ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
++int            ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
+ 
+ ASN1_OBJECT *	ASN1_OBJECT_new(void );
+ void		ASN1_OBJECT_free(ASN1_OBJECT *a);
+@@ -1329,6 +1329,7 @@ void ERR_load_ASN1_strings(void);
+ #define ASN1_R_ILLEGAL_TIME_VALUE			 184
+ #define ASN1_R_INTEGER_NOT_ASCII_FORMAT			 185
+ #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG		 128
++#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT		 220
+ #define ASN1_R_INVALID_BMPSTRING_LENGTH			 129
+ #define ASN1_R_INVALID_DIGIT				 130
+ #define ASN1_R_INVALID_MIME_TYPE			 205
+Index: crypto/openssl/crypto/asn1/asn1_err.c
+===================================================================
+--- crypto/openssl/crypto/asn1/asn1_err.c	(revision 276867)
++++ crypto/openssl/crypto/asn1/asn1_err.c	(working copy)
+@@ -246,6 +246,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
+ {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE)   ,"illegal time value"},
+ {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
+ {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
++{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"},
+ {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
+ {ERR_REASON(ASN1_R_INVALID_DIGIT)        ,"invalid digit"},
+ {ERR_REASON(ASN1_R_INVALID_MIME_TYPE)    ,"invalid mime type"},
+Index: crypto/openssl/crypto/asn1/x_algor.c
+===================================================================
+--- crypto/openssl/crypto/asn1/x_algor.c	(revision 276867)
++++ crypto/openssl/crypto/asn1/x_algor.c	(working copy)
+@@ -142,3 +142,14 @@ void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_
+ 	X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+ 
+ 	}
++
++int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
++	{
++	int rv;
++	rv = OBJ_cmp(a->algorithm, b->algorithm);
++	if (rv)
++		return rv;
++	if (!a->parameter && !b->parameter)
++		return 0;
++	return ASN1_TYPE_cmp(a->parameter, b->parameter);
++	}
+Index: crypto/openssl/crypto/bio/bss_dgram.c
+===================================================================
+--- crypto/openssl/crypto/bio/bss_dgram.c	(revision 276867)
++++ crypto/openssl/crypto/bio/bss_dgram.c	(working copy)
+@@ -982,7 +982,12 @@ static int dgram_sctp_free(BIO *a)
+ 		return 0;
+ 
+ 	data = (bio_dgram_sctp_data *)a->ptr;
+-	if(data != NULL) OPENSSL_free(data);
++	if(data != NULL)
++		{
++		if(data->saved_message.data != NULL)
++			OPENSSL_free(data->saved_message.data);
++		OPENSSL_free(data);
++		}
+ 
+ 	return(1);
+ 	}
+@@ -1099,6 +1104,7 @@ static int dgram_sctp_read(BIO *b, char *out, int
+ 						dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
+ 						                 data->saved_message.length);
+ 						OPENSSL_free(data->saved_message.data);
++						data->saved_message.data = NULL;
+ 						data->saved_message.length = 0;
+ 						}
+ 
+@@ -1258,9 +1264,11 @@ static int dgram_sctp_write(BIO *b, const char *in
+ 	if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
+ 	{
+ 		data->saved_message.bio = b;
+-		data->saved_message.length = inl;
++		if (data->saved_message.data)
++			OPENSSL_free(data->saved_message.data);
+ 		data->saved_message.data = OPENSSL_malloc(inl);
+ 		memcpy(data->saved_message.data, in, inl);
++		data->saved_message.length = inl;
+ 		return inl;
+ 	}
+ 
+Index: crypto/openssl/crypto/bn/asm/mips.pl
+===================================================================
+--- crypto/openssl/crypto/bn/asm/mips.pl	(revision 276867)
++++ crypto/openssl/crypto/bn/asm/mips.pl	(working copy)
+@@ -1874,8 +1874,43 @@ ___
+ 
+ ($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3);
+ 
++sub add_c2 () {
++my ($hi,$lo,$c0,$c1,$c2,
++    $warm,      # !$warm denotes first call with specific sequence of
++                # $c_[XYZ] when there is no Z-carry to accumulate yet;
++    $an,$bn     # these two are arguments for multiplication which
++                # result is used in *next* step [which is why it's
++                # commented as "forward multiplication" below];
++    )=@_;
+ $code.=<<___;
++	mflo	$lo
++	mfhi	$hi
++	$ADDU	$c0,$lo
++	sltu	$at,$c0,$lo
++	 $MULTU	$an,$bn			# forward multiplication
++	$ADDU	$c0,$lo
++	$ADDU	$at,$hi
++	sltu	$lo,$c0,$lo
++	$ADDU	$c1,$at
++	$ADDU	$hi,$lo
++___
++$code.=<<___	if (!$warm);
++	sltu	$c2,$c1,$at
++	$ADDU	$c1,$hi
++	sltu	$hi,$c1,$hi
++	$ADDU	$c2,$hi
++___
++$code.=<<___	if ($warm);
++	sltu	$at,$c1,$at
++	$ADDU	$c1,$hi
++	$ADDU	$c2,$at
++	sltu	$hi,$c1,$hi
++	$ADDU	$c2,$hi
++___
++}
+ 
++$code.=<<___;
++
+ .align	5
+ .globl	bn_sqr_comba8
+ .ent	bn_sqr_comba8
+@@ -1922,25 +1957,14 @@ $code.=<<___;
+ 	sltu	$at,$c_2,$t_1
+ 	$ADDU	$c_3,$t_2,$at
+ 	$ST	$c_2,$BNSZ($a0)
+-
++___
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++		$a_1,$a_1);		# mul_add_c(a[1],b[1],c3,c1,c2);
++$code.=<<___;
+ 	mflo	$t_1
+ 	mfhi	$t_2
+-	slt	$c_2,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_1,$a_1		# mul_add_c(a[1],b[1],c3,c1,c2);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+ 	$ADDU	$c_3,$t_1
+ 	sltu	$at,$c_3,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_1,$t_2
+-	sltu	$at,$c_1,$t_2
+-	$ADDU	$c_2,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	$ADDU	$c_3,$t_1
+-	sltu	$at,$c_3,$t_1
+ 	 $MULTU	$a_0,$a_3		# mul_add_c2(a[0],b[3],c1,c2,c3);
+ 	$ADDU	$t_2,$at
+ 	$ADDU	$c_1,$t_2
+@@ -1947,71 +1971,23 @@ $code.=<<___;
+ 	sltu	$at,$c_1,$t_2
+ 	$ADDU	$c_2,$at
+ 	$ST	$c_3,2*$BNSZ($a0)
+-
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$c_3,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_1,$a_2		# mul_add_c2(a[1],b[2],c1,c2,c3);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_1,$t_1
+-	sltu	$at,$c_1,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_2,$t_2
+-	sltu	$at,$c_2,$t_2
+-	$ADDU	$c_3,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_3,$at
+-	 $MULTU	$a_4,$a_0		# mul_add_c2(a[4],b[0],c2,c3,c1);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_1,$t_1
+-	sltu	$at,$c_1,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_2,$t_2
+-	sltu	$at,$c_2,$t_2
+-	$ADDU	$c_3,$at
++___
++	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++		$a_1,$a_2);		# mul_add_c2(a[1],b[2],c1,c2,c3);
++	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++		$a_4,$a_0);		# mul_add_c2(a[4],b[0],c2,c3,c1);
++$code.=<<___;
+ 	$ST	$c_1,3*$BNSZ($a0)
+-
++___
++	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++		$a_3,$a_1);		# mul_add_c2(a[3],b[1],c2,c3,c1);
++	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++		$a_2,$a_2);		# mul_add_c(a[2],b[2],c2,c3,c1);
++$code.=<<___;
+ 	mflo	$t_1
+ 	mfhi	$t_2
+-	slt	$c_1,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_3,$a_1		# mul_add_c2(a[3],b[1],c2,c3,c1);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+ 	$ADDU	$c_2,$t_1
+ 	sltu	$at,$c_2,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_3,$t_2
+-	sltu	$at,$c_3,$t_2
+-	$ADDU	$c_1,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_1,$at
+-	$MULTU	$a_2,$a_2		# mul_add_c(a[2],b[2],c2,c3,c1);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_2,$t_1
+-	sltu	$at,$c_2,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_3,$t_2
+-	sltu	$at,$c_3,$t_2
+-	$ADDU	$c_1,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	$ADDU	$c_2,$t_1
+-	sltu	$at,$c_2,$t_1
+ 	 $MULTU	$a_0,$a_5		# mul_add_c2(a[0],b[5],c3,c1,c2);
+ 	$ADDU	$t_2,$at
+ 	$ADDU	$c_3,$t_2
+@@ -2018,101 +1994,27 @@ $code.=<<___;
+ 	sltu	$at,$c_3,$t_2
+ 	$ADDU	$c_1,$at
+ 	$ST	$c_2,4*$BNSZ($a0)
+-
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$c_2,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_1,$a_4		# mul_add_c2(a[1],b[4],c3,c1,c2);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_3,$t_1
+-	sltu	$at,$c_3,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_1,$t_2
+-	sltu	$at,$c_1,$t_2
+-	$ADDU	$c_2,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_2,$at
+-	$MULTU	$a_2,$a_3		# mul_add_c2(a[2],b[3],c3,c1,c2);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_3,$t_1
+-	sltu	$at,$c_3,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_1,$t_2
+-	sltu	$at,$c_1,$t_2
+-	$ADDU	$c_2,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	 $MULTU	$a_6,$a_0		# mul_add_c2(a[6],b[0],c1,c2,c3);
+-	$ADDU	$c_2,$at
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_3,$t_1
+-	sltu	$at,$c_3,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_1,$t_2
+-	sltu	$at,$c_1,$t_2
+-	$ADDU	$c_2,$at
++___
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++		$a_1,$a_4);		# mul_add_c2(a[1],b[4],c3,c1,c2);
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++		$a_2,$a_3);		# mul_add_c2(a[2],b[3],c3,c1,c2);
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++		$a_6,$a_0);		# mul_add_c2(a[6],b[0],c1,c2,c3);
++$code.=<<___;
+ 	$ST	$c_3,5*$BNSZ($a0)
+-
++___
++	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++		$a_5,$a_1);		# mul_add_c2(a[5],b[1],c1,c2,c3);
++	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++		$a_4,$a_2);		# mul_add_c2(a[4],b[2],c1,c2,c3);
++	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++		$a_3,$a_3);		# mul_add_c(a[3],b[3],c1,c2,c3);
++$code.=<<___;
+ 	mflo	$t_1
+ 	mfhi	$t_2
+-	slt	$c_3,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_5,$a_1		# mul_add_c2(a[5],b[1],c1,c2,c3);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+ 	$ADDU	$c_1,$t_1
+ 	sltu	$at,$c_1,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_2,$t_2
+-	sltu	$at,$c_2,$t_2
+-	$ADDU	$c_3,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_3,$at
+-	$MULTU	$a_4,$a_2		# mul_add_c2(a[4],b[2],c1,c2,c3);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_1,$t_1
+-	sltu	$at,$c_1,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_2,$t_2
+-	sltu	$at,$c_2,$t_2
+-	$ADDU	$c_3,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_3,$at
+-	$MULTU	$a_3,$a_3		# mul_add_c(a[3],b[3],c1,c2,c3);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_1,$t_1
+-	sltu	$at,$c_1,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_2,$t_2
+-	sltu	$at,$c_2,$t_2
+-	$ADDU	$c_3,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	$ADDU	$c_1,$t_1
+-	sltu	$at,$c_1,$t_1
+ 	 $MULTU	$a_0,$a_7		# mul_add_c2(a[0],b[7],c2,c3,c1);
+ 	$ADDU	$t_2,$at
+ 	$ADDU	$c_2,$t_2
+@@ -2119,116 +2021,29 @@ $code.=<<___;
+ 	sltu	$at,$c_2,$t_2
+ 	$ADDU	$c_3,$at
+ 	$ST	$c_1,6*$BNSZ($a0)
+-
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$c_1,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_1,$a_6		# mul_add_c2(a[1],b[6],c2,c3,c1);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_2,$t_1
+-	sltu	$at,$c_2,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_3,$t_2
+-	sltu	$at,$c_3,$t_2
+-	$ADDU	$c_1,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_1,$at
+-	$MULTU	$a_2,$a_5		# mul_add_c2(a[2],b[5],c2,c3,c1);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_2,$t_1
+-	sltu	$at,$c_2,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_3,$t_2
+-	sltu	$at,$c_3,$t_2
+-	$ADDU	$c_1,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_1,$at
+-	$MULTU	$a_3,$a_4		# mul_add_c2(a[3],b[4],c2,c3,c1);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_2,$t_1
+-	sltu	$at,$c_2,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_3,$t_2
+-	sltu	$at,$c_3,$t_2
+-	$ADDU	$c_1,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_1,$at
+-	 $MULTU	$a_7,$a_1		# mul_add_c2(a[7],b[1],c3,c1,c2);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_2,$t_1
+-	sltu	$at,$c_2,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_3,$t_2
+-	sltu	$at,$c_3,$t_2
+-	$ADDU	$c_1,$at
++___
++	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++		$a_1,$a_6);		# mul_add_c2(a[1],b[6],c2,c3,c1);
++	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++		$a_2,$a_5);		# mul_add_c2(a[2],b[5],c2,c3,c1);
++	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++		$a_3,$a_4);		# mul_add_c2(a[3],b[4],c2,c3,c1);
++	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++		$a_7,$a_1);		# mul_add_c2(a[7],b[1],c3,c1,c2);
++$code.=<<___;
+ 	$ST	$c_2,7*$BNSZ($a0)
+-
++___
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++		$a_6,$a_2);		# mul_add_c2(a[6],b[2],c3,c1,c2);
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++		$a_5,$a_3);		# mul_add_c2(a[5],b[3],c3,c1,c2);
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++		$a_4,$a_4);		# mul_add_c(a[4],b[4],c3,c1,c2);
++$code.=<<___;
+ 	mflo	$t_1
+ 	mfhi	$t_2
+-	slt	$c_2,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_6,$a_2		# mul_add_c2(a[6],b[2],c3,c1,c2);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+ 	$ADDU	$c_3,$t_1
+ 	sltu	$at,$c_3,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_1,$t_2
+-	sltu	$at,$c_1,$t_2
+-	$ADDU	$c_2,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_2,$at
+-	$MULTU	$a_5,$a_3		# mul_add_c2(a[5],b[3],c3,c1,c2);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_3,$t_1
+-	sltu	$at,$c_3,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_1,$t_2
+-	sltu	$at,$c_1,$t_2
+-	$ADDU	$c_2,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_2,$at
+-	$MULTU	$a_4,$a_4		# mul_add_c(a[4],b[4],c3,c1,c2);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_3,$t_1
+-	sltu	$at,$c_3,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_1,$t_2
+-	sltu	$at,$c_1,$t_2
+-	$ADDU	$c_2,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	$ADDU	$c_3,$t_1
+-	sltu	$at,$c_3,$t_1
+ 	 $MULTU	$a_2,$a_7		# mul_add_c2(a[2],b[7],c1,c2,c3);
+ 	$ADDU	$t_2,$at
+ 	$ADDU	$c_1,$t_2
+@@ -2235,86 +2050,25 @@ $code.=<<___;
+ 	sltu	$at,$c_1,$t_2
+ 	$ADDU	$c_2,$at
+ 	$ST	$c_3,8*$BNSZ($a0)
+-
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$c_3,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_3,$a_6		# mul_add_c2(a[3],b[6],c1,c2,c3);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_1,$t_1
+-	sltu	$at,$c_1,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_2,$t_2
+-	sltu	$at,$c_2,$t_2
+-	$ADDU	$c_3,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_3,$at
+-	$MULTU	$a_4,$a_5		# mul_add_c2(a[4],b[5],c1,c2,c3);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_1,$t_1
+-	sltu	$at,$c_1,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_2,$t_2
+-	sltu	$at,$c_2,$t_2
+-	$ADDU	$c_3,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_3,$at
+-	 $MULTU	$a_7,$a_3		# mul_add_c2(a[7],b[3],c2,c3,c1);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_1,$t_1
+-	sltu	$at,$c_1,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_2,$t_2
+-	sltu	$at,$c_2,$t_2
+-	$ADDU	$c_3,$at
++___
++	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++		$a_3,$a_6);		# mul_add_c2(a[3],b[6],c1,c2,c3);
++	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++		$a_4,$a_5);		# mul_add_c2(a[4],b[5],c1,c2,c3);
++	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++		$a_7,$a_3);		# mul_add_c2(a[7],b[3],c2,c3,c1);
++$code.=<<___;
+ 	$ST	$c_1,9*$BNSZ($a0)
+-
++___
++	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++		$a_6,$a_4);		# mul_add_c2(a[6],b[4],c2,c3,c1);
++	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++		$a_5,$a_5);		# mul_add_c(a[5],b[5],c2,c3,c1);
++$code.=<<___;
+ 	mflo	$t_1
+ 	mfhi	$t_2
+-	slt	$c_1,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_6,$a_4		# mul_add_c2(a[6],b[4],c2,c3,c1);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+ 	$ADDU	$c_2,$t_1
+ 	sltu	$at,$c_2,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_3,$t_2
+-	sltu	$at,$c_3,$t_2
+-	$ADDU	$c_1,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_1,$at
+-	$MULTU	$a_5,$a_5		# mul_add_c(a[5],b[5],c2,c3,c1);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_2,$t_1
+-	sltu	$at,$c_2,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_3,$t_2
+-	sltu	$at,$c_3,$t_2
+-	$ADDU	$c_1,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	$ADDU	$c_2,$t_1
+-	sltu	$at,$c_2,$t_1
+ 	 $MULTU	$a_4,$a_7		# mul_add_c2(a[4],b[7],c3,c1,c2);
+ 	$ADDU	$t_2,$at
+ 	$ADDU	$c_3,$t_2
+@@ -2321,56 +2075,21 @@ $code.=<<___;
+ 	sltu	$at,$c_3,$t_2
+ 	$ADDU	$c_1,$at
+ 	$ST	$c_2,10*$BNSZ($a0)
+-
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$c_2,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_5,$a_6		# mul_add_c2(a[5],b[6],c3,c1,c2);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_3,$t_1
+-	sltu	$at,$c_3,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_1,$t_2
+-	sltu	$at,$c_1,$t_2
+-	$ADDU	$c_2,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$at,$t_2,$zero
+-	$ADDU	$c_2,$at
+-	 $MULTU	$a_7,$a_5		# mul_add_c2(a[7],b[5],c1,c2,c3);
+-	$SLL	$t_2,1
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_3,$t_1
+-	sltu	$at,$c_3,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_1,$t_2
+-	sltu	$at,$c_1,$t_2
+-	$ADDU	$c_2,$at
++___
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++		$a_5,$a_6);		# mul_add_c2(a[5],b[6],c3,c1,c2);
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++		$a_7,$a_5);		# mul_add_c2(a[7],b[5],c1,c2,c3);
++$code.=<<___;
+ 	$ST	$c_3,11*$BNSZ($a0)
+-
++___
++	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++		$a_6,$a_6);		# mul_add_c(a[6],b[6],c1,c2,c3);
++$code.=<<___;
+ 	mflo	$t_1
+ 	mfhi	$t_2
+-	slt	$c_3,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_6,$a_6		# mul_add_c(a[6],b[6],c1,c2,c3);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+ 	$ADDU	$c_1,$t_1
+ 	sltu	$at,$c_1,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_2,$t_2
+-	sltu	$at,$c_2,$t_2
+-	$ADDU	$c_3,$at
+-	mflo	$t_1
+-	mfhi	$t_2
+-	$ADDU	$c_1,$t_1
+-	sltu	$at,$c_1,$t_1
+ 	 $MULTU	$a_6,$a_7		# mul_add_c2(a[6],b[7],c2,c3,c1);
+ 	$ADDU	$t_2,$at
+ 	$ADDU	$c_2,$t_2
+@@ -2377,21 +2096,10 @@ $code.=<<___;
+ 	sltu	$at,$c_2,$t_2
+ 	$ADDU	$c_3,$at
+ 	$ST	$c_1,12*$BNSZ($a0)
+-
+-	mflo	$t_1
+-	mfhi	$t_2
+-	slt	$c_1,$t_2,$zero
+-	$SLL	$t_2,1
+-	 $MULTU	$a_7,$a_7		# mul_add_c(a[7],b[7],c3,c1,c2);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+-	$ADDU	$c_2,$t_1
+-	sltu	$at,$c_2,$t_1
+-	$ADDU	$t_2,$at
+-	$ADDU	$c_3,$t_2
+-	sltu	$at,$c_3,$t_2
+-	$ADDU	$c_1,$at
++___
++	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++		$a_7,$a_7);		# mul_add_c(a[7],b[7],c3,c1,c2);
++$code.=<<___;
+ 	$ST	$c_2,13*$BNSZ($a0)
+ 
+ 	mflo	$t_1
+@@ -2459,25 +2167,14 @@ $code.=<<___;
+ 	sltu	$at,$c_2,$t_1
+ 	$ADDU	$c_3,$t_2,$at
+ 	$ST	$c_2,$BNSZ($a0)
+-
++___
++	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++		$a_1,$a_1);		# mul_add_c(a[1],b[1],c3,c1,c2);
++$code.=<<___;
+ 	mflo	$t_1
+ 	mfhi	$t_2
+-	slt	$c_2,$t_2,$zero
+-	$SLL	$t_2,1
+-	$MULTU	$a_1,$a_1		# mul_add_c(a[1],b[1],c3,c1,c2);
+-	slt	$a2,$t_1,$zero
+-	$ADDU	$t_2,$a2
+-	$SLL	$t_1,1
+ 	$ADDU	$c_3,$t_1

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-doc-all
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.