Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Подскажите как лучше всего перевернуть байт
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Romanello
В АРМе на СИ нужно переделать байт :

было bit7, bit6. bit5. bit4. bit 3. bit2. bit 1. bit0

нужно bit0, bit1, bit2. bit3. bit4, bit5, bit6, bit7

как это сделать наиболее грамотнее?
АДИКМ
Цитата(Romanello @ Jul 1 2008, 14:06) *
В АРМе на СИ нужно переделать байт :

было bit7, bit6. bit5. bit4. bit 3. bit2. bit 1. bit0

нужно bit0, bit1, bit2. bit3. bit4, bit5, bit6, bit7

как это сделать наиболее грамотнее?


проще (и главное быстрее) это делается с помощью таблицы.
думаю 256 байт флеша найдете...
Romanello
Цитата(АДИКМ @ Jul 1 2008, 15:20) *
проще (и главное быстрее) это делается с помощью таблицы.
думаю 256 байт флеша найдете...



С таблицей это первое что пришло мне в голову, но мне кажется это совсем уж прямолинейно, может есть какие то способы с прокруткой, в 51-х было проще крутнул восемь раз и все ок, а здесь так не получится.
Alex03
Не знаю насколько оптимально на АРМ и для байтика, но на С и без циклов/ветвлений.
Код
    unsigned char c;

    c = ((c>>1) & 0x55) | ((c<<1) & 0xAA);
    c = ((c>>2) & 0x33) | ((c<<2) & 0xCC);
    c = ((c>>4) & 0x0F) | ((c<<4) & 0xF0);

Для 32-х разрядов добавляется ещё 2 строчки.

PS можно ещё упростить немного.
meister
Цитата(Romanello @ Jul 1 2008, 15:06) *
В АРМе на СИ нужно переделать байт :

было bit7, bit6. bit5. bit4. bit 3. bit2. bit 1. bit0

нужно bit0, bit1, bit2. bit3. bit4, bit5, bit6, bit7

как это сделать наиболее грамотнее?


Саттер в своей книге приводил два правила оптимизации:

1. Не оптимизируй.
2. Никогда не оптмизируй.

из комментарев к правилам вытекало "пока необходимость оптимизации не будет доказана профайлером". Я бы сначала сделал как привел Alex03, если бы было плохо - как АДИКМ.
АДИКМ
если хочется экзотики - порты перехлестните.
Romanello
Цитата(Alex03 @ Jul 1 2008, 15:29) *
Не знаю насколько оптимально на АРМ и для байтика, но на С и без циклов/ветвлений.
Код
    unsigned char c;

    c = ((c>>1) & 0x55) | ((c<<1) & 0xAA);
    c = ((c>>2) & 0x33) | ((c<<2) & 0xCC);
    c = ((c>>4) & 0x0F) | ((c<<4) & 0xF0);

Для 32-х разрядов добавляется ещё 2 строчки.

PS можно ещё упростить немного.



круто все работает. Спасибо.

Цитата(АДИКМ @ Jul 1 2008, 15:47) *
если хочется экзотики - порты перехлестните.



Порты и так пришлось перевернуть, т.к. разводка по другому не получалась, теперь приходится думать как лучше управлять перевернутыми портами.

В принципе предложено два варианта реализующих задачу максимально эффективно, поэтому думаю что дискуссию можно окончить.
Alex03
Цитата(Romanello @ Jul 1 2008, 17:50) *
круто все работает. Спасибо.
Порты и так пришлось перевернуть, т.к. разводка по другому не получалась, теперь приходится думать как лучше управлять перевернутыми портами.

Если ещё вот так сделать:
Код
unsigned char bitrev8(unsigned char c)
{
    c = ((c>>1) & 0x55) | ((c & 0x55)<<1);
    c = ((c>>2) & 0x33) | ((c & 0x33)<<2);
    c = (c>>4) | (c<<4);
    return c;
}

то GCC с -O3 генерит:
Код
<bitrev8>:
       E1A030A0   mov r3, r0, lsr #0x01
       E2033055   and r3, r3, #0x00000055
       E2000055   and r0, r0, #0x00000055
       E1833080   orr r3, r3, r0, lsl #0x01
       E1A02123   mov r2, r3, lsr #0x02
       E2022033   and r2, r2, #0x00000033
       E2033033   and r3, r3, #0x00000033
       E1822103   orr r2, r2, r3, lsl #0x02
       E1A00222   mov r0, r2, lsr #0x04
       E1800202   orr r0, r0, r2, lsl #0x04
       E20000FF   and r0, r0, #0x000000ff
       E12FFF1E   bx lr

