@@ -477,6 +477,10 @@ ZEND_API void zend_update_current_locale(void);
477
477
#define zend_update_current_locale ()
478
478
#endif
479
479
480
+ /* The offset in bytes between the value and type fields of a zval */
481
+ #define ZVAL_OFFSETOF_TYPE \
482
+ (__builtin_offsetof(zval,type) - __builtin_offsetof(zval,value))
483
+
480
484
static zend_always_inline int fast_increment_function (zval * op1 )
481
485
{
482
486
if (EXPECTED (Z_TYPE_P (op1 ) == IS_LONG )) {
@@ -486,20 +490,26 @@ static zend_always_inline int fast_increment_function(zval *op1)
486
490
"jno 0f\n\t"
487
491
"movl $0x0, (%0)\n\t"
488
492
"movl $0x41e00000, 0x4(%0)\n\t"
489
- "movb $0x2,0xc (%0)\n"
493
+ "movb %1, %c2 (%0)\n"
490
494
"0:"
491
495
:
492
- : "r" (op1 ));
496
+ : "r" (& op1 -> value ),
497
+ "n" (IS_DOUBLE ),
498
+ "n" (ZVAL_OFFSETOF_TYPE )
499
+ : "cc" );
493
500
#elif defined(__GNUC__ ) && defined(__x86_64__ )
494
501
__asm__(
495
502
"incq (%0)\n\t"
496
503
"jno 0f\n\t"
497
504
"movl $0x0, (%0)\n\t"
498
505
"movl $0x43e00000, 0x4(%0)\n\t"
499
- "movb $0x2,0x14 (%0)\n"
506
+ "movb %1, %c2 (%0)\n"
500
507
"0:"
501
508
:
502
- : "r" (op1 ));
509
+ : "r" (& op1 -> value ),
510
+ "n" (IS_DOUBLE ),
511
+ "n" (ZVAL_OFFSETOF_TYPE )
512
+ : "cc" );
503
513
#else
504
514
if (UNEXPECTED (Z_LVAL_P (op1 ) == LONG_MAX )) {
505
515
/* switch to double */
@@ -523,20 +533,26 @@ static zend_always_inline int fast_decrement_function(zval *op1)
523
533
"jno 0f\n\t"
524
534
"movl $0x00200000, (%0)\n\t"
525
535
"movl $0xc1e00000, 0x4(%0)\n\t"
526
- "movb $0x2,0xc (%0)\n"
536
+ "movb %1,%c2 (%0)\n"
527
537
"0:"
528
538
:
529
- : "r" (op1 ));
539
+ : "r" (& op1 -> value ),
540
+ "n" (IS_DOUBLE ),
541
+ "n" (ZVAL_OFFSETOF_TYPE )
542
+ : "cc" );
530
543
#elif defined(__GNUC__ ) && defined(__x86_64__ )
531
544
__asm__(
532
545
"decq (%0)\n\t"
533
546
"jno 0f\n\t"
534
547
"movl $0x00000000, (%0)\n\t"
535
548
"movl $0xc3e00000, 0x4(%0)\n\t"
536
- "movb $0x2,0x14 (%0)\n"
549
+ "movb %1,%c2 (%0)\n"
537
550
"0:"
538
551
:
539
- : "r" (op1 ));
552
+ : "r" (& op1 -> value ),
553
+ "n" (IS_DOUBLE ),
554
+ "n" (ZVAL_OFFSETOF_TYPE )
555
+ : "cc" );
540
556
#else
541
557
if (UNEXPECTED (Z_LVAL_P (op1 ) == LONG_MIN )) {
542
558
/* switch to double */
@@ -561,40 +577,46 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o
561
577
"addl (%2), %%eax\n\t"
562
578
"jo 0f\n\t"
563
579
"movl %%eax, (%0)\n\t"
564
- "movb $0x1,0xc (%0)\n\t"
580
+ "movb %3, %c5 (%0)\n\t"
565
581
"jmp 1f\n"
566
582
"0:\n\t"
567
583
"fildl (%1)\n\t"
568
584
"fildl (%2)\n\t"
569
585
"faddp %%st, %%st(1)\n\t"
570
- "movb $0x2,0xc (%0)\n\t"
586
+ "movb %4, %c5 (%0)\n\t"
571
587
"fstpl (%0)\n"
572
588
"1:"
573
589
:
574
- : "r" (result ),
575
- "r" (op1 ),
576
- "r" (op2 )
577
- : "eax" );
590
+ : "r" (& result -> value ),
591
+ "r" (& op1 -> value ),
592
+ "r" (& op2 -> value ),
593
+ "n" (IS_LONG ),
594
+ "n" (IS_DOUBLE ),
595
+ "n" (ZVAL_OFFSETOF_TYPE )
596
+ : "eax" ,"cc" );
578
597
#elif defined(__GNUC__ ) && defined(__x86_64__ )
579
598
__asm__(
580
599
"movq (%1), %%rax\n\t"
581
600
"addq (%2), %%rax\n\t"
582
601
"jo 0f\n\t"
583
602
"movq %%rax, (%0)\n\t"
584
- "movb $0x1,0x14 (%0)\n\t"
603
+ "movb %3, %c5 (%0)\n\t"
585
604
"jmp 1f\n"
586
605
"0:\n\t"
587
606
"fildq (%1)\n\t"
588
607
"fildq (%2)\n\t"
589
608
"faddp %%st, %%st(1)\n\t"
590
- "movb $0x2,0x14 (%0)\n\t"
609
+ "movb %4, %c5 (%0)\n\t"
591
610
"fstpl (%0)\n"
592
611
"1:"
593
612
:
594
- : "r" (result ),
595
- "r" (op1 ),
596
- "r" (op2 )
597
- : "rax" );
613
+ : "r" (& result -> value ),
614
+ "r" (& op1 -> value ),
615
+ "r" (& op2 -> value ),
616
+ "n" (IS_LONG ),
617
+ "n" (IS_DOUBLE ),
618
+ "n" (ZVAL_OFFSETOF_TYPE )
619
+ : "rax" ,"cc" );
598
620
#else
599
621
Z_LVAL_P (result ) = Z_LVAL_P (op1 ) + Z_LVAL_P (op2 );
600
622
@@ -636,7 +658,7 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o
636
658
"subl (%2), %%eax\n\t"
637
659
"jo 0f\n\t"
638
660
"movl %%eax, (%0)\n\t"
639
- "movb $0x1,0xc (%0)\n\t"
661
+ "movb %3, %c5 (%0)\n\t"
640
662
"jmp 1f\n"
641
663
"0:\n\t"
642
664
"fildl (%2)\n\t"
@@ -646,21 +668,24 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o
646
668
#else
647
669
"fsubp %%st, %%st(1)\n\t"
648
670
#endif
649
- "movb $0x2,0xc (%0)\n\t"
671
+ "movb %4, %c5 (%0)\n\t"
650
672
"fstpl (%0)\n"
651
673
"1:"
652
674
:
653
- : "r" (result ),
654
- "r" (op1 ),
655
- "r" (op2 )
656
- : "eax" );
675
+ : "r" (& result -> value ),
676
+ "r" (& op1 -> value ),
677
+ "r" (& op2 -> value ),
678
+ "n" (IS_LONG ),
679
+ "n" (IS_DOUBLE ),
680
+ "n" (ZVAL_OFFSETOF_TYPE )
681
+ : "eax" ,"cc" );
657
682
#elif defined(__GNUC__) && defined(__x86_64__)
658
683
__asm__(
659
684
"movq (%1), %%rax\n\t"
660
685
"subq (%2), %%rax\n\t"
661
686
"jo 0f\n\t"
662
687
"movq %%rax, (%0)\n\t"
663
- "movb $0x1,0x14 (%0)\n\t"
688
+ "movb %3, %c5 (%0)\n\t"
664
689
"jmp 1f\n"
665
690
"0:\n\t"
666
691
"fildq (%2)\n\t"
@@ -670,14 +695,17 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o
670
695
#else
671
696
"fsubp %%st, %%st(1)\n\t"
672
697
#endif
673
- "movb $0x2,0x14 (%0)\n\t"
698
+ "movb %4, %c5 (%0)\n\t"
674
699
"fstpl (%0)\n"
675
700
"1:"
676
701
:
677
- : "r" (result ),
678
- "r" (op1 ),
679
- "r" (op2 )
680
- : "rax" );
702
+ : "r" (& result -> value ),
703
+ "r" (& op1 -> value ),
704
+ "r" (& op2 -> value ),
705
+ "n" (IS_LONG ),
706
+ "n" (IS_DOUBLE ),
707
+ "n" (ZVAL_OFFSETOF_TYPE )
708
+ : "rax" ,"cc" );
681
709
#else
682
710
Z_LVAL_P (result ) = Z_LVAL_P (op1 ) - Z_LVAL_P (op2 );
683
711
0 commit comments