[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 1529, Sun Aug 1 08:45:15 2004 UTC revision 1530, Tue Aug 10 21:58:55 2004 UTC
# Line 95  Line 95 
95  cglobal interpolate8x8_halfpel_h_mmx  cglobal interpolate8x8_halfpel_h_mmx
96  cglobal interpolate8x8_halfpel_v_mmx  cglobal interpolate8x8_halfpel_v_mmx
97  cglobal interpolate8x8_halfpel_hv_mmx  cglobal interpolate8x8_halfpel_hv_mmx
98    
99  cglobal interpolate8x8_avg4_mmx  cglobal interpolate8x8_avg4_mmx
100  cglobal interpolate8x8_avg2_mmx  cglobal interpolate8x8_avg2_mmx
101    
102  cglobal interpolate8x8_6tap_lowpass_h_mmx  cglobal interpolate8x8_6tap_lowpass_h_mmx
103  cglobal interpolate8x8_6tap_lowpass_v_mmx  cglobal interpolate8x8_6tap_lowpass_v_mmx
104    
105    cglobal interpolate8x8_halfpel_add_mmx
106    cglobal interpolate8x8_halfpel_h_add_mmx
107    cglobal interpolate8x8_halfpel_v_add_mmx
108    cglobal interpolate8x8_halfpel_hv_add_mmx
109    
110  %macro  CALC_AVG 6  %macro  CALC_AVG 6
111    punpcklbw %3, %6    punpcklbw %3, %6
112    punpckhbw %4, %6    punpckhbw %4, %6
# Line 908  Line 915 
915    
916    pop ebx    pop ebx
917    ret    ret
918    
919    ;===========================================================================
920    ;
921    ; The next functions combine both source halfpel interpolation step and the
922    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
923    ; intermediate halfpel images and then averaging them.
924    ;
925    ;===========================================================================
926    
927    %macro PROLOG0 0
928      mov ecx, [esp+ 4] ; Dst
929      mov eax, [esp+ 8] ; Src
930      mov edx, [esp+12] ; BpS
931    %endmacro
932    
933    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
934      pxor mm6, mm6
935      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
936    %if %2
937      movq mm5, [rounding1_mmx]
938    %endif
939    
940      PROLOG0
941    %endmacro
942    
943      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
944    %macro MIX 0
945      punpcklbw mm0, mm6
946      punpcklbw mm2, mm6
947      punpckhbw mm1, mm6
948      punpckhbw mm3, mm6
949      paddusw mm0, mm2
950      paddusw mm1, mm3
951    %endmacro
952    
953    %macro MIX_DST 0
954      movq mm3, mm2
955      paddusw mm0, mm7  ; rounder
956      paddusw mm1, mm7  ; rounder
957      punpcklbw mm2, mm6
958      punpckhbw mm3, mm6
959      psrlw mm0, 1
960      psrlw mm1, 1
961    
962      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
963      paddusw mm1, mm3
964      paddusw mm0, mm5
965      paddusw mm1, mm5
966      psrlw mm0, 1
967      psrlw mm1, 1
968    
969      packuswb mm0, mm1
970    %endmacro
971    
972    %macro MIX2 0
973      punpcklbw mm0, mm6
974      punpcklbw mm2, mm6
975      paddusw mm0, mm2
976      paddusw mm0, mm7
977      punpckhbw mm1, mm6
978      punpckhbw mm3, mm6
979      paddusw mm1, mm7
980      paddusw mm1, mm3
981      psrlw mm0, 1
982      psrlw mm1, 1
983    
984      packuswb mm0, mm1
985    %endmacro
986    
987    ;===========================================================================
988    ;
989    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
990    ;                       const uint8_t * const src,
991    ;                       const uint32_t stride,
992    ;                       const uint32_t rounding);
993    ;
994    ;
995    ;===========================================================================
996    
997    %macro ADD_FF_MMX 1
998      movq mm0, [eax]
999      movq mm2, [ecx]
1000      movq mm1, mm0
1001      movq mm3, mm2
1002    %if (%1!=0)
1003      lea eax,[eax+%1*edx]
1004    %endif
1005      MIX
1006      paddusw mm0, mm5  ; rounder
1007      paddusw mm1, mm5  ; rounder
1008      psrlw mm0, 1
1009      psrlw mm1, 1
1010    
1011      packuswb mm0, mm1
1012      movq [ecx], mm0
1013    %if (%1!=0)
1014      lea ecx,[ecx+%1*edx]
1015    %endif
1016    %endmacro
1017    
1018    ALIGN 16
1019    interpolate8x8_halfpel_add_mmx:
1020      PROLOG rounding1_mmx, 1
1021      ADD_FF_MMX 1
1022      ADD_FF_MMX 1
1023      ADD_FF_MMX 1
1024      ADD_FF_MMX 1
1025      ADD_FF_MMX 1
1026      ADD_FF_MMX 1
1027      ADD_FF_MMX 1
1028      ADD_FF_MMX 0
1029      ret
1030    
1031    ;===========================================================================
1032    ;
1033    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1034    ;                       const uint8_t * const src,
1035    ;                       const uint32_t stride,
1036    ;                       const uint32_t rounding);
1037    ;
1038    ;
1039    ;===========================================================================
1040    
1041    %macro ADD_FH_MMX 0
1042      movq mm0, [eax]
1043      movq mm2, [eax+1]
1044      movq mm1, mm0
1045      movq mm3, mm2
1046    
1047      lea eax,[eax+edx]
1048    
1049      MIX
1050      movq mm2, [ecx]   ; prepare mix with Dst[0]
1051      MIX_DST
1052      movq [ecx], mm0
1053    %endmacro
1054    
1055    ALIGN 16
1056    interpolate8x8_halfpel_h_add_mmx:
1057      PROLOG rounding1_mmx, 1
1058    
1059      ADD_FH_MMX
1060      lea ecx,[ecx+edx]
1061      ADD_FH_MMX
1062      lea ecx,[ecx+edx]
1063      ADD_FH_MMX
1064      lea ecx,[ecx+edx]
1065      ADD_FH_MMX
1066      lea ecx,[ecx+edx]
1067      ADD_FH_MMX
1068      lea ecx,[ecx+edx]
1069      ADD_FH_MMX
1070      lea ecx,[ecx+edx]
1071      ADD_FH_MMX
1072      lea ecx,[ecx+edx]
1073      ADD_FH_MMX
1074      ret
1075    
1076    ;===========================================================================
1077    ;
1078    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1079    ;                       const uint8_t * const src,
1080    ;                       const uint32_t stride,
1081    ;                       const uint32_t rounding);
1082    ;
1083    ;
1084    ;===========================================================================
1085    
1086    %macro ADD_HF_MMX 0
1087      movq mm0, [eax]
1088      movq mm2, [eax+edx]
1089      movq mm1, mm0
1090      movq mm3, mm2
1091    
1092      lea eax,[eax+edx]
1093    
1094      MIX
1095      movq mm2, [ecx]   ; prepare mix with Dst[0]
1096      MIX_DST
1097      movq [ecx], mm0
1098    
1099    %endmacro
1100    
1101    ALIGN 16
1102    interpolate8x8_halfpel_v_add_mmx:
1103      PROLOG rounding1_mmx, 1
1104    
1105      ADD_HF_MMX
1106      lea ecx,[ecx+edx]
1107      ADD_HF_MMX
1108      lea ecx,[ecx+edx]
1109      ADD_HF_MMX
1110      lea ecx,[ecx+edx]
1111      ADD_HF_MMX
1112      lea ecx,[ecx+edx]
1113      ADD_HF_MMX
1114      lea ecx,[ecx+edx]
1115      ADD_HF_MMX
1116      lea ecx,[ecx+edx]
1117      ADD_HF_MMX
1118      lea ecx,[ecx+edx]
1119      ADD_HF_MMX
1120      ret
1121    
1122    ; The trick is to correct the result of 'pavgb' with some combination of the
1123    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1124    ; The boolean relations are:
1125    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1126    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1127    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1128    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1129    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1130    
1131    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1132    
1133    ;===========================================================================
1134    ;
1135    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1136    ;                       const uint8_t * const src,
1137    ;                       const uint32_t stride,
1138    ;                       const uint32_t rounding);
1139    ;
1140    ;
1141    ;===========================================================================
1142    
1143    %macro ADD_HH_MMX 0
1144      lea eax,[eax+edx]
1145    
1146        ; transfert prev line to mm0/mm1
1147      movq mm0, mm2
1148      movq mm1, mm3
1149    
1150        ; load new line in mm2/mm3
1151      movq mm2, [eax]
1152      movq mm4, [eax+1]
1153      movq mm3, mm2
1154      movq mm5, mm4
1155    
1156      punpcklbw mm2, mm6
1157      punpcklbw mm4, mm6
1158      paddusw mm2, mm4
1159      punpckhbw mm3, mm6
1160      punpckhbw mm5, mm6
1161      paddusw mm3, mm5
1162    
1163        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1164        ; we'll preserve mm2/mm3 for next line...
1165    
1166      paddusw mm0, mm2
1167      paddusw mm1, mm3
1168    
1169      movq mm4, [ecx]   ; prepare mix with Dst[0]
1170      movq mm5, mm4
1171    
1172      paddusw mm0, mm7  ; finish mixing current line
1173      paddusw mm1, mm7
1174    
1175      punpcklbw mm4, mm6
1176      punpckhbw mm5, mm6
1177    
1178      psrlw mm0, 2
1179      psrlw mm1, 2
1180    
1181      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1182      paddusw mm1, mm5
1183    
1184      paddusw mm0, [rounding1_mmx]
1185      paddusw mm1, [rounding1_mmx]
1186    
1187      psrlw mm0, 1
1188      psrlw mm1, 1
1189    
1190      packuswb mm0, mm1
1191    
1192      movq [ecx], mm0
1193    %endmacro
1194    
1195    ALIGN 16
1196    interpolate8x8_halfpel_hv_add_mmx:
1197      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1198    
1199        ; preprocess first line
1200      movq mm0, [eax]
1201      movq mm2, [eax+1]
1202      movq mm1, mm0
1203      movq mm3, mm2
1204    
1205      punpcklbw mm0, mm6
1206      punpcklbw mm2, mm6
1207      punpckhbw mm1, mm6
1208      punpckhbw mm3, mm6
1209      paddusw mm2, mm0
1210      paddusw mm3, mm1
1211    
1212       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1213    
1214      ADD_HH_MMX
1215      lea ecx,[ecx+edx]
1216      ADD_HH_MMX
1217      lea ecx,[ecx+edx]
1218      ADD_HH_MMX
1219      lea ecx,[ecx+edx]
1220      ADD_HH_MMX
1221      lea ecx,[ecx+edx]
1222      ADD_HH_MMX
1223      lea ecx,[ecx+edx]
1224      ADD_HH_MMX
1225      lea ecx,[ecx+edx]
1226      ADD_HH_MMX
1227      lea ecx,[ecx+edx]
1228      ADD_HH_MMX
1229    
1230      ret
1231    

Legend:
Removed from v.1529  
changed lines
  Added in v.1530

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