реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Сдвиг 64битного беззнакового целого
coolibin
сообщение Jul 1 2009, 09:41
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 19-07-07
Пользователь №: 29 228



Есть код:

CODE

#define UINT unsigned int
#define UINT64 unsigned long long
....
UINT64 iValue;
UINT iOffset;

iOffset = rand()&63;
iValue = (UINT64)(1) << iOffset;


компилятор генерит такой асм:

CODE

_BLF rand,??rand??rT
LSLS R2,R0,#+26
LSRS R2,R2,#+26
MOVS R0,#+1
MOVS R1,#+0
_BLF ??lllsl_t,??rT??lllsl_t


т. е. он юзает функцию lllsl_t для сдвига. Как заставить его обойтись без этой функции, т. е. через простые операции, если это конечно, возможно?


--------------------
Нет повести печальнее на свете, чем повесть о хреновом интернете.
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Jul 1 2009, 10:07
Сообщение #2


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



iOffset тогда должна быть константой.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
coolibin
сообщение Jul 1 2009, 10:58
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 19-07-07
Пользователь №: 29 228



да, я это знаю, но увы по замыслу она не может быть константой

Cделать циклом что ли?
Код
iOffset = rand()&63;
iValue = 1;
while(iOffset){
    iValue = iValue << 1;
    iOffset--;
}


Сообщение отредактировал coolibin - Jul 1 2009, 10:59


--------------------
Нет повести печальнее на свете, чем повесть о хреновом интернете.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 1 2009, 11:06
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(coolibin @ Jul 1 2009, 14:58) *
Cделать циклом что ли?

Зачем? Вы же единицу сдвигаете, сделайте так:
Код
    UINT vl = 0, vh = 0;

    iOffset = rand()&63;
    if(iOffset < 32) vl = 1UL << iOffset;
    else vh = 1UL << (iOffset - 32);
    iValue = ((UINT64)vh << 32) | vl;
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jul 1 2009, 11:15
Сообщение #5


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



А рукопашную проверку нельзя?
Код
UINT64 f1(void)
{
  UINT iOffset = rand()&63;
  if (iOffset>31) return (UINT64)(1UL<<(iOffset-32))<<32;
  return (UINT64)(1UL<<iOffset);
}


CODE

// 123 UINT64 f1(void)
// 124 {
f1:
PUSH {LR}
SUB SP,SP,#+4
// 125 UINT iOffset = rand()&63;
BL rand
AND R0,R0,#0x3F
// 126 if (iOffset>31) return (UINT64)(1UL<<(iOffset-32))<<32;
MOV R1,#+1
CMP R0,#+32
BCC ??f1_0
SUB R0,R0,#+32
LSL R0,R1,R0
MOV R1,R0
MOV R0,#+0
B ??f1_1
// 127 return (UINT64)(1UL<<iOffset);
??f1_0:
LSL R0,R1,R0
MOV R1,#+0
??f1_1:
ADD SP,SP,#+4 ;; stack cleaning
POP {LR}
BX LR ;; return
// 128 }


Я вам всем больше скажу. Стреляет такой код (щас курнул мануал, при сдвиге больше чем 31 результат равен 0). Но будьте аккуратны. В других ядрах (не ARM) поведение сдвига другое (например AVR32).

Код
UINT64 f1(void)
{
  UINT vl, vh;
  UINT iOffset = rand()&63;
  vl = 1UL << iOffset;
  vh = 1UL << (iOffset - 32);
  return ((UINT64)vh << 32) | vl;
}


CODE

// 123 UINT64 f1(void)
// 124 {
f1:
PUSH {LR}
SUB SP,SP,#+4
// 125 UINT vl, vh;
// 126 UINT iOffset = rand()&63;
BL rand
AND R0,R0,#0x3F
// 127 vl = 1UL << iOffset;
// 128 vh = 1UL << (iOffset - 32);
// 129 return ((UINT64)vh << 32) | vl;
MOV R2,#+1
SUB R1,R0,#+32
LSL R1,R2,R1
LSL R0,R2,R0
ADD SP,SP,#+4 ;; stack cleaning
POP {LR}
BX LR ;; return
// 130 }


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Jul 1 2009, 11:17
Сообщение #6


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



В библиотеке JPEG люди сдвигают вообще по таблице. Т.е. ищут результат сдвига по таблице.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 1 2009, 11:23
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(DpInRock @ Jul 1 2009, 14:17) *
В библиотеке JPEG люди сдвигают вообще по таблице. Т.е. ищут результат сдвига по таблице.
Это актуально для AVR, но не для ARM. ARM имеет аппаратный сдвигатель, позволяющий сдвигать не затрачивая времени - в той же операции, где используется результат сдвига. Или сдвигать отдельной командой за такт, что явно быстрее, чем чтение таблицы.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jul 1 2009, 11:31
Сообщение #8


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
В библиотеке JPEG люди сдвигают вообще по таблице.


В какой библиотеке? wink.gif

Цитата
Это актуально для AVR


Для AVR в качестве barrel-shift'ера надо использовать аппаратный умножитель


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 10th July 2025 - 15:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01502 секунд с 7
ELECTRONIX ©2004-2016