А Вы свой код проверяли с предопределенным BYTE_ORDER? Он какую-то фигню считает. К тому же у Вас ошибка (t может переполниться). Попробуй это: Должно раза в два быстрее работать (нет кучи лишних присваиваний)
static long muls16_x(short x, short y)
{
uint8_t a, b, c, d, s;
unsigned long t = 0;
unsigned long result;
a=x>>8, c=y>>8;
s = (a ^ c);
if (a & 0x80) x =- x;
if (c & 0x80) y =- y;
a =x >> 8, b = x & 0xFF;
c =y >> 8, d = y & 0xFF;
#if BYTE_ORDER == 1234
*((unsigned*)&result + 0) = b*d;
*((unsigned*)&result + 1) = a*c;
*(unsigned*)((uint8_t*)&t + 1) = a*d;
*(unsigned*)((uint8_t*)&t + 1) += b*c; // Здесь переполнение невозможно
#elif BYTE_ORDER == 4321
*((unsigned*)&result + 1) = b*d;
*((unsigned*)&result + 0) = a*c;
*(unsigned*)((uint8_t*)&t + 2) = a*d;
*(unsigned*)((uint8_t*)&t + 2) += b*c; // Здесь переполнение невозможно
#else
#error "BYTE_ORDER not defined!"
#endif
if (!(s & 0x80)) return (result+t);
else return -(result+t)
}
Около 100 тактов. Можно еще несколько тактов скроить (на проверке знака, на инициализации t, на возврате и пр.), но это уже мелочи. Чем, кстати, хайтековское умножение не устраивает? А для других компиляторов локальные переменные лучше статиком объявлять для скорости, а то MCC18, например, будет через псевдо-стек работать.