[svn] / trunk / xvidcore / src / image / x86_asm / interpolate8x8_mmx.asm Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/image/x86_asm/interpolate8x8_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1519, Sat Jul 24 11:46:08 2004 UTC revision 1793, Tue Nov 11 20:46:24 2008 UTC
# Line 26  Line 26 
26    
27  %macro cglobal 1  %macro cglobal 1
28          %ifdef PREFIX          %ifdef PREFIX
29                    %ifdef MARK_FUNCS
30                            global _%1:function %1.endfunc-%1
31                            %define %1 _%1:function %1.endfunc-%1
32                            %define ENDFUNC .endfunc
33                    %else
34                  global _%1                  global _%1
35                  %define %1 _%1                  %define %1 _%1
36                            %define ENDFUNC
37                    %endif
38            %else
39                    %ifdef MARK_FUNCS
40                            global %1:function %1.endfunc-%1
41                            %define ENDFUNC .endfunc
42          %else          %else
43                  global %1                  global %1
44                            %define ENDFUNC
45                    %endif
46          %endif          %endif
47  %endmacro  %endmacro
48    
# Line 95  Line 108 
108  cglobal interpolate8x8_halfpel_h_mmx  cglobal interpolate8x8_halfpel_h_mmx
109  cglobal interpolate8x8_halfpel_v_mmx  cglobal interpolate8x8_halfpel_v_mmx
110  cglobal interpolate8x8_halfpel_hv_mmx  cglobal interpolate8x8_halfpel_hv_mmx
111    
112    cglobal interpolate8x4_halfpel_h_mmx
113    cglobal interpolate8x4_halfpel_v_mmx
114    cglobal interpolate8x4_halfpel_hv_mmx
115    
116  cglobal interpolate8x8_avg4_mmx  cglobal interpolate8x8_avg4_mmx
117  cglobal interpolate8x8_avg2_mmx  cglobal interpolate8x8_avg2_mmx
118    
119  cglobal interpolate8x8_6tap_lowpass_h_mmx  cglobal interpolate8x8_6tap_lowpass_h_mmx
120  cglobal interpolate8x8_6tap_lowpass_v_mmx  cglobal interpolate8x8_6tap_lowpass_v_mmx
121    
122    cglobal interpolate8x8_halfpel_add_mmx
123    cglobal interpolate8x8_halfpel_h_add_mmx
124    cglobal interpolate8x8_halfpel_v_add_mmx
125    cglobal interpolate8x8_halfpel_hv_add_mmx
126    
127  %macro  CALC_AVG 6  %macro  CALC_AVG 6
128    punpcklbw %3, %6    punpcklbw %3, %6
129    punpckhbw %4, %6    punpckhbw %4, %6
# Line 169  Line 193 
193    pop esi    pop esi
194    
195    ret    ret
196    ENDFUNC
197    
198    
199  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 228  Line 253 
253    pop esi    pop esi
254    
255    ret    ret
256    ENDFUNC
257    
258    
259  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 319  Line 345 
345    pop esi    pop esi
346    
347    ret    ret
348    ENDFUNC
349    
350    ;-----------------------------------------------------------------------------
351    ;
352    ; void interpolate8x4_halfpel_h_mmx(uint8_t * const dst,
353    ;                       const uint8_t * const src,
354    ;                       const uint32_t stride,
355    ;                       const uint32_t rounding);
356    ;
357    ;-----------------------------------------------------------------------------
358    
359    ALIGN 16
360    interpolate8x4_halfpel_h_mmx:
361    
362      push esi
363      push edi
364      mov eax, [esp + 8 + 16]       ; rounding
365    
366      movq mm7, [rounding1_mmx + eax * 8]
367    
368      mov edi, [esp + 8 + 4]        ; dst
369      mov esi, [esp + 8 + 8]        ; src
370      mov edx, [esp + 8 + 12]       ; stride
371    
372      pxor mm6, mm6                 ; zero
373    
374      COPY_H_MMX
375      COPY_H_MMX
376      COPY_H_MMX
377      COPY_H_MMX
378    
379      pop edi
380      pop esi
381    
382      ret
383    ENDFUNC
384    
385    
386    ;-----------------------------------------------------------------------------
387    ;
388    ; void interpolate8x4_halfpel_v_mmx(uint8_t * const dst,
389    ;                       const uint8_t * const src,
390    ;                       const uint32_t stride,
391    ;                       const uint32_t rounding);
392    ;
393    ;-----------------------------------------------------------------------------
394    
395    ALIGN 16
396    interpolate8x4_halfpel_v_mmx:
397    
398      push esi
399      push edi
400    
401      mov eax, [esp + 8 + 16]       ; rounding
402    
403      movq mm7, [rounding1_mmx + eax * 8]
404    
405      mov edi, [esp + 8 + 4]        ; dst
406      mov esi, [esp + 8 + 8]        ; src
407      mov edx, [esp + 8 + 12]       ; stride
408    
409      pxor mm6, mm6                 ; zero
410    
411    
412      COPY_V_MMX
413      COPY_V_MMX
414      COPY_V_MMX
415      COPY_V_MMX
416    
417      pop edi
418      pop esi
419    
420      ret
421    ENDFUNC
422    
423    
424    ;-----------------------------------------------------------------------------
425    ;
426    ; void interpolate8x4_halfpel_hv_mmx(uint8_t * const dst,
427    ;                       const uint8_t * const src,
428    ;                       const uint32_t stride,
429    ;                       const uint32_t rounding);
430    ;
431    ;
432    ;-----------------------------------------------------------------------------
433    
434    ALIGN 16
435    interpolate8x4_halfpel_hv_mmx:
436    
437      push esi
438      push edi
439    
440      mov eax, [esp + 8 + 16]   ; rounding
441    
442      movq mm7, [rounding2_mmx + eax * 8]
443    
444      mov edi, [esp + 8 + 4]    ; dst
445      mov esi, [esp + 8 + 8]    ; src
446    
447      mov eax, 8
448    
449      pxor mm6, mm6             ; zero
450    
451      mov edx, [esp + 8 + 12]   ; stride
452    
453      COPY_HV_MMX
454      COPY_HV_MMX
455      COPY_HV_MMX
456      COPY_HV_MMX
457    
458      pop edi
459      pop esi
460    
461      ret
462    ENDFUNC
463    
464  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
465  ;  ;
# Line 451  Line 592 
592    AVG2_MMX_RND0    AVG2_MMX_RND0
593    lea ecx, [ecx+2*edx]    lea ecx, [ecx+2*edx]
594    
595  .start0  .start0:
596    
597    AVG2_MMX_RND0    AVG2_MMX_RND0
598    lea ecx, [ecx+2*edx]    lea ecx, [ecx+2*edx]
# Line 464  Line 605 
605    pop ebx    pop ebx
606    ret    ret
607    
608  .rounding1  .rounding1:
609    mov eax, [esp + 4 + 24]       ; height -> eax    mov eax, [esp + 4 + 24]       ; height -> eax
610    sub eax, 8    sub eax, 8
611    test eax, eax    test eax, eax
# Line 481  Line 622 
622    AVG2_MMX_RND1    AVG2_MMX_RND1
623    lea ecx, [ecx+2*edx]    lea ecx, [ecx+2*edx]
624    
625  .start1  .start1:
626    
627    AVG2_MMX_RND1    AVG2_MMX_RND1
628    lea ecx, [ecx+2*edx]    lea ecx, [ecx+2*edx]
# Line 493  Line 634 
634    
635    pop ebx    pop ebx
636    ret    ret
637    ENDFUNC
638    
639    
640  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 660  Line 802 
802    pop ebx    pop ebx
803    ret    ret
804    
805  .rounding1  .rounding1:
806    AVG4_MMX_RND1    AVG4_MMX_RND1
807    lea ecx, [ecx+edx]    lea ecx, [ecx+edx]
808    AVG4_MMX_RND1    AVG4_MMX_RND1
# Line 681  Line 823 
823    pop edi    pop edi
824    pop ebx    pop ebx
825    ret    ret
826    ENDFUNC
827    
828    
829  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 791  Line 934 
934    LOWPASS_6TAP_H_MMX    LOWPASS_6TAP_H_MMX
935    
936    ret    ret
937    ENDFUNC
938    
939  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
940  ;  ;
# Line 908  Line 1052 
1052    
1053    pop ebx    pop ebx
1054    ret    ret
1055    ENDFUNC
1056    
1057    ;===========================================================================
1058    ;
1059    ; The next functions combine both source halfpel interpolation step and the
1060    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
1061    ; intermediate halfpel images and then averaging them.
1062    ;
1063    ;===========================================================================
1064    
1065    %macro PROLOG0 0
1066      mov ecx, [esp+ 4] ; Dst
1067      mov eax, [esp+ 8] ; Src
1068      mov edx, [esp+12] ; BpS
1069    %endmacro
1070    
1071    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
1072      pxor mm6, mm6
1073      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
1074    %if %2
1075      movq mm5, [rounding1_mmx]
1076    %endif
1077    
1078      PROLOG0
1079    %endmacro
1080    
1081      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
1082    %macro MIX 0
1083      punpcklbw mm0, mm6
1084      punpcklbw mm2, mm6
1085      punpckhbw mm1, mm6
1086      punpckhbw mm3, mm6
1087      paddusw mm0, mm2
1088      paddusw mm1, mm3
1089    %endmacro
1090    
1091    %macro MIX_DST 0
1092      movq mm3, mm2
1093      paddusw mm0, mm7  ; rounder
1094      paddusw mm1, mm7  ; rounder
1095      punpcklbw mm2, mm6
1096      punpckhbw mm3, mm6
1097      psrlw mm0, 1
1098      psrlw mm1, 1
1099    
1100      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1101      paddusw mm1, mm3
1102      paddusw mm0, mm5
1103      paddusw mm1, mm5
1104      psrlw mm0, 1
1105      psrlw mm1, 1
1106    
1107      packuswb mm0, mm1
1108    %endmacro
1109    
1110    %macro MIX2 0
1111      punpcklbw mm0, mm6
1112      punpcklbw mm2, mm6
1113      paddusw mm0, mm2
1114      paddusw mm0, mm7
1115      punpckhbw mm1, mm6
1116      punpckhbw mm3, mm6
1117      paddusw mm1, mm7
1118      paddusw mm1, mm3
1119      psrlw mm0, 1
1120      psrlw mm1, 1
1121    
1122      packuswb mm0, mm1
1123    %endmacro
1124    
1125    ;===========================================================================
1126    ;
1127    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1128    ;                       const uint8_t * const src,
1129    ;                       const uint32_t stride,
1130    ;                       const uint32_t rounding);
1131    ;
1132    ;
1133    ;===========================================================================
1134    
1135    %macro ADD_FF_MMX 1
1136      movq mm0, [eax]
1137      movq mm2, [ecx]
1138      movq mm1, mm0
1139      movq mm3, mm2
1140    %if (%1!=0)
1141      lea eax,[eax+%1*edx]
1142    %endif
1143      MIX
1144      paddusw mm0, mm5  ; rounder
1145      paddusw mm1, mm5  ; rounder
1146      psrlw mm0, 1
1147      psrlw mm1, 1
1148    
1149      packuswb mm0, mm1
1150      movq [ecx], mm0
1151    %if (%1!=0)
1152      lea ecx,[ecx+%1*edx]
1153    %endif
1154    %endmacro
1155    
1156    ALIGN 16
1157    interpolate8x8_halfpel_add_mmx:
1158      PROLOG rounding1_mmx, 1
1159      ADD_FF_MMX 1
1160      ADD_FF_MMX 1
1161      ADD_FF_MMX 1
1162      ADD_FF_MMX 1
1163      ADD_FF_MMX 1
1164      ADD_FF_MMX 1
1165      ADD_FF_MMX 1
1166      ADD_FF_MMX 0
1167      ret
1168    ENDFUNC
1169    
1170    ;===========================================================================
1171    ;
1172    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1173    ;                       const uint8_t * const src,
1174    ;                       const uint32_t stride,
1175    ;                       const uint32_t rounding);
1176    ;
1177    ;
1178    ;===========================================================================
1179    
1180    %macro ADD_FH_MMX 0
1181      movq mm0, [eax]
1182      movq mm2, [eax+1]
1183      movq mm1, mm0
1184      movq mm3, mm2
1185    
1186      lea eax,[eax+edx]
1187    
1188      MIX
1189      movq mm2, [ecx]   ; prepare mix with Dst[0]
1190      MIX_DST
1191      movq [ecx], mm0
1192    %endmacro
1193    
1194    ALIGN 16
1195    interpolate8x8_halfpel_h_add_mmx:
1196      PROLOG rounding1_mmx, 1
1197    
1198      ADD_FH_MMX
1199      lea ecx,[ecx+edx]
1200      ADD_FH_MMX
1201      lea ecx,[ecx+edx]
1202      ADD_FH_MMX
1203      lea ecx,[ecx+edx]
1204      ADD_FH_MMX
1205      lea ecx,[ecx+edx]
1206      ADD_FH_MMX
1207      lea ecx,[ecx+edx]
1208      ADD_FH_MMX
1209      lea ecx,[ecx+edx]
1210      ADD_FH_MMX
1211      lea ecx,[ecx+edx]
1212      ADD_FH_MMX
1213      ret
1214    ENDFUNC
1215    
1216    ;===========================================================================
1217    ;
1218    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1219    ;                       const uint8_t * const src,
1220    ;                       const uint32_t stride,
1221    ;                       const uint32_t rounding);
1222    ;
1223    ;
1224    ;===========================================================================
1225    
1226    %macro ADD_HF_MMX 0
1227      movq mm0, [eax]
1228      movq mm2, [eax+edx]
1229      movq mm1, mm0
1230      movq mm3, mm2
1231    
1232      lea eax,[eax+edx]
1233    
1234      MIX
1235      movq mm2, [ecx]   ; prepare mix with Dst[0]
1236      MIX_DST
1237      movq [ecx], mm0
1238    
1239    %endmacro
1240    
1241    ALIGN 16
1242    interpolate8x8_halfpel_v_add_mmx:
1243      PROLOG rounding1_mmx, 1
1244    
1245      ADD_HF_MMX
1246      lea ecx,[ecx+edx]
1247      ADD_HF_MMX
1248      lea ecx,[ecx+edx]
1249      ADD_HF_MMX
1250      lea ecx,[ecx+edx]
1251      ADD_HF_MMX
1252      lea ecx,[ecx+edx]
1253      ADD_HF_MMX
1254      lea ecx,[ecx+edx]
1255      ADD_HF_MMX
1256      lea ecx,[ecx+edx]
1257      ADD_HF_MMX
1258      lea ecx,[ecx+edx]
1259      ADD_HF_MMX
1260      ret
1261    ENDFUNC
1262    
1263    ; The trick is to correct the result of 'pavgb' with some combination of the
1264    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1265    ; The boolean relations are:
1266    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1267    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1268    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1269    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1270    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1271    
1272    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1273    
1274    ;===========================================================================
1275    ;
1276    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1277    ;                       const uint8_t * const src,
1278    ;                       const uint32_t stride,
1279    ;                       const uint32_t rounding);
1280    ;
1281    ;
1282    ;===========================================================================
1283    
1284    %macro ADD_HH_MMX 0
1285      lea eax,[eax+edx]
1286    
1287        ; transfert prev line to mm0/mm1
1288      movq mm0, mm2
1289      movq mm1, mm3
1290    
1291        ; load new line in mm2/mm3
1292      movq mm2, [eax]
1293      movq mm4, [eax+1]
1294      movq mm3, mm2
1295      movq mm5, mm4
1296    
1297      punpcklbw mm2, mm6
1298      punpcklbw mm4, mm6
1299      paddusw mm2, mm4
1300      punpckhbw mm3, mm6
1301      punpckhbw mm5, mm6
1302      paddusw mm3, mm5
1303    
1304        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1305        ; we'll preserve mm2/mm3 for next line...
1306    
1307      paddusw mm0, mm2
1308      paddusw mm1, mm3
1309    
1310      movq mm4, [ecx]   ; prepare mix with Dst[0]
1311      movq mm5, mm4
1312    
1313      paddusw mm0, mm7  ; finish mixing current line
1314      paddusw mm1, mm7
1315    
1316      punpcklbw mm4, mm6
1317      punpckhbw mm5, mm6
1318    
1319      psrlw mm0, 2
1320      psrlw mm1, 2
1321    
1322      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1323      paddusw mm1, mm5
1324    
1325      paddusw mm0, [rounding1_mmx]
1326      paddusw mm1, [rounding1_mmx]
1327    
1328      psrlw mm0, 1
1329      psrlw mm1, 1
1330    
1331      packuswb mm0, mm1
1332    
1333      movq [ecx], mm0
1334    %endmacro
1335    
1336    ALIGN 16
1337    interpolate8x8_halfpel_hv_add_mmx:
1338      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1339    
1340        ; preprocess first line
1341      movq mm0, [eax]
1342      movq mm2, [eax+1]
1343      movq mm1, mm0
1344      movq mm3, mm2
1345    
1346      punpcklbw mm0, mm6
1347      punpcklbw mm2, mm6
1348      punpckhbw mm1, mm6
1349      punpckhbw mm3, mm6
1350      paddusw mm2, mm0
1351      paddusw mm3, mm1
1352    
1353       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1354    
1355      ADD_HH_MMX
1356      lea ecx,[ecx+edx]
1357      ADD_HH_MMX
1358      lea ecx,[ecx+edx]
1359      ADD_HH_MMX
1360      lea ecx,[ecx+edx]
1361      ADD_HH_MMX
1362      lea ecx,[ecx+edx]
1363      ADD_HH_MMX
1364      lea ecx,[ecx+edx]
1365      ADD_HH_MMX
1366      lea ecx,[ecx+edx]
1367      ADD_HH_MMX
1368      lea ecx,[ecx+edx]
1369      ADD_HH_MMX
1370    
1371      ret
1372    ENDFUNC
1373    
1374    
1375    %ifidn __OUTPUT_FORMAT__,elf
1376    section ".note.GNU-stack" noalloc noexec nowrite progbits
1377    %endif
1378    

Legend:
Removed from v.1519  
changed lines
  Added in v.1793

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4