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

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

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