[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.12.2.1, Tue Oct 28 22:23:03 2003 UTC revision 1.17, Sun Aug 29 10:02:38 2004 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  ;=============================================================================  ;=============================================================================
46  ; Read only data  ; Read only data
47  ;=============================================================================  ;=============================================================================
48    
49    %ifdef FORMAT_COFF
50  SECTION .rodata  SECTION .rodata
51    %else
52    SECTION .rodata align=16
53    %endif
54    
55  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
56  ; (16 - r) rounding table  ; (16 - r) rounding table
# Line 91  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 interpolate8x8_avg4_mmx  cglobal interpolate8x8_avg4_mmx
109  cglobal interpolate8x8_avg2_mmx  cglobal interpolate8x8_avg2_mmx
110    
111  cglobal interpolate8x8_6tap_lowpass_h_mmx  cglobal interpolate8x8_6tap_lowpass_h_mmx
112  cglobal interpolate8x8_6tap_lowpass_v_mmx  cglobal interpolate8x8_6tap_lowpass_v_mmx
113    
114    cglobal interpolate8x8_halfpel_add_mmx
115    cglobal interpolate8x8_halfpel_h_add_mmx
116    cglobal interpolate8x8_halfpel_v_add_mmx
117    cglobal interpolate8x8_halfpel_hv_add_mmx
118    
119  %macro  CALC_AVG 6  %macro  CALC_AVG 6
120    punpcklbw %3, %6    punpcklbw %3, %6
121    punpckhbw %4, %6    punpckhbw %4, %6
# Line 165  Line 185 
185    pop esi    pop esi
186    
187    ret    ret
188    .endfunc
189    
190    
191  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 224  Line 245 
245    pop esi    pop esi
246    
247    ret    ret
248    .endfunc
249    
250    
251  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 315  Line 337 
337    pop esi    pop esi
338    
339    ret    ret
340    .endfunc
341    
342  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
343  ;  ;
# Line 489  Line 512 
512    
513    pop ebx    pop ebx
514    ret    ret
515    .endfunc
516    
517    
518  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 677  Line 701 
701    pop edi    pop edi
702    pop ebx    pop ebx
703    ret    ret
704    .endfunc
705    
706    
707  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 787  Line 812 
812    LOWPASS_6TAP_H_MMX    LOWPASS_6TAP_H_MMX
813    
814    ret    ret
815    .endfunc
816    
817  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
818  ;  ;
# Line 904  Line 930 
930    
931    pop ebx    pop ebx
932    ret    ret
933    .endfunc
934    
935    ;===========================================================================
936    ;
937    ; The next functions combine both source halfpel interpolation step and the
938    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
939    ; intermediate halfpel images and then averaging them.
940    ;
941    ;===========================================================================
942    
943    %macro PROLOG0 0
944      mov ecx, [esp+ 4] ; Dst
945      mov eax, [esp+ 8] ; Src
946      mov edx, [esp+12] ; BpS
947    %endmacro
948    
949    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
950      pxor mm6, mm6
951      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
952    %if %2
953      movq mm5, [rounding1_mmx]
954    %endif
955    
956      PROLOG0
957    %endmacro
958    
959      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
960    %macro MIX 0
961      punpcklbw mm0, mm6
962      punpcklbw mm2, mm6
963      punpckhbw mm1, mm6
964      punpckhbw mm3, mm6
965      paddusw mm0, mm2
966      paddusw mm1, mm3
967    %endmacro
968    
969    %macro MIX_DST 0
970      movq mm3, mm2
971      paddusw mm0, mm7  ; rounder
972      paddusw mm1, mm7  ; rounder
973      punpcklbw mm2, mm6
974      punpckhbw mm3, mm6
975      psrlw mm0, 1
976      psrlw mm1, 1
977    
978      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
979      paddusw mm1, mm3
980      paddusw mm0, mm5
981      paddusw mm1, mm5
982      psrlw mm0, 1
983      psrlw mm1, 1
984    
985      packuswb mm0, mm1
986    %endmacro
987    
988    %macro MIX2 0
989      punpcklbw mm0, mm6
990      punpcklbw mm2, mm6
991      paddusw mm0, mm2
992      paddusw mm0, mm7
993      punpckhbw mm1, mm6
994      punpckhbw mm3, mm6
995      paddusw mm1, mm7
996      paddusw mm1, mm3
997      psrlw mm0, 1
998      psrlw mm1, 1
999    
1000      packuswb mm0, mm1
1001    %endmacro
1002    
1003    ;===========================================================================
1004    ;
1005    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1006    ;                       const uint8_t * const src,
1007    ;                       const uint32_t stride,
1008    ;                       const uint32_t rounding);
1009    ;
1010    ;
1011    ;===========================================================================
1012    
1013    %macro ADD_FF_MMX 1
1014      movq mm0, [eax]
1015      movq mm2, [ecx]
1016      movq mm1, mm0
1017      movq mm3, mm2
1018    %if (%1!=0)
1019      lea eax,[eax+%1*edx]
1020    %endif
1021      MIX
1022      paddusw mm0, mm5  ; rounder
1023      paddusw mm1, mm5  ; rounder
1024      psrlw mm0, 1
1025      psrlw mm1, 1
1026    
1027      packuswb mm0, mm1
1028      movq [ecx], mm0
1029    %if (%1!=0)
1030      lea ecx,[ecx+%1*edx]
1031    %endif
1032    %endmacro
1033    
1034    ALIGN 16
1035    interpolate8x8_halfpel_add_mmx:
1036      PROLOG rounding1_mmx, 1
1037      ADD_FF_MMX 1
1038      ADD_FF_MMX 1
1039      ADD_FF_MMX 1
1040      ADD_FF_MMX 1
1041      ADD_FF_MMX 1
1042      ADD_FF_MMX 1
1043      ADD_FF_MMX 1
1044      ADD_FF_MMX 0
1045      ret
1046    .endfunc
1047    
1048    ;===========================================================================
1049    ;
1050    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1051    ;                       const uint8_t * const src,
1052    ;                       const uint32_t stride,
1053    ;                       const uint32_t rounding);
1054    ;
1055    ;
1056    ;===========================================================================
1057    
1058    %macro ADD_FH_MMX 0
1059      movq mm0, [eax]
1060      movq mm2, [eax+1]
1061      movq mm1, mm0
1062      movq mm3, mm2
1063    
1064      lea eax,[eax+edx]
1065    
1066      MIX
1067      movq mm2, [ecx]   ; prepare mix with Dst[0]
1068      MIX_DST
1069      movq [ecx], mm0
1070    %endmacro
1071    
1072    ALIGN 16
1073    interpolate8x8_halfpel_h_add_mmx:
1074      PROLOG rounding1_mmx, 1
1075    
1076      ADD_FH_MMX
1077      lea ecx,[ecx+edx]
1078      ADD_FH_MMX
1079      lea ecx,[ecx+edx]
1080      ADD_FH_MMX
1081      lea ecx,[ecx+edx]
1082      ADD_FH_MMX
1083      lea ecx,[ecx+edx]
1084      ADD_FH_MMX
1085      lea ecx,[ecx+edx]
1086      ADD_FH_MMX
1087      lea ecx,[ecx+edx]
1088      ADD_FH_MMX
1089      lea ecx,[ecx+edx]
1090      ADD_FH_MMX
1091      ret
1092    .endfunc
1093    
1094    ;===========================================================================
1095    ;
1096    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1097    ;                       const uint8_t * const src,
1098    ;                       const uint32_t stride,
1099    ;                       const uint32_t rounding);
1100    ;
1101    ;
1102    ;===========================================================================
1103    
1104    %macro ADD_HF_MMX 0
1105      movq mm0, [eax]
1106      movq mm2, [eax+edx]
1107      movq mm1, mm0
1108      movq mm3, mm2
1109    
1110      lea eax,[eax+edx]
1111    
1112      MIX
1113      movq mm2, [ecx]   ; prepare mix with Dst[0]
1114      MIX_DST
1115      movq [ecx], mm0
1116    
1117    %endmacro
1118    
1119    ALIGN 16
1120    interpolate8x8_halfpel_v_add_mmx:
1121      PROLOG rounding1_mmx, 1
1122    
1123      ADD_HF_MMX
1124      lea ecx,[ecx+edx]
1125      ADD_HF_MMX
1126      lea ecx,[ecx+edx]
1127      ADD_HF_MMX
1128      lea ecx,[ecx+edx]
1129      ADD_HF_MMX
1130      lea ecx,[ecx+edx]
1131      ADD_HF_MMX
1132      lea ecx,[ecx+edx]
1133      ADD_HF_MMX
1134      lea ecx,[ecx+edx]
1135      ADD_HF_MMX
1136      lea ecx,[ecx+edx]
1137      ADD_HF_MMX
1138      ret
1139    .endfunc
1140    
1141    ; The trick is to correct the result of 'pavgb' with some combination of the
1142    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1143    ; The boolean relations are:
1144    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1145    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1146    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1147    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1148    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1149    
1150    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1151    
1152    ;===========================================================================
1153    ;
1154    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1155    ;                       const uint8_t * const src,
1156    ;                       const uint32_t stride,
1157    ;                       const uint32_t rounding);
1158    ;
1159    ;
1160    ;===========================================================================
1161    
1162    %macro ADD_HH_MMX 0
1163      lea eax,[eax+edx]
1164    
1165        ; transfert prev line to mm0/mm1
1166      movq mm0, mm2
1167      movq mm1, mm3
1168    
1169        ; load new line in mm2/mm3
1170      movq mm2, [eax]
1171      movq mm4, [eax+1]
1172      movq mm3, mm2
1173      movq mm5, mm4
1174    
1175      punpcklbw mm2, mm6
1176      punpcklbw mm4, mm6
1177      paddusw mm2, mm4
1178      punpckhbw mm3, mm6
1179      punpckhbw mm5, mm6
1180      paddusw mm3, mm5
1181    
1182        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1183        ; we'll preserve mm2/mm3 for next line...
1184    
1185      paddusw mm0, mm2
1186      paddusw mm1, mm3
1187    
1188      movq mm4, [ecx]   ; prepare mix with Dst[0]
1189      movq mm5, mm4
1190    
1191      paddusw mm0, mm7  ; finish mixing current line
1192      paddusw mm1, mm7
1193    
1194      punpcklbw mm4, mm6
1195      punpckhbw mm5, mm6
1196    
1197      psrlw mm0, 2
1198      psrlw mm1, 2
1199    
1200      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1201      paddusw mm1, mm5
1202    
1203      paddusw mm0, [rounding1_mmx]
1204      paddusw mm1, [rounding1_mmx]
1205    
1206      psrlw mm0, 1
1207      psrlw mm1, 1
1208    
1209      packuswb mm0, mm1
1210    
1211      movq [ecx], mm0
1212    %endmacro
1213    
1214    ALIGN 16
1215    interpolate8x8_halfpel_hv_add_mmx:
1216      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1217    
1218        ; preprocess first line
1219      movq mm0, [eax]
1220      movq mm2, [eax+1]
1221      movq mm1, mm0
1222      movq mm3, mm2
1223    
1224      punpcklbw mm0, mm6
1225      punpcklbw mm2, mm6
1226      punpckhbw mm1, mm6
1227      punpckhbw mm3, mm6
1228      paddusw mm2, mm0
1229      paddusw mm3, mm1
1230    
1231       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1232    
1233      ADD_HH_MMX
1234      lea ecx,[ecx+edx]
1235      ADD_HH_MMX
1236      lea ecx,[ecx+edx]
1237      ADD_HH_MMX
1238      lea ecx,[ecx+edx]
1239      ADD_HH_MMX
1240      lea ecx,[ecx+edx]
1241      ADD_HH_MMX
1242      lea ecx,[ecx+edx]
1243      ADD_HH_MMX
1244      lea ecx,[ecx+edx]
1245      ADD_HH_MMX
1246      lea ecx,[ecx+edx]
1247      ADD_HH_MMX
1248    
1249      ret
1250    .endfunc
1251    

Legend:
Removed from v.1.12.2.1  
changed lines
  Added in v.1.17

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