Merge remote branch 'origin/opengl-es-v2'
[mesa.git] / src / mesa / x86 / mmx_blend.S
index ce946ec5ba0ce2603082e4deee5a75894c44fe49..eeaf43ea9370e9cd91558942877b746df4ff154d 100644 (file)
@@ -1,9 +1,12 @@
+       ;
 /*
- * Written by José Fonseca <j_r_fonseca@yahoo.co.uk>
+ * Written by Jos Fonseca <j_r_fonseca@yahoo.co.uk>
  */
 
-#include "matypes.h"
 
+#ifdef USE_MMX_ASM
+#include "assyntax.h"
+#include "matypes.h"
 
 /* integer multiplication - alpha plus one
  *
@@ -21,9 +24,9 @@
  */
 #define GMB_MULT_AP1( MP1, MA1, MP2, MA2, MX1 ) \
     PSUBW      ( MX1, MA1 )                    /*   a1 + 1  |   a1 + 1  |   a1 + 1  |   a1 + 1  */     ;\
-TWO(PSUBW      ( MX1, MA2 ))                   /*   a2 + 1  |   a2 + 1  |   a2 + 1  |   a2 + 1  */     ;\
-                                                                                                       ;\
     PMULLW     ( MP1, MA1 )                    /*                  t1 = p1*a1                   */     ;\
+                                                                                                       ;\
+TWO(PSUBW      ( MX1, MA2 ))                   /*   a2 + 1  |   a2 + 1  |   a2 + 1  |   a2 + 1  */     ;\
 TWO(PMULLW     ( MP2, MA2 ))                   /*                  t2 = p2*a2                   */     ;\
                                                                                                        ;\
     PSRLW      ( CONST(8), MA1 )               /*               t1 >> 8 ~= t1/255               */     ;\
@@ -48,15 +51,15 @@ TWO(PSRLW      ( CONST(8), MA2 ))           /*               t2 >> 8 ~= t2/255
 TWO(PMULLW     ( MP2, MA2 ))                   /*                  t2 = p2*a2                   */     ;\
                                                                                                        ;\
     MOVQ       ( MA1, MP1 )                                                                            ;\
-TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+    PSRLW      ( CONST(8), MA1 )               /*                    t1 >> 8                    */     ;\
                                                                                                        ;\
-    PSRLW      ( CONST(8), MP1 )               /*                    t1 >> 8                    */     ;\
-TWO(PSRLW      ( CONST(8), MP2 ))              /*                    t2 >> 8                    */     ;\
+TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+TWO(PSRLW      ( CONST(8), MA2 ))              /*                    t2 >> 8                    */     ;\
                                                                                                        ;\
     PADDW      ( MP1, MA1 )                    /*        t1 + (t1 >> 8) ~= (t1/255) << 8        */     ;\
-TWO(PADDW      ( MP2, MA2 ))                   /*        t2 + (t2 >> 8) ~= (t2/255) << 8        */     ;\
-                                                                                                       ;\
     PSRLW      ( CONST(8), MA1 )               /*    sa1    |    sb1    |    sg1    |    sr1    */     ;\
+                                                                                                       ;\
+TWO(PADDW      ( MP2, MA2 ))                   /*        t2 + (t2 >> 8) ~= (t2/255) << 8        */     ;\
 TWO(PSRLW      ( CONST(8), MA2 ))              /*    sa2    |    sb2    |    sg2    |    sr2    */
 
 
@@ -73,21 +76,21 @@ TWO(PSRLW      ( CONST(8), MA2 ))           /*    sa2    |    sb2    |    sg2    |    sr2
  */
 #define GMB_MULT_GSR( MP1, MA1, MP2, MA2, M80 ) \
     PMULLW     ( MP1, MA1 )                    /*                  t1 = p1*a1                   */     ;\
-TWO(PMULLW     ( MP2, MA2 ))                   /*                  t2 = p2*a2                   */     ;\
-                                                                                                       ;\
     PADDW      ( M80, MA1 )                    /*                 t1 += 0x80                    */     ;\
+                                                                                                       ;\
+TWO(PMULLW     ( MP2, MA2 ))                   /*                  t2 = p2*a2                   */     ;\
 TWO(PADDW      ( M80, MA2 ))                   /*                 t2 += 0x80                    */     ;\
                                                                                                        ;\
     MOVQ       ( MA1, MP1 )                                                                            ;\
-TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+    PSRLW      ( CONST(8), MA1 )               /*                    t1 >> 8                    */     ;\
                                                                                                        ;\
-    PSRLW      ( CONST(8), MP1 )               /*                    t1 >> 8                    */     ;\
-TWO(PSRLW      ( CONST(8), MP2 ))              /*                    t2 >> 8                    */     ;\
+TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+TWO(PSRLW      ( CONST(8), MA2 ))              /*                    t2 >> 8                    */     ;\
                                                                                                        ;\
     PADDW      ( MP1, MA1 )                    /*        t1 + (t1 >> 8) ~= (t1/255) << 8        */     ;\
-TWO(PADDW      ( MP2, MA2 ))                   /*        t2 + (t2 >> 8) ~= (t2/255) << 8        */     ;\
-                                                                                                       ;\
     PSRLW      ( CONST(8), MA1 )               /*    sa1    |    sb1    |    sg1    |    sr1    */     ;\
+                                                                                                       ;\
+TWO(PADDW      ( MP2, MA2 ))                   /*        t2 + (t2 >> 8) ~= (t2/255) << 8        */     ;\
 TWO(PSRLW      ( CONST(8), MA2 ))              /*    sa2    |    sb2    |    sg2    |    sr2    */
 
 
@@ -95,19 +98,18 @@ TWO(PSRLW      ( CONST(8), MA2 ))           /*    sa2    |    sb2    |    sg2    |    sr2
  */
 #define GMB_LERP_GS( MP1, MQ1, MA1, MP2, MQ2, MA2) \
     PSUBW      ( MQ1, MP1 )                     /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */    ;\
-TWO(PSUBW      ( MQ2, MP2 ))                    /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */    ;\
-                                                                                                       ;\
     PSLLW      ( CONST(8), MQ1 )               /*                    q1 << 8                    */     ;\
-TWO(PSLLW      ( CONST(8), MQ2 ))              /*                    q2 << 8                    */     ;\
-                                                                                                       ;\
     PMULLW     ( MP1, MA1 )                    /*              t1 = (q1 - p1)*pa1               */     ;\
+                                                                                                       ;\
+TWO(PSUBW      ( MQ2, MP2 ))                    /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */    ;\
+TWO(PSLLW      ( CONST(8), MQ2 ))              /*                    q2 << 8                    */     ;\
 TWO(PMULLW     ( MP2, MA2 ))                   /*              t2 = (q2 - p2)*pa2               */     ;\
                                                                                                        ;\
     MOVQ       ( MA1, MP1 )                                                                            ;\
-TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+    PSRLW      ( CONST(8), MA1 )               /*                    t1 >> 8                    */     ;\
                                                                                                        ;\
-    PSRLW      ( CONST(8), MP1 )               /*                    t1 >> 8                    */     ;\
-TWO(PSRLW      ( CONST(8), MP2 ))              /*                    t2 >> 8                    */     ;\
+TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+TWO(PSRLW      ( CONST(8), MA2 ))              /*                    t2 >> 8                    */     ;\
                                                                                                        ;\
     PADDW      ( MP1, MA1 )                    /*        t1 + (t1 >> 8) ~= (t1/255) << 8        */     ;\
 TWO(PADDW      ( MP2, MA2 ))                   /*        t2 + (t2 >> 8) ~= (t2/255) << 8        */     ;\
@@ -127,12 +129,11 @@ TWO(PSRLW      ( CONST(8), MA2 ))         /*    sa2    |    sb2    |    sg2    |    sr2
  */
 #define GMB_LERP_GSR( MP1, MQ1, MA1, MP2, MQ2, MA2, M80) \
     PSUBW      ( MQ1, MP1 )                     /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */    ;\
-TWO(PSUBW      ( MQ2, MP2 ))                    /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */    ;\
-                                                                                                       ;\
     PSLLW      ( CONST(8), MQ1 )               /*                    q1 << 8                    */     ;\
-TWO(PSLLW      ( CONST(8), MQ2 ))              /*                    q2 << 8                    */     ;\
-                                                                                                       ;\
     PMULLW     ( MP1, MA1 )                    /*              t1 = (q1 - p1)*pa1               */     ;\