И то строчка and r0, r0, #0x000000ff лишняя.
MrYuran
Круто. Реально круто. Где бы такого нахвататься можно?
Rst7
Цитата
Круто. Реально круто. Где бы такого нахвататься можно?


Это еще не самое крутое wink.gif Круто - это таким способом поворот матрицы 8*8 бит (именно бит!) на 90 градусов, причем еще и штуки четыре (матрицы, конечно) за раз - они как раз в восемь 32хбитных регистра лезут.
GetSmart
Цитата(Rst7 @ Jul 1 2008, 18:33) *
Это еще не самое крутое wink.gif Круто - это таким способом поворот матрицы 8*8 бит (именно бит!) на 90 градусов, причем еще и штуки четыре (матрицы, конечно) за раз - они как раз в восемь 32хбитных регистра лезут.
Это куда такое применяется?
PS. вроде бы 8*8 бит влазит в два 32-х разрядных регистра
Rst7
Цитата
Это куда такое применяется?


Для преобразования изображения в виде байт на точку к битовым плоскостям. Для ширпотреба не актуально smile.gif

Цитата
PS. вроде бы 8*8 бит влазит в два 32-х разрядных регистра


Ну правильно, а 4 раза по 8*8 - в восемь регистров.
ljerry
Цитата(MrYuran @ Jul 1 2008, 16:06) *
Круто. Реально круто. Где бы такого нахвататься можно?


Рекомендую хорошую книжку "Алгоритмические трюки для программистов", там подобных фокусов много
blackfin
Цитата(Rst7 @ Jul 1 2008, 17:16) *
Ну правильно, а 4 раза по 8*8 - в восемь регистров.
Или одна ПЛИС.. smile.gif
Axel
Посмотрите: http://www.cs.utk.edu/~vose/c-stuff/bithac...CopyIntegerSign
Там такого дофига...
abcdefg
Цитата(Rst7 @ Jul 1 2008, 16:33) *
Это еще не самое крутое wink.gif Круто - это таким способом поворот матрицы 8*8 бит (именно бит!) на 90 градусов, причем еще и штуки четыре (матрицы, конечно) за раз - они как раз в восемь 32хбитных регистра лезут.


Раз пошла такая пьянка - как бы красиво сделать удвоение кол-ва бит? Т.е. 0010 1000b => 0000 1100 1100 0000b
Rst7
Цитата
Раз пошла такая пьянка - как бы красиво сделать удвоение кол-ва бит? Т.е. 0010 1000b => 0000 1100 1100 0000b


Идея все та же, для байта в 16 бит будет выглядеть так
Код
        ARM
//   12 unsigned int doublebits(unsigned int x)
//   13 {
//   14   x = (x | (x << 4)) & 0x0F0F;
doublebits:
        ORR      R0,R0,R0, LSL #+4
        MOV      R1,#+15
        ORR      R1,R1,#0xF00
        AND      R0,R1,R0
//   15   x = (x | (x << 2)) & 0x3333;
        ORR      R0,R0,R0, LSL #+2
        MOV      R1,#+51
        ORR      R1,R1,#0x3300
        AND      R0,R1,R0
//   16   x = (x | (x << 1)) & 0x5555;
        ORR      R0,R0,R0, LSL #+1
        MOV      R1,#+85
        ORR      R1,R1,#0x5500
        AND      R0,R1,R0
//   17   x |= x<<1;
//   18   return x;
        ORR      R0,R0,R0, LSL #+1
        BX       LR              ;; return
//   19 }
Alexis_
RBIT<c> <Rd>,<Rm>
aaarrr
Можно подумать, что все поголовно пишут для ARM1156.
Roman Mich.
Код

const unsigned char transpb[16]=
    {0x0,0x8,0x4,0xc,0x2,0xa,0x6,0xe,0x1,0x9,0x5,0xd,0x3,0xb,0x7,0xf};

// транспонирование байта
#define TRANSPB(b) ((unsigned char)((unsigned char)(transpb[b & 0xf]) << 4) | ((unsigned char)(transpb[(b & 0xf0) >> 4])))
Alexis_
Цитата(aaarrr @ Jul 14 2008, 16:18) *
Можно подумать, что все поголовно пишут для ARM1156.

Нет, в основном для Cortex-A9.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.