summaryrefslogtreecommitdiffstats
path: root/media/libvpx/vp8/encoder/x86/dct_mmx.asm
blob: 6f188cb94a865f8965883e66d9926907a7078a27 (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
;
;  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
;
;  Use of this source code is governed by a BSD-style license
;  that can be found in the LICENSE file in the root of the source
;  tree. An additional intellectual property rights grant can be found
;  in the file PATENTS.  All contributing project authors may
;  be found in the AUTHORS file in the root of the source tree.
;


%include "vpx_ports/x86_abi_support.asm"

;void vp8_short_fdct4x4_mmx(short *input, short *output, int pitch)
global sym(vp8_short_fdct4x4_mmx) PRIVATE
sym(vp8_short_fdct4x4_mmx):
    push        rbp
    mov         rbp,        rsp
    SHADOW_ARGS_TO_STACK 3
    GET_GOT     rbx
    push        rsi
    push        rdi
    ; end prolog

        mov         rsi,        arg(0)      ; input
        mov         rdi,        arg(1)      ; output

        movsxd      rax,        dword ptr arg(2) ;pitch

        lea         rcx,        [rsi + rax*2]
        ; read the input data
        movq        mm0,        [rsi]
        movq        mm1,        [rsi + rax]

        movq        mm2,        [rcx]
        movq        mm4,        [rcx + rax]

        ; transpose for the first stage
        movq        mm3,        mm0         ; 00 01 02 03
        movq        mm5,        mm2         ; 20 21 22 23

        punpcklwd   mm0,        mm1         ; 00 10 01 11
        punpckhwd   mm3,        mm1         ; 02 12 03 13

        punpcklwd   mm2,        mm4         ; 20 30 21 31
        punpckhwd   mm5,        mm4         ; 22 32 23 33

        movq        mm1,        mm0         ; 00 10 01 11
        punpckldq   mm0,        mm2         ; 00 10 20 30

        punpckhdq   mm1,        mm2         ; 01 11 21 31

        movq        mm2,        mm3         ; 02 12 03 13
        punpckldq   mm2,        mm5         ; 02 12 22 32

        punpckhdq   mm3,        mm5         ; 03 13 23 33

        ; mm0 0
        ; mm1 1
        ; mm2 2
        ; mm3 3

        ; first stage
        movq        mm5,        mm0
        movq        mm4,        mm1

        paddw       mm0,        mm3         ; a1 = 0 + 3
        paddw       mm1,        mm2         ; b1 = 1 + 2

        psubw       mm4,        mm2         ; c1 = 1 - 2
        psubw       mm5,        mm3         ; d1 = 0 - 3

        psllw       mm5,        3
        psllw       mm4,        3

        psllw       mm0,        3
        psllw       mm1,        3

        ; output 0 and 2
        movq        mm2,        mm0         ; a1

        paddw       mm0,        mm1         ; op[0] = a1 + b1
        psubw       mm2,        mm1         ; op[2] = a1 - b1

        ; output 1 and 3
        ; interleave c1, d1
        movq        mm1,        mm5         ; d1
        punpcklwd   mm1,        mm4         ; c1 d1
        punpckhwd   mm5,        mm4         ; c1 d1

        movq        mm3,        mm1
        movq        mm4,        mm5

        pmaddwd     mm1,        MMWORD PTR[GLOBAL (_5352_2217)]    ; c1*2217 + d1*5352
        pmaddwd     mm4,        MMWORD PTR[GLOBAL (_5352_2217)]    ; c1*2217 + d1*5352

        pmaddwd     mm3,        MMWORD PTR[GLOBAL(_2217_neg5352)]  ; d1*2217 - c1*5352
        pmaddwd     mm5,        MMWORD PTR[GLOBAL(_2217_neg5352)]  ; d1*2217 - c1*5352

        paddd       mm1,        MMWORD PTR[GLOBAL(_14500)]
        paddd       mm4,        MMWORD PTR[GLOBAL(_14500)]
        paddd       mm3,        MMWORD PTR[GLOBAL(_7500)]
        paddd       mm5,        MMWORD PTR[GLOBAL(_7500)]

        psrad       mm1,        12          ; (c1 * 2217 + d1 * 5352 +  14500)>>12
        psrad       mm4,        12          ; (c1 * 2217 + d1 * 5352 +  14500)>>12
        psrad       mm3,        12          ; (d1 * 2217 - c1 * 5352 +   7500)>>12
        psrad       mm5,        12          ; (d1 * 2217 - c1 * 5352 +   7500)>>12

        packssdw    mm1,        mm4         ; op[1]
        packssdw    mm3,        mm5         ; op[3]

        ; done with vertical
        ; transpose for the second stage
        movq        mm4,        mm0         ; 00 10 20 30
        movq        mm5,        mm2         ; 02 12 22 32

        punpcklwd   mm0,        mm1         ; 00 01 10 11
        punpckhwd   mm4,        mm1         ; 20 21 30 31

        punpcklwd   mm2,        mm3         ; 02 03 12 13
        punpckhwd   mm5,        mm3         ; 22 23 32 33

        movq        mm1,        mm0         ; 00 01 10 11
        punpckldq   mm0,        mm2         ; 00 01 02 03

        punpckhdq   mm1,        mm2         ; 01 22 12 13

        movq        mm2,        mm4         ; 20 31 30 31
        punpckldq   mm2,        mm5         ; 20 21 22 23

        punpckhdq   mm4,        mm5         ; 30 31 32 33

        ; mm0 0
        ; mm1 1
        ; mm2 2
        ; mm3 4

        movq        mm5,        mm0
        movq        mm3,        mm1

        paddw       mm0,        mm4         ; a1 = 0 + 3
        paddw       mm1,        mm2         ; b1 = 1 + 2

        psubw       mm3,        mm2         ; c1 = 1 - 2
        psubw       mm5,        mm4         ; d1 = 0 - 3

        pxor        mm6,        mm6         ; zero out for compare

        pcmpeqw     mm6,        mm5         ; d1 != 0

        pandn       mm6,        MMWORD PTR[GLOBAL(_cmp_mask)]   ; clear upper,
                                                                ; and keep bit 0 of lower

        ; output 0 and 2
        movq        mm2,        mm0         ; a1

        paddw       mm0,        mm1         ; a1 + b1
        psubw       mm2,        mm1         ; a1 - b1

        paddw       mm0,        MMWORD PTR[GLOBAL(_7w)]
        paddw       mm2,        MMWORD PTR[GLOBAL(_7w)]

        psraw       mm0,        4           ; op[0] = (a1 + b1 + 7)>>4
        psraw       mm2,        4           ; op[8] = (a1 - b1 + 7)>>4

        movq        MMWORD PTR[rdi + 0 ],  mm0
        movq        MMWORD PTR[rdi + 16],  mm2

        ; output 1 and 3
        ; interleave c1, d1
        movq        mm1,        mm5         ; d1
        punpcklwd   mm1,        mm3         ; c1 d1
        punpckhwd   mm5,        mm3         ; c1 d1

        movq        mm3,        mm1
        movq        mm4,        mm5

        pmaddwd     mm1,        MMWORD PTR[GLOBAL (_5352_2217)]    ; c1*2217 + d1*5352
        pmaddwd     mm4,        MMWORD PTR[GLOBAL (_5352_2217)]    ; c1*2217 + d1*5352

        pmaddwd     mm3,        MMWORD PTR[GLOBAL(_2217_neg5352)]  ; d1*2217 - c1*5352
        pmaddwd     mm5,        MMWORD PTR[GLOBAL(_2217_neg5352)]  ; d1*2217 - c1*5352

        paddd       mm1,        MMWORD PTR[GLOBAL(_12000)]
        paddd       mm4,        MMWORD PTR[GLOBAL(_12000)]
        paddd       mm3,        MMWORD PTR[GLOBAL(_51000)]
        paddd       mm5,        MMWORD PTR[GLOBAL(_51000)]

        psrad       mm1,        16          ; (c1 * 2217 + d1 * 5352 +  14500)>>16
        psrad       mm4,        16          ; (c1 * 2217 + d1 * 5352 +  14500)>>16
        psrad       mm3,        16          ; (d1 * 2217 - c1 * 5352 +   7500)>>16
        psrad       mm5,        16          ; (d1 * 2217 - c1 * 5352 +   7500)>>16

        packssdw    mm1,        mm4         ; op[4]
        packssdw    mm3,        mm5         ; op[12]

        paddw       mm1,        mm6         ; op[4] += (d1!=0)

        movq        MMWORD PTR[rdi + 8 ],  mm1
        movq        MMWORD PTR[rdi + 24],  mm3

     ; begin epilog
    pop         rdi
    pop         rsi
    RESTORE_GOT
    UNSHADOW_ARGS
    pop         rbp
    ret

SECTION_RODATA
align 8
_5352_2217:
    dw 5352
    dw 2217
    dw 5352
    dw 2217
align 8
_2217_neg5352:
    dw 2217
    dw -5352
    dw 2217
    dw -5352
align 8
_cmp_mask:
    times 4 dw 1
align 8
_7w:
    times 4 dw 7
align 8
_14500:
    times 2 dd 14500
align 8
_7500:
    times 2 dd 7500
align 8
_12000:
    times 2 dd 12000
align 8
_51000:
    times 2 dd 51000