Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

MCCP (C18) и оптимизация
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=8263
Страница 1 от 1

Автор:  npelov [ Сря Ное 03, 2010 4:20 pm ]
Заглавие:  MCCP (C18) и оптимизация

Как да напиша на C нещо което да се транслира в:
swapf XXX, f

Опитах какво ли не -union с 4 бита, x<<4 | x>>4, последното с & 0xF0 и & 0X0F ..

Виждал съм x=x & ~(1<<5) да се транслира в bsf x, 5 (може и да не е било с майкрочипското C)

Пробвах с inline:
Код:
_asm
  swapf x, 1
_endasm

обаче има 2 проблема:
1. ако използвам инлайн в някоя функция се изключва оптимизацията за тази функция
2. не работи с union. Пример:

Код:
WORD_VAL x;
_asm
  swapf x.LB, 1
_endasm


последното го прескочих с функция:
Код:
void swapf(BYTE *b){
  _asm
    swapf b, 1, ACCESS
  _endasm
}
WORD_VAL x
swapf(x.LB);


което обаче генерира 4-5 инструкции при извикването. доста код си е за едно swapf.

Чудя се дали има някакъв готов макрос в MC C18 за това?

Автор:  Cino [ Сря Ное 03, 2010 4:48 pm ]
Заглавие: 

v c:\mcc18\h ,
във всеки h фаил за всеки PIC има

#define Swapf(f,dest,access) {_asm movlb f swapf f,dest,access _endasm }

само че имаше някаква особеност за dest i access, трябва да са с числа..

Автор:  relsys [ Сря Ное 03, 2010 6:39 pm ]
Заглавие: 

Ами аз така съм го правил:

Код:
asm
    SWAPF _reg_counter_2 + 0, f
    SWAPF _reg_counter_2 + 1, f
    SWAPF _reg_counter_2 + 2, f
    SWAPF _reg_counter_2 + 3, f
    SWAPF _reg_counter_2 + 4, f
    SWAPF _reg_counter_2 + 5, f
  end;

Автор:  npelov [ Сря Ное 03, 2010 7:22 pm ]
Заглавие: 

Cino написа:
v c:\mcc18\h ,
във всеки h фаил за всеки PIC има

#define Swapf(f,dest,access) {_asm movlb f swapf f,dest,access _endasm }

само че имаше някаква особеност за dest i access, трябва да са с числа..


movlb f ... това е хитро. не знаех че на movlb може да му подадеш директно променливата.
access обаче защо са го сложили ... след като зареждат банката и може винаги да е banked.


Проблема обаче остава проблема с union.
Код:
WORD_VAL w;
Swapf(w.LB, 1, 0); //Error [1253] constant operand expected
Swapf(w+0, 1, 0); //--> MOVLB 0    SWAPF 0, F, ACCESS
Swapf(@w, 1, 0);  //пак така




Може би въпроса е повече за union отколкото за swapf. Как да ползвам union променлива в inline асемблер

Автор:  sukhoi [ Сря Ное 03, 2010 8:01 pm ]
Заглавие: 

аз мисля че трябва да се сложи static на това което искаш да слопваш с тази функция Swapf(f,dest,access) .
и на access май се задава 1, т.е да е банкирана

Автор:  npelov [ Чет Ное 04, 2010 1:48 am ]
Заглавие: 

за access си прав, но какво общо има статик. Ето това както писах работи:

Код:
void swapf(BYTE *b){
  _asm
    swapf b, 1, ACCESS
  _endasm
}
.....
WORD_VAL x
swapf(x.LB);


но това - не:
Код:
Swapf(@w.byte.LB, 1, 1);
//или
Swapf(@w, 1, 1);



едит: не съм опитал каст към (unsigned char) например

мне, не стана:

Код:
  WORD_VAL w;
   w.Val = 1000;
  Swapf(((unsigned char)(w.byte.LB)), 1, 1);//[1253] constant operand expected


Проблема е че с union е удобно да се работи, но дори някое поле да е байт не може да се ползва от inline асемблер. Ей това обаче работи:


Код:
  WORD_VAL w;
  unsigned char i;

  w.Val = 1000;
  i = w.byte.LB;
  Swapf(i, 1, 1);
  w.byte.LB = i;


Което ми подсказва че би трябвало да има някакъв cast или нещо такова...

Автор:  sukhoi [ Чет Ное 04, 2010 8:09 pm ]
Заглавие: 

ами аз използвах rlfc(...) функцията и нищо не се въртеше на симулация в watch като гледах. Направих променливата static и проработи

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/