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

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

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

revision 1.14, Sat Jul 24 11:46:08 2004 UTC revision 1.18, Tue Sep 13 12:12:15 2005 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                    %else
33                  global _%1                  global _%1
34                  %define %1 _%1                  %define %1 _%1
35                    %endif
36            %else
37                    %ifdef MARK_FUNCS
38                            global %1:function %1.endfunc-%1
39          %else          %else
40                  global %1                  global %1
41          %endif          %endif
42            %endif
43  %endmacro  %endmacro
44    
45  ;=============================================================================  ;=============================================================================
# Line 95  Line 104 
104  cglobal interpolate8x8_halfpel_h_mmx  cglobal interpolate8x8_halfpel_h_mmx
105  cglobal interpolate8x8_halfpel_v_mmx  cglobal interpolate8x8_halfpel_v_mmx
106  cglobal interpolate8x8_halfpel_hv_mmx  cglobal interpolate8x8_halfpel_hv_mmx
107    
108    cglobal interpolate8x4_halfpel_h_mmx
109    cglobal interpolate8x4_halfpel_v_mmx
110    cglobal interpolate8x4_halfpel_hv_mmx
111    
112  cglobal interpolate8x8_avg4_mmx  cglobal interpolate8x8_avg4_mmx
113  cglobal interpolate8x8_avg2_mmx  cglobal interpolate8x8_avg2_mmx
114    
115  cglobal interpolate8x8_6tap_lowpass_h_mmx  cglobal interpolate8x8_6tap_lowpass_h_mmx
116  cglobal interpolate8x8_6tap_lowpass_v_mmx  cglobal interpolate8x8_6tap_lowpass_v_mmx
117    
118    cglobal interpolate8x8_halfpel_add_mmx
119    cglobal interpolate8x8_halfpel_h_add_mmx
120    cglobal interpolate8x8_halfpel_v_add_mmx
121    cglobal interpolate8x8_halfpel_hv_add_mmx
122    
123  %macro  CALC_AVG 6  %macro  CALC_AVG 6
124    punpcklbw %3, %6    punpcklbw %3, %6
125    punpckhbw %4, %6    punpckhbw %4, %6
# Line 169  Line 189 
189    pop esi    pop esi
190    
191    ret    ret
192    .endfunc
193    
194    
195  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 228  Line 249 
249    pop esi    pop esi
250    
251    ret    ret
252    .endfunc
253    
254    
255  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 319  Line 341 
341    pop esi    pop esi
342    
343    ret    ret
344    .endfunc
345    
346    ;-----------------------------------------------------------------------------
347    ;
348    ; void interpolate8x4_halfpel_h_mmx(uint8_t * const dst,
349    ;                       const uint8_t * const src,
350    ;                       const uint32_t stride,
351    ;                       const uint32_t rounding);
352    ;
353    ;-----------------------------------------------------------------------------
354    
355    ALIGN 16
356    interpolate8x4_halfpel_h_mmx:
357    
358      push esi
359      push edi
360      mov eax, [esp + 8 + 16]       ; rounding
361    
362      movq mm7, [rounding1_mmx + eax * 8]
363    
364      mov edi, [esp + 8 + 4]        ; dst
365      mov esi, [esp + 8 + 8]        ; src
366      mov edx, [esp + 8 + 12]       ; stride
367    
368      pxor mm6, mm6                 ; zero
369    
370      COPY_H_MMX
371      COPY_H_MMX
372      COPY_H_MMX
373      COPY_H_MMX
374    
375      pop edi
376      pop esi
377    
378      ret
379    .endfunc
380    
381    
382    ;-----------------------------------------------------------------------------
383    ;
384    ; void interpolate8x4_halfpel_v_mmx(uint8_t * const dst,
385    ;                       const uint8_t * const src,
386    ;                       const uint32_t stride,
387    ;                       const uint32_t rounding);
388    ;
389    ;-----------------------------------------------------------------------------
390    
391    ALIGN 16
392    interpolate8x4_halfpel_v_mmx:
393    
394      push esi
395      push edi
396    
397      mov eax, [esp + 8 + 16]       ; rounding
398    
399      movq mm7, [rounding1_mmx + eax * 8]
400    
401      mov edi, [esp + 8 + 4]        ; dst
402      mov esi, [esp + 8 + 8]        ; src
403      mov edx, [esp + 8 + 12]       ; stride
404    
405      pxor mm6, mm6                 ; zero
406    
407    
408      COPY_V_MMX
409      COPY_V_MMX
410      COPY_V_MMX
411      COPY_V_MMX
412    
413      pop edi
414      pop esi
415    
416      ret
417    .endfunc
418    
419    
420    ;-----------------------------------------------------------------------------
421    ;
422    ; void interpolate8x4_halfpel_hv_mmx(uint8_t * const dst,
423    ;                       const uint8_t * const src,
424    ;                       const uint32_t stride,
425    ;                       const uint32_t rounding);
426    ;
427    ;
428    ;-----------------------------------------------------------------------------
429    
430    ALIGN 16
431    interpolate8x4_halfpel_hv_mmx:
432    
433      push esi
434      push edi
435    
436      mov eax, [esp + 8 + 16]   ; rounding
437    
438      movq mm7, [rounding2_mmx + eax * 8]
439    
440      mov edi, [esp + 8 + 4]    ; dst
441      mov esi, [esp + 8 + 8]    ; src
442    
443      mov eax, 8
444    
445      pxor mm6, mm6             ; zero
446    
447      mov edx, [esp + 8 + 12]   ; stride
448    
449      COPY_HV_MMX
450      COPY_HV_MMX
451      COPY_HV_MMX
452      COPY_HV_MMX
453    
454      pop edi
455      pop esi
456    
457      ret
458    .endfunc
459    
460  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
461  ;  ;
# Line 493  Line 630 
630    
631    pop ebx    pop ebx
632    ret    ret
633    .endfunc
634    
635    
636  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 681  Line 819 
819    pop edi    pop edi
820    pop ebx    pop ebx
821    ret    ret
822    .endfunc
823    
824    
825  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 791  Line 930 
930    LOWPASS_6TAP_H_MMX    LOWPASS_6TAP_H_MMX
931    
932    ret    ret
933    .endfunc
934    
935  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
936  ;  ;
# Line 908  Line 1048 
1048    
1049    pop ebx    pop ebx
1050    ret    ret
1051    .endfunc
1052    
1053    ;===========================================================================
1054    ;
1055    ; The next functions combine both source halfpel interpolation step and the
1056    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
1057    ; intermediate halfpel images and then averaging them.
1058    ;
1059    ;===========================================================================
1060    
1061    %macro PROLOG0 0
1062      mov ecx, [esp+ 4] ; Dst
1063      mov eax, [esp+ 8] ; Src
1064      mov edx, [esp+12] ; BpS
1065    %endmacro
1066    
1067    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
1068      pxor mm6, mm6
1069      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
1070    %if %2
1071      movq mm5, [rounding1_mmx]
1072    %endif
1073    
1074      PROLOG0
1075    %endmacro
1076    
1077      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
1078    %macro MIX 0
1079      punpcklbw mm0, mm6
1080      punpcklbw mm2, mm6
1081      punpckhbw mm1, mm6
1082      punpckhbw mm3, mm6
1083      paddusw mm0, mm2
1084      paddusw mm1, mm3
1085    %endmacro
1086    
1087    %macro MIX_DST 0
1088      movq mm3, mm2
1089      paddusw mm0, mm7  ; rounder
1090      paddusw mm1, mm7  ; rounder
1091      punpcklbw mm2, mm6
1092      punpckhbw mm3, mm6
1093      psrlw mm0, 1
1094      psrlw mm1, 1
1095    
1096      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1097      paddusw mm1, mm3
1098      paddusw mm0, mm5
1099      paddusw mm1, mm5
1100      psrlw mm0, 1
1101      psrlw mm1, 1
1102    
1103      packuswb mm0, mm1
1104    %endmacro
1105    
1106    %macro MIX2 0
1107      punpcklbw mm0, mm6
1108      punpcklbw mm2, mm6
1109      paddusw mm0, mm2
1110      paddusw mm0, mm7
1111      punpckhbw mm1, mm6
1112      punpckhbw mm3, mm6
1113      paddusw mm1, mm7
1114      paddusw mm1, mm3
1115      psrlw mm0, 1
1116      psrlw mm1, 1
1117    
1118      packuswb mm0, mm1
1119    %endmacro
1120    
1121    ;===========================================================================
1122    ;
1123    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1124    ;                       const uint8_t * const src,
1125    ;                       const uint32_t stride,
1126    ;                       const uint32_t rounding);
1127    ;
1128    ;
1129    ;===========================================================================
1130    
1131    %macro ADD_FF_MMX 1
1132      movq mm0, [eax]
1133      movq mm2, [ecx]
1134      movq mm1, mm0
1135      movq mm3, mm2
1136    %if (%1!=0)
1137      lea eax,[eax+%1*edx]
1138    %endif
1139      MIX
1140      paddusw mm0, mm5  ; rounder
1141      paddusw mm1, mm5  ; rounder
1142      psrlw mm0, 1
1143      psrlw mm1, 1
1144    
1145      packuswb mm0, mm1
1146      movq [ecx], mm0
1147    %if (%1!=0)
1148      lea ecx,[ecx+%1*edx]
1149    %endif
1150    %endmacro
1151    
1152    ALIGN 16
1153    interpolate8x8_halfpel_add_mmx:
1154      PROLOG rounding1_mmx, 1
1155      ADD_FF_MMX 1
1156      ADD_FF_MMX 1
1157      ADD_FF_MMX 1
1158      ADD_FF_MMX 1
1159      ADD_FF_MMX 1
1160      ADD_FF_MMX 1
1161      ADD_FF_MMX 1
1162      ADD_FF_MMX 0
1163      ret
1164    .endfunc
1165    
1166    ;===========================================================================
1167    ;
1168    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1169    ;                       const uint8_t * const src,
1170    ;                       const uint32_t stride,
1171    ;                       const uint32_t rounding);
1172    ;
1173    ;
1174    ;===========================================================================
1175    
1176    %macro ADD_FH_MMX 0
1177      movq mm0, [eax]
1178      movq mm2, [eax+1]
1179      movq mm1, mm0
1180      movq mm3, mm2
1181    
1182      lea eax,[eax+edx]
1183    
1184      MIX
1185      movq mm2, [ecx]   ; prepare mix with Dst[0]
1186      MIX_DST
1187      movq [ecx], mm0
1188    %endmacro
1189    
1190    ALIGN 16
1191    interpolate8x8_halfpel_h_add_mmx:
1192      PROLOG rounding1_mmx, 1
1193    
1194      ADD_FH_MMX
1195      lea ecx,[ecx+edx]
1196      ADD_FH_MMX
1197      lea ecx,[ecx+edx]
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      ret
1210    .endfunc
1211    
1212    ;===========================================================================
1213    ;
1214    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1215    ;                       const uint8_t * const src,
1216    ;                       const uint32_t stride,
1217    ;                       const uint32_t rounding);
1218    ;
1219    ;
1220    ;===========================================================================
1221    
1222    %macro ADD_HF_MMX 0
1223      movq mm0, [eax]
1224      movq mm2, [eax+edx]
1225      movq mm1, mm0
1226      movq mm3, mm2
1227    
1228      lea eax,[eax+edx]
1229    
1230      MIX
1231      movq mm2, [ecx]   ; prepare mix with Dst[0]
1232      MIX_DST
1233      movq [ecx], mm0
1234    
1235    %endmacro
1236    
1237    ALIGN 16
1238    interpolate8x8_halfpel_v_add_mmx:
1239      PROLOG rounding1_mmx, 1
1240    
1241      ADD_HF_MMX
1242      lea ecx,[ecx+edx]
1243      ADD_HF_MMX
1244      lea ecx,[ecx+edx]
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      ret
1257    .endfunc
1258    
1259    ; The trick is to correct the result of 'pavgb' with some combination of the
1260    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1261    ; The boolean relations are:
1262    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1263    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1264    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1265    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1266    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1267    
1268    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1269    
1270    ;===========================================================================
1271    ;
1272    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1273    ;                       const uint8_t * const src,
1274    ;                       const uint32_t stride,
1275    ;                       const uint32_t rounding);
1276    ;
1277    ;
1278    ;===========================================================================
1279    
1280    %macro ADD_HH_MMX 0
1281      lea eax,[eax+edx]
1282    
1283        ; transfert prev line to mm0/mm1
1284      movq mm0, mm2
1285      movq mm1, mm3
1286    
1287        ; load new line in mm2/mm3
1288      movq mm2, [eax]
1289      movq mm4, [eax+1]
1290      movq mm3, mm2
1291      movq mm5, mm4
1292    
1293      punpcklbw mm2, mm6
1294      punpcklbw mm4, mm6
1295      paddusw mm2, mm4
1296      punpckhbw mm3, mm6
1297      punpckhbw mm5, mm6
1298      paddusw mm3, mm5
1299    
1300        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1301        ; we'll preserve mm2/mm3 for next line...
1302    
1303      paddusw mm0, mm2
1304      paddusw mm1, mm3
1305    
1306      movq mm4, [ecx]   ; prepare mix with Dst[0]
1307      movq mm5, mm4
1308    
1309      paddusw mm0, mm7  ; finish mixing current line
1310      paddusw mm1, mm7
1311    
1312      punpcklbw mm4, mm6
1313      punpckhbw mm5, mm6
1314    
1315      psrlw mm0, 2
1316      psrlw mm1, 2
1317    
1318      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1319      paddusw mm1, mm5
1320    
1321      paddusw mm0, [rounding1_mmx]
1322      paddusw mm1, [rounding1_mmx]
1323    
1324      psrlw mm0, 1
1325      psrlw mm1, 1
1326    
1327      packuswb mm0, mm1
1328    
1329      movq [ecx], mm0
1330    %endmacro
1331    
1332    ALIGN 16
1333    interpolate8x8_halfpel_hv_add_mmx:
1334      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1335    
1336        ; preprocess first line
1337      movq mm0, [eax]
1338      movq mm2, [eax+1]
1339      movq mm1, mm0
1340      movq mm3, mm2
1341    
1342      punpcklbw mm0, mm6
1343      punpcklbw mm2, mm6
1344      punpckhbw mm1, mm6
1345      punpckhbw mm3, mm6
1346      paddusw mm2, mm0
1347      paddusw mm3, mm1
1348    
1349       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1350    
1351      ADD_HH_MMX
1352      lea ecx,[ecx+edx]
1353      ADD_HH_MMX
1354      lea ecx,[ecx+edx]
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    
1367      ret
1368    .endfunc
1369    

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.18

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