Я реализовал 32-разрядное деление с фиксированной точкой на TSP C5515 с использованием итеративного метода, описанного в DSPLIB .Это 16-битный DSP, и эта функция является узким местом с некоторыми повторными 32-битными вычислениями, поэтому каждая команда имеет значение.
Первая часть функции вырабатывает начальную оценку для обратной величинызнаменатель.Это линейная оценка, которая делает ±3 - 2x
(но в фиксированной точке).Знак на 3 взят из знака знаменателя.Обратите внимание, что знаменатель никогда не равен нулю.
У меня сейчас есть (den
- это int32_t
):
int32_t offset = den > 0 ? 0x60000000 : -0x60000000;
Это компилируется в (AC0
- это смещение, AC3
- знаменатель):
MOV #-24576 << #16, AC0
XCCPART AC3 > #0 ||
MOV #24576 << #16, AC0
Результат используется следующим образом, если это помогает (_l[s]shl
- [насыщающий] сдвиг влево, _lssub
- насыщающий вычитающий):
int32_t est = _lsshl(_lssub(offset, _lshl(den, -1)), 1);
Можно ли удалить ветку (XCCPART
) и еще больше сократить количество инструкций?Я был бы рад использовать побитовые операции для этого, но я не могу понять, как это сделать (C5515 использует дополнение до двух, поэтому побитовое копирование не будет работать).Он не должен быть переносимым (я использую встроенные функции в других местах функции), поведение, определяемое реализацией, хорошо, но не неопределенное поведение.