+                                                                                                       ;\
+TWO(PSUBW      ( MQ2, MP2 ))                    /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */    ;\
+TWO(PSLLW      ( CONST(8), MQ2 ))              /*                    q2 << 8                    */     ;\
 TWO(PMULLW     ( MP2, MA2 ))                   /*              t2 = (q2 - p2)*pa2               */     ;\
                                                                                                        ;\
     PSRLW      ( CONST(15), MP1 )              /*                 q1 > p1 ? 1 : 0               */     ;\
@@ -148,10 +149,10 @@ TWO(PSUBW      ( MP2, MA2 ))                      /*                  t2 -=? 0x100
 TWO(PADDW      ( M80, MA2 ))                   /*                 t2 += 0x80                    */     ;\
                                                                                                        ;\
     MOVQ       ( MA1, MP1 )                                                                            ;\
-TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+    PSRLW      ( CONST(8), MA1 )               /*                    t1 >> 8                    */     ;\
                                                                                                        ;\
-    PSRLW      ( CONST(8), MP1 )               /*                    t1 >> 8                    */     ;\
-TWO(PSRLW      ( CONST(8), MP2 ))              /*                    t2 >> 8                    */     ;\
+TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+TWO(PSRLW      ( CONST(8), MA2 ))              /*                    t2 >> 8                    */     ;\
                                                                                                        ;\
     PADDW      ( MP1, MA1 )                    /*        t1 + (t1 >> 8) ~= (t1/255) << 8        */     ;\
 TWO(PADDW      ( MP2, MA2 ))                   /*        t2 + (t2 >> 8) ~= (t2/255) << 8        */     ;\
@@ -173,25 +174,24 @@ TWO(PSRLW      ( CONST(8), MA2 ))         /*    sa2    |    sb2    |    sg2    |    sr2
  */
 #define GMB_LERP_GSC( MP1, MQ1, MA1, MP2, MQ2, MA2) \
     PSUBW      ( MQ1, MP1 )                     /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */    ;\
-TWO(PSUBW      ( MQ2, MP2 ))                    /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */    ;\
-                                                                                                       ;\
     PSLLW      ( CONST(8), MQ1 )               /*                    q1 << 8                    */     ;\
-TWO(PSLLW      ( CONST(8), MQ2 ))              /*                    q2 << 8                    */     ;\
-                                                                                                       ;\
     PMULLW     ( MP1, MA1 )                    /*              t1 = (q1 - p1)*pa1               */     ;\
+                                                                                                       ;\
+TWO(PSUBW      ( MQ2, MP2 ))                    /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */    ;\
+TWO(PSLLW      ( CONST(8), MQ2 ))              /*                    q2 << 8                    */     ;\
 TWO(PMULLW     ( MP2, MA2 ))                   /*              t2 = (q2 - p2)*pa2               */     ;\
                                                                                                        ;\
     MOVQ       ( MA1, MP1 )                                                                            ;\
-TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+    PSRLW      ( CONST(8), MA1 )               /*                    t1 >> 8                    */     ;\
                                                                                                        ;\
-    PSRLW      ( CONST(8), MP1 )               /*                    t1 >> 8                    */     ;\
-TWO(PSRLW      ( CONST(8), MP2 ))              /*                    t2 >> 8                    */     ;\
+TWO(MOVQ       ( MA2, MP2 ))                                                                           ;\
+TWO(PSRLW      ( CONST(8), MA2 ))              /*                    t2 >> 8                    */     ;\
                                                                                                        ;\
-    PADDW      ( MP1, MA1 )                    /*        t1 + (t1 >> 8) ~= (t1/255) << 8        */     ;\
-TWO(PADDW      ( MP2, MA2 ))                   /*        t2 + (t2 >> 8) ~= (t2/255) << 8        */     ;\
+    PADDW      ( MA1, MP1 )                    /*        t1 + (t1 >> 8) ~= (t1/255) << 8        */     ;\
+    PSRLW      ( CONST(7), MA1 )               /*                    t1 >> 15                   */     ;\
                                                                                                        ;\
