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