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 */
14ALIGNTEXT16
15GLOBL GLNAME( TAG(_mesa_mmx_blend) )
16HIDDEN( TAG(_mesa_mmx_blend) )
17GLNAME( TAG(_mesa_mmx_blend) ):
18
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
48LLTAG(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
55LLTAG(GMB_align_end):
56
57    CMP_L      ( CONST(2), ECX)
58    JB         ( LLTAG(GMB_loop_end) )
59
60ALIGNTEXT16
61LLTAG(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
73LLTAG(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
83LLTAG(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
98LLTAG(GMB_done):
99
100    EMMS
101
102LLTAG(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