-    PSRLW      ( CONST(7), MP1 )               /*                    t1 >> 15                   */     ;\
-TWO(PSRLW      ( CONST(7), MP2 ))              /*                    t2 >> 15                   */     ;\
+TWO(PADDW      ( MA2, MP2 ))                   /*        t2 + (t2 >> 8) ~= (t2/255) << 8        */     ;\
+TWO(PSRLW      ( CONST(7), MA2 ))              /*                    t2 >> 15                   */     ;\
                                                                                                        ;\
     PADDW      ( MP1, MA1 )                    /*  t1 + (t1 >> 8) + (t1 >>15) ~= (t1/255) << 8  */     ;\
 TWO(PADDW      ( MP2, MA2 ))                   /*  t2 + (t2 >> 8) + (t2 >>15) ~= (t2/255) << 8  */     ;\
@@ -238,23 +238,34 @@ TWO(PUNPCKHDQ  ( MA2, MA2 ))                    /*    pa2    |    pa2    |    pa
     PACKUSWB   ( MS2, MS1 )                    /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */     ;\
 
 #define GMB_STORE(rgba, MSS ) \
-ONE(MOVD       ( MSS, REGIND(rgba) ))                                                                  ;\
-TWO(MOVQ       ( MSS, REGIND(rgba) ))
-
+ONE(MOVD       ( MSS, REGIND(rgba) ))          /*     |     |     |     | sa1 | sb1 | sg1 | sr1 */     ;\
+TWO(MOVQ       ( MSS, REGIND(rgba) ))          /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */
 
+/* Kevin F. Quinn <kevquinn@gentoo.org> 2 July 2006
+ * Replace data segment constants with text-segment
+ * constants (via pushl/movq)
     SEG_DATA
 
 ALIGNDATA8
+const_0080:
+    D_LONG 0x00800080, 0x00800080
+
 const_80:
-       D_LONG 0x00800080, 0x00800080
+    D_LONG 0x80808080, 0x80808080
+*/
+#define const_0080_l 0x00800080
+#define const_0080_h 0x00800080
+#define const_80_l 0x80808080
+#define const_80_h 0x80808080
 
     SEG_TEXT
 
 
-/* common transparency blending mode
+/* Blend transparency function
  */
 
-#define TAG(x) x##_transparency
+#define TAG(x) CONCAT(x,_transparency)
+#define LLTAG(x) LLBL2(x,_transparency)
 
 #define INIT \
     PXOR       ( MM0, MM0 )                    /*   0x0000  |   0x0000  |   0x0000  |   0x0000  */
@@ -270,14 +281,110 @@ const_80:
 #include "mmx_blendtmp.h"
 
 
-/* modulate
+/* Blend add function
+ *
+ * FIXME: Add some loop unrolling here...
+ */
+
+#define TAG(x) CONCAT(x,_add)
+#define LLTAG(x) LLBL2(x,_add)
+
+#define INIT
+
+#define MAIN( rgba, dest ) \
+ONE(MOVD       ( REGIND(rgba), MM1 ))          /*     |     |     |     | qa1 | qb1 | qg1 | qr1 */     ;\
+ONE(MOVD       ( REGIND(dest), MM2 ))          /*     |     |     |     | pa1 | pb1 | pg1 | pr1 */     ;\
+ONE(PADDUSB    ( MM2, MM1 ))                                                                           ;\
+ONE(MOVD       ( MM1, REGIND(rgba) ))          /*     |     |     |     | sa1 | sb1 | sg1 | sr1 */     ;\
+                                                                                                       ;\
+TWO(MOVQ       ( REGIND(rgba), MM1 ))          /* qa2 | qb2 | qg2 | qr2 | qa1 | qb1 | qg1 | qr1 */     ;\
+TWO(PADDUSB    ( REGIND(dest), MM1 ))          /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */     ;\
+TWO(MOVQ       ( MM1, REGIND(rgba) ))
+
+#include "mmx_blendtmp.h"
+
+
+/* Blend min function
+ */
+
+#define TAG(x) CONCAT(x,_min)
+#define LLTAG(x) LLBL2(x,_min)
+
+/* Kevin F. Quinn 2nd July 2006
+ * Replace data segment constants with text-segment instructions
+#define INIT \
+    MOVQ       ( CONTENT(const_80), MM7 )
+ */
+#define INIT \
+    PUSH_L     ( CONST(const_80_h) )           /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/     ;\
+    PUSH_L     ( CONST(const_80_l) )                                                                   ;\
+    MOVQ       ( REGIND(ESP), MM7 )                                                                    ;\
+    ADD_L      ( CONST(8), ESP)
+
+#define MAIN( rgba, dest ) \
+    GMB_LOAD( rgba, dest, MM1, MM2 )                                                                   ;\
+    MOVQ       ( MM1, MM3 )                                                                            ;\
+    MOVQ       ( MM2, MM4 )                                                                            ;\
+    PXOR       ( MM7, MM3 )                    /*              unsigned -> signed               */     ;\
+    PXOR       ( MM7, MM4 )                    /*              unsigned -> signed               */     ;\
+    PCMPGTB    ( MM3, MM4 )                    /*                 q > p ? 0xff : 0x00           */     ;\
+    PAND       ( MM4, MM1 )                    /*                 q > p ? p : 0                 */     ;\
+    PANDN      ( MM2, MM4 )                    /*                 q > p ? 0 : q                 */     ;\
+    POR        ( MM1, MM4 )                    /*                 q > p ? p : q                 */     ;\
+    GMB_STORE( rgba, MM4 )
+
+#include "mmx_blendtmp.h"
+
+
+/* Blend max function
  */
 
