1 /*
2  * Written by José Fonseca <j_r_fonseca@yahoo.co.uk>
3  */
4 
5 
6 /*
7  * void _mesa_mmx_blend( struct gl_context *ctx,
8  *                       GLuint n,
9  *                       const GLubyte mask[],
10  *                       GLchan rgba[][4],
11  *                       CONST GLchan dest[][4] )
12  *
13  */
14 ALIGNTEXT16
15 GLOBL GLNAME( TAG(_mesa_mmx_blend) )
16 HIDDEN( TAG(_mesa_mmx_blend) )
17 GLNAME( TAG(_mesa_mmx_blend) ):
18     _CET_ENDBR
19     PUSH_L     ( EBP )
20     MOV_L      ( ESP, EBP )
21     PUSH_L     ( ESI )
22     PUSH_L     ( EDI )
23     PUSH_L     ( EBX )
24 
25     MOV_L      ( REGOFF(12, EBP), ECX )		/* n */
26     CMP_L      ( CONST(0), ECX)
27     JE         ( LLTAG(GMB_return) )
28 
29     MOV_L      ( REGOFF(16, EBP), EBX )		/* mask */
30     MOV_L      ( REGOFF(20, EBP), EDI )         /* rgba */
31     MOV_L      ( REGOFF(24, EBP), ESI )         /* dest */
32 
33     INIT
34 
35     TEST_L     ( CONST(4), EDI )		/* align rgba on an 8-byte boundary */
36     JZ         ( LLTAG(GMB_align_end) )
37 
38     CMP_B      ( CONST(0), REGIND(EBX) )	/* *mask == 0 */
39     JE         ( LLTAG(GMB_align_continue) )
40 
41     /* runin */
42 #define ONE(x)	x
43 #define TWO(x)
44     MAIN       ( EDI, ESI )
45 #undef ONE
46 #undef TWO
47 
48 LLTAG(GMB_align_continue):
49 
50     DEC_L      ( ECX )				/* n -= 1 */
51     INC_L      ( EBX )		                /* mask += 1 */
52     ADD_L      ( CONST(4), EDI )		/* rgba += 1 */
53     ADD_L      ( CONST(4), ESI )		/* dest += 1 */
54 
55 LLTAG(GMB_align_end):
56 
57     CMP_L      ( CONST(2), ECX)
58     JB         ( LLTAG(GMB_loop_end) )
59 
60 ALIGNTEXT16
61 LLTAG(GMB_loop_begin):
62 
63     CMP_W      ( CONST(0), REGIND(EBX) )	/* *mask == 0 && *(mask + 1) == 0 */
64     JE         ( LLTAG(GMB_loop_continue) )
65 
66     /* main loop */
67 #define ONE(x)
68 #define TWO(x)	x
69     MAIN       ( EDI, ESI )
70 #undef ONE
71 #undef TWO
72 
73 LLTAG(GMB_loop_continue):
74 
75     DEC_L      ( ECX )
76     DEC_L      ( ECX )				/* n -= 2 */
77     ADD_L      ( CONST(2), EBX )		/* mask += 2 */
78     ADD_L      ( CONST(8), EDI )		/* rgba += 2 */
79     ADD_L      ( CONST(8), ESI )		/* dest += 2 */
80     CMP_L      ( CONST(2), ECX )
81     JAE        ( LLTAG(GMB_loop_begin) )
82 
83 LLTAG(GMB_loop_end):
84 
85     CMP_L      ( CONST(1), ECX )
86     JB         ( LLTAG(GMB_done) )
87 
88     CMP_B      ( CONST(0), REGIND(EBX) )	/* *mask == 0 */
89     JE         ( LLTAG(GMB_done) )
90 
91     /* runout */
92 #define ONE(x)	x
93 #define TWO(x)
94     MAIN       ( EDI, ESI )
95 #undef ONE
96 #undef TWO
97 
98 LLTAG(GMB_done):
99 
100     EMMS
101 
102 LLTAG(GMB_return):
103 
104     POP_L      ( EBX )
105     POP_L      ( EDI )
106     POP_L      ( ESI )
107     MOV_L      ( EBP, ESP )
108     POP_L      ( EBP )
109     RET
110 
111 #undef TAG
112 #undef LLTAG
113 #undef INIT
114 #undef MAIN
115