RTV forum PL | NewsGroups PL

Jak zminimalizować generowany kod w AVR gcc przy łączeniu dwóch unsigned char w unsigned short?

AVR gcc - pytanie

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Jak zminimalizować generowany kod w AVR gcc przy łączeniu dwóch unsigned char w unsigned short?

MariuszC
Guest

Tue Nov 09, 2004 9:04 am   



Witam,
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
unsigned short wValue;
unsigned char byValue1, byValue2;
wValue = (byValue1<<Cool | byValue2;
albo
wValue = (byValue1<<Cool + byValue2;

promują byValue1 oraz byValue2 do liczby unsigned short
potem je ORują ze sobą, a przecież wiadomo że byValue1
ma trafić na starszy bajt wValue, a byValue2 na młodszy
i to wszystko.

Są jakieś makra jak np:
HIBYTE(wValue) = byValue1;
LOBYTE(wValue) = byValue2;
dzięki którym kompilator by wpisywał wartość do odpowiedniego
rejestru, albo komórki pamięci? Ja nie znalazłem, albo przegapiłem
(jeśli w ogóle coś takiego istnieje). Może Ktoś z Was zna rozwiązanie.
Po prostu wkurza mnie, że zawsze brakuje FLASHa, a kompilator
dodatkowo generuje niepotrzebny kod, tymbardziej w takich prostych
przypadkach.

Mariusz

Piotr Chmiel
Guest

Tue Nov 09, 2004 10:11 am   



On Tue, 9 Nov 2004, MariuszC wrote:

Quote:
Po prostu wkurza mnie, że zawsze brakuje FLASHa, a kompilator
dodatkowo generuje niepotrzebny kod, tymbardziej w takich prostych
przypadkach.

A ile go masz że Ci ciągle brakuje ?
Dostosuj AVR do swoich potrzeb Smile

Andrzej Ekiert
Guest

Tue Nov 09, 2004 10:19 am   



MariuszC wrote:
Quote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
unsigned short wValue;
unsigned char byValue1, byValue2;
wValue = (byValue1<<Cool | byValue2;
albo
wValue = (byValue1<<Cool + byValue2;


Nie używam co prawda AVRów, ale na taki sam problem pod gcc na procesory
dsPIC Microchipa, oraz pod mcc18 na PIC18 rozwiązałem w sposób następujący:

/*
* Use when assigning to unsigned 8-bit variable
* (x is a 16 bit variable)
*/
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))

Paskudne to to jest, wiem.

hth,
--
Andrzej Ekiert
Polskie Forum Microchipa
http://www.ekiert.com/microchip

Marek Dzwonnik
Guest

Tue Nov 09, 2004 11:19 am   



Użytkownik "Andrzej Ekiert" <reply@to.invalid> napisał w wiadomości
news:cmq5j2$jpv$1@polsl.gliwice.pl
Quote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
wValue = (byValue1<<Cool | byValue2;
albo
wValue = (byValue1<<Cool + byValue2;

dsPIC Microchipa, oraz pod mcc18 na PIC18 rozwiązałem w
sposób następujący:
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))

A może z wykorzystaniem unii zawierajacej alternatywnie jednego int-a albo
strukture zlozona z dwoch bajtów? To wprawdzie nie jest zbyt legalne, ale
powinno działać:

union {
struct {
unsigned char b1;
unsigned char b2;
} asByte;
unsigned int asWord;
} value;

value.asWord
value.asByte.b1
value.asByte.b2

--
Marek Dzwonnik, GG: #2061027 - zwykle jako 'niewidoczny'
(Uwaga Gadu-Gadulcowicze: Nie odpowiadam na anonimy.)

J.F.
Guest

Tue Nov 09, 2004 11:49 am   



On Tue, 09 Nov 2004 11:19:13 +0100, Andrzej Ekiert wrote:
Quote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.

wValue = (byValue1<<Cool | byValue2;
albo
wValue = (byValue1<<Cool + byValue2;

#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))

Paskudne to to jest, wiem.

Paskudne. Bo sie okaze na innym procku [np AVR] zmienna jest w jednym
z [np 32] rejestrow i nie ma adresu :-)

Chyba lepiej to pierwsze i zdac sie na optymalizator.

J.

Albert Bartoszko
Guest

Tue Nov 09, 2004 2:16 pm   



Użytkownik J.F. napisał:
[...]
Quote:
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))

Paskudne to to jest, wiem.


Paskudne. Bo sie okaze na innym procku [np AVR] zmienna jest w jednym
z [np 32] rejestrow i nie ma adresu Smile

Nie, po użyciu czegoś takiego już nie będzie w rejestrze i będzie miała
adres.

Quote:

Chyba lepiej to pierwsze i zdac sie na optymalizator.
Jak ktoś jest tak oszczędny to jednak proponowałbym asembler


Albert

MariuszC
Guest

Tue Nov 09, 2004 2:47 pm   



Marek Dzwonnik wrote:
Quote:
Użytkownik "Andrzej Ekiert" <reply@to.invalid> napisał w wiadomości
news:cmq5j2$jpv$1@polsl.gliwice.pl

czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
wValue = (byValue1<<Cool | byValue2;
albo
wValue = (byValue1<<Cool + byValue2;


dsPIC Microchipa, oraz pod mcc18 na PIC18 rozwiązałem w
sposób następujący:
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))


A może z wykorzystaniem unii zawierajacej alternatywnie jednego int-a albo
strukture zlozona z dwoch bajtów? To wprawdzie nie jest zbyt legalne, ale
powinno działać:

union {
struct {
unsigned char b1;
unsigned char b2;
} asByte;
unsigned int asWord;
} value;

value.asWord
value.asByte.b1
value.asByte.b2

Też to ćwiczyłem i jest znacznie lepiej, jednak np
po przeniesieniu części kodu na 51 trzeba będzie pamiętać
że one chyba (dawno nic w nich nie robiłem) mają
odwrotny zapis MSB,LSB, a nie jak w AVR LSB,MSB

Mariusz

Mister
Guest

Tue Nov 09, 2004 3:20 pm   



Quote:
po przeniesieniu części kodu na 51 trzeba będzie pamiętać
że one chyba (dawno nic w nich nie robiłem) mają
odwrotny zapis MSB,LSB, a nie jak w AVR LSB,MSB


Tak jest. I to jest denerwujące.

Mister

Marek Dzwonnik
Guest

Tue Nov 09, 2004 4:32 pm   



Użytkownik "Mister" <wojpie@wywal_to.poczta.onet.pl> napisał w
wiadomości news:cmqn9j$dmd$1@atlantis.news.tpi.pl
Quote:
po przeniesieniu części kodu na 51 trzeba będzie pamiętać
że one chyba (dawno nic w nich nie robiłem) mają
odwrotny zapis MSB,LSB, a nie jak w AVR LSB,MSB

Tak jest. I to jest denerwujące.


W takim razie zależnie od typu procesora zdefiniować:
#define MSB b1
#define LSB b2

lub na odwrót
#define MSB b2
#define LSB b1

i odwoływać się do pól struktury przez MSB i LSB.
value.asByte.MSB
value.asByte.LSB

--
MDz

Jurek Szczesiul
Guest

Tue Nov 09, 2004 4:37 pm   



Tue, 09 Nov 2004 10:04:38 +0100, na pl.misc.elektronika, MariuszC
napisał(a):

Quote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.

Cześć.

memcpy((char*)&word,(char*)&chr2,1);
64: 00 91 62 00 lds r16, 0x0062
68: 00 93 74 00 sts 0x0074, r16
memcpy((char*)&word+1,(char*)&chr1,1);
6c: 10 91 63 00 lds r17, 0x0063
70: 10 93 75 00 sts 0x0075, r17


--
Pozdrowienia
Jurek Szczesiul

J.F.
Guest

Tue Nov 09, 2004 5:13 pm   



On Tue, 9 Nov 2004 17:37:06 +0100, Jurek Szczesiul wrote:
Quote:
memcpy((char*)&word,(char*)&chr2,1);
64: 00 91 62 00 lds r16, 0x0062
68: 00 93 74 00 sts 0x0074, r16
memcpy((char*)&word+1,(char*)&chr1,1);
6c: 10 91 63 00 lds r17, 0x0063
70: 10 93 75 00 sts 0x0075, r17


Eeeee .. czy on ma prawo tak robic ?
powinien wywolac funkcje biblioteczna memcpy.

J.

Marcin Stanisz
Guest

Tue Nov 09, 2004 6:00 pm   



Quote:
Eeeee .. czy on ma prawo tak robic ?
powinien wywolac funkcje biblioteczna memcpy.

I to jest dopiero optymalizacja! ;-)

Pozdrawiam

Marcin Stanisz



--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl

Marek Michalkiewicz
Guest

Tue Nov 09, 2004 9:45 pm   



J.F. <jfox_nospam@poczta.onet.pl> wrote:
Quote:

Eeeee .. czy on ma prawo tak robic ?
powinien wywolac funkcje biblioteczna memcpy.

Ma prawo. GCC (na kazda architekture, niekoniecznie AVR) ma troche
funkcji wbudowanych - zamiast wywolania funkcji moze wygenerowac
kawalek kodu, robiacy to samo tylko bardziej efektywnie. Mozna
uzyc -fno-builtin (lub dla konkretnej funkcji: -fno-builtin-memcpy)
by te optymalizacje wylaczyc.

Wstawienie kawalka kodu ma te przewage nad wywolaniem funkcji, ze
nie "zapomina" sie tylu rejestrow (AVR: r18-r27 i r30-r31), wiec
moze sie oplacac nawet dla funkcji nieco wiekszych niz memcpy().

Marek

elektroda NewsGroups Forum Index - Elektronika Polska - Jak zminimalizować generowany kod w AVR gcc przy łączeniu dwóch unsigned char w unsigned short?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map