-#define TAG(x) x##_modulate
+#define TAG(x) CONCAT(x,_max)
+#define LLTAG(x) LLBL2(x,_max)
+
+/* Kevin F. Quinn 2nd July 2006
+ * Replace data segment constants with text-segment instructions
+#define INIT \
+    MOVQ       ( CONTENT(const_80), MM7 )
+ */
+#define INIT \
+    PUSH_L     ( CONST(const_80_l) )           /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/     ;\
+    PUSH_L     ( CONST(const_80_h) )                                                                   ;\
+    MOVQ       ( REGIND(ESP), MM7 )                                                                    ;\
+    ADD_L      ( CONST(8), ESP)
 
+#define MAIN( rgba, dest ) \
+    GMB_LOAD( rgba, dest, MM1, MM2 )                                                                   ;\
+    MOVQ       ( MM1, MM3 )                                                                            ;\
+    MOVQ       ( MM2, MM4 )                                                                            ;\
+    PXOR       ( MM7, MM3 )                    /*              unsigned -> signed               */     ;\
+    PXOR       ( MM7, MM4 )                    /*              unsigned -> signed               */     ;\
+    PCMPGTB    ( MM3, MM4 )                    /*                 q > p ? 0xff : 0x00           */     ;\
+    PAND       ( MM4, MM2 )                    /*                 q > p ? q : 0                 */     ;\
+    PANDN      ( MM1, MM4 )                    /*                 q > p ? 0 : p                 */     ;\
+    POR        ( MM2, MM4 )                    /*                 q > p ? p : q                 */     ;\
+    GMB_STORE( rgba, MM4 )
+
+#include "mmx_blendtmp.h"
+
+
+/* Blend modulate function
+ */
+
+#define TAG(x) CONCAT(x,_modulate)
+#define LLTAG(x) LLBL2(x,_modulate)
+
+/* Kevin F. Quinn 2nd July 2006
+ * Replace data segment constants with text-segment instructions
+#define INIT \
+    MOVQ       ( CONTENT(const_0080), MM7 )
+ */
 #define INIT \
     PXOR       ( MM0, MM0 )                    /*   0x0000  |   0x0000  |   0x0000  |   0x0000  */     ;\
-    MOVQ       ( CONTENT(const_80), MM7 )      /*   0xffff  |   0xffff  |   0xffff  |   0xffff  */
+    PUSH_L     ( CONST(const_0080_l) )         /*   0x0080  |   0x0080  |   0x0080  |   0x0080  */     ;\
+    PUSH_L     ( CONST(const_0080_h) )                                                                 ;\
+    MOVQ       ( REGIND(ESP), MM7 )                                                                    ;\
+    ADD_L      ( CONST(8), ESP)
 
 #define MAIN( rgba, dest ) \
     GMB_LOAD( rgba, dest, MM1, MM2 )                                                                   ;\
@@ -288,3 +395,8 @@ const_80:
 
 #include "mmx_blendtmp.h"
 
+#endif
+       
+#if defined (__ELF__) && defined (__linux__)
+       .section .note.GNU-stack,"",%progbits
+#endif