develooper Front page | perl.perl5.porters | Postings from December 2000

Re: pp_add -> pp_i_add efficiency hack?

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
December 3, 2000 13:48
Subject:
Re: pp_add -> pp_i_add efficiency hack?
Message ID:
20001203214758.B79486@plum.flirble.org
On Sun, Dec 03, 2000 at 09:43:48PM +0000, Nicholas Clark wrote:
> Also, it's your pp_add overflow detection algorithm, not that one I suggested
> (partially implemented, tested and then wiped with a mis-timed rsync)
> But I'll try mine at some point soon, and try benchmarking.

Well, it would be if I sent it. I'm tired and making mistakes now.

Nicholas Clark

--- pp_hot.c.NV	Wed Nov 22 21:38:18 2000
+++ pp_hot.c	Sat Nov 25 10:30:23 2000
@@ -317,10 +317,105 @@
 PP(pp_add)
 {
     djSP; dATARGET; tryAMAGICbin(add,opASSIGN);
+#ifdef PRESERVE_IVUV
+    if (SvIOK(TOPs) && SvIOK(TOPm1s)) {
+	bool auvok = SvUOK(TOPm1s);
+	bool buvok = SvUOK(TOPs);
+
+	if (!auvok) {
+	    IV aiv = SvIVx(TOPm1s);
+	    
+	    if (!buvok) {		/* IV + IV */
+		IV biv = SvIVx(TOPs);
+
+		if (biv >= 0) {
+		    if (aiv <= IV_MAX - biv) {
+			SP--;
+			SETi( aiv + biv );
+			RETURN;
+		    }
+		    if (aiv >= 0 && (UV)aiv <= UV_MAX - (UV)biv) {
+			SP--;
+			SETu( (UV)aiv + (UV)biv );
+			RETURN;
+		    }
+		}		
+		else { /* biv < 0 */
+		    if (aiv >= IV_MIN - biv) {
+			SP--;
+			SETi( aiv + biv );
+			RETURN;
+		    }
+		}
+	    }
+	    else {			/* IV + UV */
+		UV buv = SvUVx(TOPs);
+
+		if (aiv <= 0 && buv < -aiv) {
+		    SP--;
+		    SETi( aiv + (IV)buv );
+		    RETURN;
+		}
+		if ((IV)buv <= IV_MAX && aiv <= IV_MAX - (IV)buv) {
+		    SP--;
+		    SETi( aiv + (IV)buv );
+		    RETURN;
+		}
+		if (aiv >= 0 && (UV)aiv <= UV_MAX - buv) {
+		    SP--;
+		    SETu( (UV)aiv + buv );
+		    RETURN;
+		}
+		if (aiv < 0 && (UV)-aiv <= UV_MAX - buv) {
+		    SP--;
+		    SETu( buv - (UV)-aiv );
+		    RETURN;
+		}
+	    }
+	}
+	else { /* auvok */
+	    UV auv = SvUVx(TOPm1s);
+
+	    if (!buvok) {		/* UV + IV */
+		IV biv = SvIVx(TOPs);
+
+		if (biv <= 0 && auv < -biv) {
+		    SP--;
+		    SETi( (IV)auv + biv );
+		    RETURN;
+		}
+		if ((IV)auv <= IV_MAX && biv <= IV_MAX - (IV)auv) {
+		    SP--;
+		    SETi( (IV)auv + biv );
+		    RETURN;
+		}
+		if (biv >= 0 && (UV)biv <= UV_MAX - auv) {
+		    SP--;
+		    SETu( auv + (UV)biv );
+		    RETURN;
+		}
+		if (biv < 0 && (UV)-biv <= UV_MAX - auv) {
+		    SP--;
+		    SETu( auv - (UV)-biv );
+		    RETURN;
+		}
+	    }
+	    else {			/* UV + UV */
+		UV buv = SvUVx(TOPs);
+
+		if (auv <= UV_MAX - buv) {
+		    SP--;
+		    SETu( auv + buv );
+		    RETURN;
+		}
+	    }
+	}
+    }
+#endif
     {
-      dPOPTOPnnrl_ul;
-      SETn( left + right );
-      RETURN;
+	dPOPTOPnnrl_ul;
+	SETn( left + right );
+	RETURN;
     }
 }
 

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About