Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Jan 2015 21:37:46 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        doc-committers@freebsd.org, svn-doc-all@freebsd.org, svn-doc-head@freebsd.org
Subject:   svn commit: r46203 - in head/share: security/advisories security/patches/SA-15:01 xml
Message-ID:  <201501142137.t0ELbk5R026545@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501142137.t0ELbk5R026545>