summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2011-06-22 10:59:18 +0100
committerDavid Mitchell <davem@iabyn.com>2011-06-25 09:28:17 +0100
commit33efebe6a5ab2b2152593885ee155259a5bfd3f1 (patch)
tree6d1f68c083281adbc896385bd35d8dcebb4945bd /pp_hot.c
parent06c6da524f9e0eae167367edc8fe0150d69893fa (diff)
downloadperl-33efebe6a5ab2b2152593885ee155259a5bfd3f1.tar.gz
add do_ncmp fn and make pp_ncmp, pp_eq etc use it
Extract most of the body of pp_ncmp() (numeric compare) into a separate function, do_ncmp(), then make the following ops use it: pp_ncmp pp_lt pp_le pp_eq pp_ne pp_ge pp_gt This removes a lot of similar or duplicated code, most of which is dedicated to handling the various combinations of IV verses UV verses NV verses NaN. The various ops first check for, and directly process, the simple and common case of both args being SvIOK_notUV(), and pass the processing on to do_ncmp() otherwise. Benchmarking seems to indicate (but with a lot of noise) that the SvIOK_notUV case is slightly faster than before, and the do_ncmp() branch slightly slower.
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c71
1 files changed, 10 insertions, 61 deletions
diff --git a/pp_hot.c b/pp_hot.c
index c284781b38..3b97815b70 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -341,68 +341,17 @@ PP(pp_readline)
PP(pp_eq)
{
dVAR; dSP;
+ SV *left, *right;
+
tryAMAGICbin_MG(eq_amg, AMGf_set|AMGf_numeric);
-#ifdef PERL_PRESERVE_IVUV
- SvIV_please_nomg(TOPs);
- if (SvIOK(TOPs)) {
- /* Unless the left argument is integer in range we are going
- to have to use NV maths. Hence only attempt to coerce the
- right argument if we know the left is integer. */
- SvIV_please_nomg(TOPm1s);
- if (SvIOK(TOPm1s)) {
- const bool auvok = SvUOK(TOPm1s);
- const bool buvok = SvUOK(TOPs);
-
- if (auvok == buvok) { /* ## IV == IV or UV == UV ## */
- /* Casting IV to UV before comparison isn't going to matter
- on 2s complement. On 1s complement or sign&magnitude
- (if we have any of them) it could to make negative zero
- differ from normal zero. As I understand it. (Need to
- check - is negative zero implementation defined behaviour
- anyway?). NWC */
- const UV buv = SvUVX(POPs);
- const UV auv = SvUVX(TOPs);
-
- SETs(boolSV(auv == buv));
- RETURN;
- }
- { /* ## Mixed IV,UV ## */
- SV *ivp, *uvp;
- IV iv;
-
- /* == is commutative so doesn't matter which is left or right */
- if (auvok) {
- /* top of stack (b) is the iv */
- ivp = *SP;
- uvp = *--SP;
- } else {
- uvp = *SP;
- ivp = *--SP;
- }
- iv = SvIVX(ivp);
- if (iv < 0)
- /* As uv is a UV, it's >0, so it cannot be == */
- SETs(&PL_sv_no);
- else
- /* we know iv is >= 0 */
- SETs(boolSV((UV)iv == SvUVX(uvp)));
- RETURN;
- }
- }
- }
-#endif
- {
-#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
- dPOPTOPnnrl_nomg;
- if (Perl_isnan(left) || Perl_isnan(right))
- RETSETNO;
- SETs(boolSV(left == right));
-#else
- dPOPnv_nomg;
- SETs(boolSV(SvNV_nomg(TOPs) == value));
-#endif
- RETURN;
- }
+ right = POPs;
+ left = TOPs;
+ SETs(boolSV(
+ (SvIOK_notUV(left) && SvIOK_notUV(right))
+ ? (SvIVX(left) == SvIVX(right))
+ : ( do_ncmp(left, right) == 0)
+ ));
+ RETURN;
}
PP(pp_preinc)