summaryrefslogtreecommitdiffstats
path: root/src/mesa/x86/mmx_blendtmp.h
blob: 5d22f288a03639aba911e3209ad9af1502663698 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * Written by José Fonseca <j_r_fonseca@yahoo.co.uk>
 */


/*
 * void _mesa_mmx_blend( GLcontext *ctx,
 *                       GLuint n, 
 *                       const GLubyte mask[],
 *                       GLchan rgba[][4], 
 *                       CONST GLchan dest[][4] )
 * 
 */
ALIGNTEXT16
GLOBL GLNAME( TAG(_mesa_mmx_blend) )

GLNAME( TAG(_mesa_mmx_blend) ):

    PUSH_L     ( EBP )
    MOV_L      ( ESP, EBP )
    PUSH_L     ( ESI )
    PUSH_L     ( EDI )
    PUSH_L     ( EBX )

    MOV_L      ( REGOFF(12, EBP), ECX )		/* n */
    CMP_L      ( CONST(0), ECX)
    JE         ( LLTAG(GMB_return) )

    MOV_L      ( REGOFF(16, EBP), EBX )		/* mask */
    MOV_L      ( REGOFF(20, EBP), EDI )         /* rgba */
    MOV_L      ( REGOFF(24, EBP), ESI )         /* dest */

    INIT
    
    TEST_L     ( CONST(4), EDI )		/* align rgba on an 8-byte boundary */
    JZ         ( LLTAG(GMB_align_end) )

    CMP_B      ( CONST(0), REGIND(EBX) )	/* *mask == 0 */
    JE         ( LLTAG(GMB_align_continue) )

    /* runin */
#define ONE(x)	x
#define TWO(x)  
    MAIN       ( EDI, ESI )
#undef ONE
#undef TWO

LLTAG(GMB_align_continue):

    DEC_L      ( ECX )				/* n -= 1 */
    INC_L      ( EBX )		                /* mask += 1 */
    ADD_L      ( CONST(4), EDI )		/* rgba += 1 */
    ADD_L      ( CONST(4), ESI )		/* dest += 1 */ 

LLTAG(GMB_align_end):

    CMP_L      ( CONST(2), ECX)
    JB         ( LLTAG(GMB_loop_end) )

ALIGNTEXT16
LLTAG(GMB_loop_begin):

    CMP_W      ( CONST(0), REGIND(EBX) )	/* *mask == 0 && *(mask + 1) == 0 */
    JE         ( LLTAG(GMB_loop_continue) )

    /* main loop */
#define ONE(x)
#define TWO(x)	x
    MAIN       ( EDI, ESI )
#undef ONE
#undef TWO

LLTAG(GMB_loop_continue):

    DEC_L      ( ECX )
    DEC_L      ( ECX )				/* n -= 2 */
    ADD_L      ( CONST(2), EBX )		/* mask += 2 */
    ADD_L      ( CONST(8), EDI )		/* rgba += 2 */
    ADD_L      ( CONST(8), ESI )		/* dest += 2 */ 
    CMP_L      ( CONST(2), ECX )
    JAE        ( LLTAG(GMB_loop_begin) )

LLTAG(GMB_loop_end):

    CMP_L      ( CONST(1), ECX )
    JB         ( LLTAG(GMB_done) )

    CMP_B      ( CONST(0), REGIND(EBX) )	/* *mask == 0 */
    JE         ( LLTAG(GMB_done) )

    /* runout */
#define ONE(x)	x
#define TWO(x)
    MAIN       ( EDI, ESI )
#undef ONE
#undef TWO

LLTAG(GMB_done):

    EMMS

LLTAG(GMB_return):

    POP_L      ( EBX )
    POP_L      ( EDI )
    POP_L      ( ESI )
    MOV_L      ( EBP, ESP )
    POP_L      ( EBP )
    RET

#undef TAG
#undef LLTAG
#undef INIT
#undef MAIN