Помогите оптимизировать умножение 16x16 со знаком. Что ещё сделать? (кроме ассемблера). Нужно для абстрактного 8-битника (и pic18).
/* signed 16x16 multiplication ~222 commands on PIC18 */
static long muls16(short x, short y)
{
uint8_t a, b, c, d, s;
unsigned t;
unsigned long result=0;
a=x>>8, c=y>>8;
s=(a^c)&0x80;
if (x<0) x=-x;
if (y<0) y=-y;
a=x>>8, b=x&0xFF;
c=y>>8, d=y&0xFF;
t=b*d;
result=t&0xFF;
t>>=8;
t+=a*d;
t+=b*c;
#if BYTE_ORDER==1234
((char*)result)[1]=t;
#elif BYTE_ORDER==4321
((char*)result)[2]=t;
#else
result+=(t&0xFF)<<8;
#endif
t>>=8;
t+=a*c;
#if BYTE_ORDER==1234
((unsigned*)result)[1]=t;
#elif BYTE_ORDER==4321
((unsigned*)result)[0]=t;
#else
result+=(unsigned long)t<<16;
#endif
if (!s) return result;
else return -result;
}
Вырождается в такой код:
1033 000506' _muls16:
1034 000000
1035 ;g726_24.c: 210: uint8_t a, b, c, d, s;
1036 000506' 6A04' clrf btemp+4,c
1037 000508' 6A05' clrf btemp+5,c
1038 00050A' 6A06' clrf btemp+6,c
1039 00050C' 6A07' clrf btemp+7,c
1040 ;g726_24.c: 213: a=x>>8, c=y>>8;
1041 ; _a allocated to fsr2l
1042 00050E' 0100' movlb __Lparam shr (0+8)
1043 000510' 5100' movf (?_muls16+1)^(__Lparam& (0+65280)),w
1044 000512' 6ED9 movwf fsr2l,c
1045 ; _c allocated to fsr1l
1046 000514' 5100' movf (?_muls16+3)^(__Lparam& (0+65280)),w
1047 000516' 6EE1 movwf fsr1l,c
1048 ;g726_24.c: 214: s=(a^c)&0x80;
1049 000518' 50E1 movf fsr1l,w,c
1050 00051A' 18D9 xorwf fsr2l,w,c
1051 00051C' 0B80 andlw -128
1052 00051E' 6E01' movwf btemp+1,c
1053 ;g726_24.c: 215: if (x<0) x=-x;
1054 000520' AF00' btfss (?_muls16+1)^(__Lparam& (0+65280)),7,b
1055 000522' D004 goto l70
1056 000524' 6D00' negf ?_muls16^(__Lparam& (0+65280)),b
1057 000526' 1F00' comf (?_muls16+1)^(__Lparam& (0+65280)),f,b
1058 000528' B0D8 btfsc status,0,c
1059 00052A' 2B00' incf (?_muls16+1)^(__Lparam& (0+65280)),f,b
1060 00052C' l70:
1061 ;g726_24.c: 216: if (y<0) y=-y;
1062 00052C' 0100' movlb __Lparam shr (0+8)
1063 00052E' AF00' btfss (?_muls16+3)^(__Lparam& (0+65280)),7,b
1064 000530' D004 goto l71
1065 000532' 6D00' negf (?_muls16+2)^(__Lparam& (0+65280)),b
1066 000534' 1F00' comf (?_muls16+3)^(__Lparam& (0+65280)),f,b
1067 000536' B0D8 btfsc status,0,c
1068 000538' 2B00' incf (?_muls16+3)^(__Lparam& (0+65280)),f,b
1069 00053A' l71:
1070 ;g726_24.c: 217: a=x>>8, b=x&0xFF;
1071 ; _a allocated to btemp
1072 00053A' 0100' movlb __Lparam shr (0+8)
1073 00053C' 5100' movf (?_muls16+1)^(__Lparam& (0+65280)),w
1074 00053E' 6E00' movwf btemp,c
1075 000540' 5100' movf ?_muls16^(__Lparam& (0+65280)),w
1076 000542' 6EE1 movwf fsr1l,c
1077 ;g726_24.c: 218: c=y>>8, d=y&0xFF;
1078 ; _c allocated to fsr2l
1079 000544' 5100' movf (?_muls16+3)^(__Lparam& (0+65280)),w
1080 000546' 6ED9 movwf fsr2l,c
1081 000548' 5100' movf (?_muls16+2)^(__Lparam& (0+65280)),w
1082 00054A' 6EE9 movwf fsr0l,c
1083 ;g726_24.c: 219: t=b*d;
1084 00054C' 50E1 movf fsr1l,w,c
1085 00054E' 02E9 mulwf fsr0l,c
1086 000550' CFF3 FFF6 movff prodl,tblptrl
1087 000554' CFF4 FFF7 movff prodh,tblptrh
1088 ;g726_24.c: 220: result=t&0xFF;
1089 000558' 50F6 movf tblptrl,w,c
1090 00055A' 6E04' movwf btemp+4,c
1091 00055C' 6A05' clrf btemp+5,c
1092 00055E' 6A06' clrf btemp+6,c
1093 000560' 6A07' clrf btemp+7,c
1094 ;g726_24.c: 221: t>>=8;
1095 000562' 50F7 movf tblptrh,w,c
1096 000564' 6EF6 movwf tblptrl,c
1097 000566' 6AF7 clrf tblptrh,c
1098 ;g726_24.c: 222: t+=a*d;
1099 000568' 5000' movf btemp,w,c
1100 00056A' 02E9 mulwf fsr0l,c
1101 00056C' 50F3 movf prodl,w,c
1102 00056E' 26F6 addwf tblptrl,f,c
1103 000570' 50F4 movf prodh,w,c
1104 000572' 22F7 addwfc tblptrh,f,c
1105 ;g726_24.c: 223: t+=b*c;
1106 000574' 50E1 movf fsr1l,w,c
1107 000576' 02D9 mulwf fsr2l,c
1108 000578' 50F3 movf prodl,w,c
1109 00057A' 26F6 addwf tblptrl,f,c
1110 00057C' 50F4 movf prodh,w,c
1111 00057E' 22F7 addwfc tblptrh,f,c
1112 ;g726_24.c: 225: ((char*)result)[1]=t;
1113 000580' EE00 F001 lfsr 0,1
1114 000584' 5004' movf btemp+4,w,c
1115 000586' 26E9 addwf fsr0l,f,c
1116 000588' 5005' movf btemp+5,w,c
1117 00058A' 22EA addwfc fsr0h,f,c
1118 00058C' CFF6 FFEF movff tblptrl,indf0
1119 ;g726_24.c: 231: t>>=8;
1120 000590' 50F7 movf tblptrh,w,c
1121 000592' 6EF6 movwf tblptrl,c
1122 000594' 6AF7 clrf tblptrh,c
1123 ;g726_24.c: 232: t+=a*c;
1124 000596' 5000' movf btemp,w,c
1125 000598' 02D9 mulwf fsr2l,c
1126 00059A' 50F3 movf prodl,w,c
1127 00059C' 26F6 addwf tblptrl,f,c
1128 00059E' 50F4 movf prodh,w,c
1129 0005A0' 22F7 addwfc tblptrh,f,c
1130 ;g726_24.c: 234: ((unsigned*)result)[1]=t;
1131 0005A2' EE00 F002 lfsr 0,2
1132 0005A6' 5004' movf btemp+4,w,c
1133 0005A8' 26E9 addwf fsr0l,f,c
1134 0005AA' 5005' movf btemp+5,w,c
1135 0005AC' 22EA addwfc fsr0h,f,c
1136 0005AE' CFF6 FFEE movff tblptrl,postinc0
1137 0005B2' CFF7 FFED movff tblptrh,postdec0
1138 ;g726_24.c: 240: if (!s) return result;
1139 0005B6' 5001' movf btemp+1,w,c
1140 0005B8' C004' F000' movff btemp+4,btemp
1141 0005BC' C005' F001' movff btemp+5,btemp+1
1142 0005C0' C006' F002' movff btemp+6,btemp+2
1143 0005C4' C007' F003' movff btemp+7,btemp+3
1144 0005C8' E101 bnz L26
1145 0005CA' 0012 return
1146 ;g726_24.c: 241: else return -result;
1147 0005CC' L26:
1148 0005CC' 1E00' comf btemp,f,c
1149 0005CE' 1E01' comf btemp+1,f,c
1150 0005D0' 1E02' comf btemp+2,f,c
1151 0005D2' 1E03' comf btemp+3,f,c
1152 0005D4' 2A00' incf btemp,f,c
1153 0005D6' B4D8 btfsc status,2,c
1154 0005D8' 2A01' incf btemp+1,f,c
1155 0005DA' B4D8 btfsc status,2,c
1156 0005DC' 2A02' incf btemp+2,f,c
1157 0005DE' B4D8 btfsc status,2,c
1158 0005E0' 2A03' incf btemp+3,f,c
1159 0005E2' 0012 return
1160 ;g726_24.c: 242: }
1161 0005E4' __end_of_muls16:
[ZX]
-
- А Вы свой код проверяли с предопределенным BYTE_ORDER? Он какую-то фигню считает. К тому же у Вас ошибка (t может переполниться). Попробуй это: testerplus(1438 знак., 30.03.2011 16:35 - 16:38)