kategoria: ANSI C
[#1] gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)
Jako że wczoraj zbudowałem gcc od bebbo na windzie 10 do skrośnej kompilacji i po to by zobaczyć jakość kodu generowanego, to natrafiłem na problemik. Chciałbym pozbyć się odkładania na stos argumentów przy wołaniu na przykład OpenLibrary i żeby nie było wołania OpenLibrary poprzez wrapper.
pea 34.w
	pea .LC9
	lea _OpenLibrary,a2
	jsr (a2)
	move.l d0,_IntuitionBase
	addq.l #8,sp


Flagi jakie używam to: -noixemul -Wall -Wextra -Os -fomit-frame-pointer -m68000.
Czy ktoś ma na to radę. Z góry dziękuje.
[#2] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #1

Spróbuj zrobić wrapper, który argumenty przyjmuje z rejestrów:

#if defined(__GNUC__)
#define REGARG(arg, reg) arg asm(reg)
#elif defined(__VBCC__)
#define REGARG(arg, reg) __reg(reg) arg
#endif

struct Library *regOpenLibrary(REGARG(STRPTR libName, "a1"), REGARG(ULONG version, "d0")) {
  return OpenLibrary(libName, version);
}


Może jeszcze trzeba by przekazać ExecBase w ten sam sposób i zawołać nie OpenLibrary tylko funkcję, którą woła to makro. Nie mam jak teraz tego sprawdzić bo jestem w pracy. Jeśli nie zadziała, to myślę że możesz założyć mu issue. ;)

EDYT: teraz doczytałem że nie chcesz wrappera. Spróbuj bezpośrednio zmodyfikować pliki nagłówkowe w podobny sposób, jak pomoże to jest to potencjalny fix do włączenia na stałe do jego paczki. No i spróbuj dla przyzwoitości też -O3.

EDYT2: Byłem pewien że w headerach OpenLibrary jest wrapperem który przekazuje w dodatkowym argumencie ExecBase a tu zonk, widzę tylko nagłówek. W takim wypadku chyba najlepiej będzie pójść z tym do źródła, czyli założyć issue. Im więcej ludzi mu truje tyłek tym lepszy będziemy mieli kompilator. ;)

Ostatnia aktualizacja: 29.06.2018 09:41:10 przez teh_KaiN
[#3] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@teh_KaiN, post #2

Wiem, że jest taka opcja -mregparm, która powoduje że parametry funkcji przekazywane są w rejestrach, a nie przez stos, ale nie wiem, czy pomoże w tym przypadku.
[#4] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@Hexmage960, post #3

Dzięki - pomogło połowicznie, bo
lea _OpenLibrary,a2
	moveq #34,d0
	lea .LC9,a0
	jsr (a2)


wrapper został.

@teh_KaiN - Jakoś nie chce mnie się wierzyć, że to trzeba jakieś fikołki odwalać by uzyskać normalną (w sensie asemblerowym :) - przepraszam za neologizm ) wersję wywołania funkcji bibliotecznej. Zważywszy że w vbcc nie mam z tym problemu wcale. Z innej strony, SAS robi to jeszcze lepiej bo potrafi wywalić powtarzające się odwołania do bazy biblioteki - ale znowu w SAS boli mnie, że nie ma c99 i sypie żwirem przez moje nawyki definiowania zmiennych w jak najmniejszym zasięgu jak się da.
[#5] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #4

Dzięki - pomogło połowicznie, bo

lea _OpenLibrary,a2
moveq #34,d0
lea .LC9,a0
jsr (a2)



wrapper został.

No to wynikałoby z tego, że, skoro jego parametry są dostosowane dynamicznie, to ten wrapper jest kompilowany na bieżąco podczas kompilowania programu.

Znalazłem takie oto ciekawe archiwum na Aminecie:
http://aminet.net/package/dev/gg/fd2inline-bin

Podobno tworzy efektywne inline pod GCC dla amigowych funkcji bibliotecznych (na podstawie plików FD). Może uzyska się dzięki niemu to czego oczekujesz. Warto spróbować.
[#6] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #4

Ha, wiedziałem że gdzieś to widziałem, w VBCC:

struct Library * __OpenLibrary(__reg("a6") void *, __reg("a1") CONST_STRPTR libName, __reg("d0") ULONG version)="\tjsr\t-552(a6)";
#define OpenLibrary(libName, version) __OpenLibrary(SysBase, (libName), (version))


U Bebbo tego nie ma. Bebbo mocno wjechał ze swoimi rzeczami w pliki nagłówkowe. Raz jego kompilator robił straszny kołchoz ze wszystkimi customowymi regami, bo nie było volatile przed polami struktury Custom. Tak czy inaczej jest to pole do ulepszenia i to myślę że w dość łatwy sposób, więc może faktycznie to zgłoś - jak Ty nie chcesz, to ja zgłoszę. ;)

Ostatnia aktualizacja: 29.06.2018 17:18:41 przez teh_KaiN
[#7] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@teh_KaiN, post #6

Według mnie to nie jest wina kompilatora, tylko sposobu wywoływania funkcji bibliotecznych przez kompilator C, co drzemie w amiga.lib. Domyślnie są one na stosie.

Właśnie sprawdziłem i DCC podobnie wywołuje funkcje biblioteczne:
;    Delay(300);

	pea	300.W
	jsr	_Delay(pc)
	addq.l	#4,sp


Po dodaniu opcji "-mi" i załączeniu prototypów z clib/dos_protos.h wyszło:
;    Delay(300);

	move.l	#$012C,D1
	move.l	_DOSBase(A4),A6
	jsr	-198(A6)

Pytanie, jaki jest odpowiednik tej opcji "-mi" w GCC.

Ostatnia aktualizacja: 29.06.2018 17:49:01 przez Hexmage960
[#8] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #1

A to ciekawe, bo problem ten rozwiązano za pomocą plików inline jeszcze za czasów GCC 2.7.2... Natywny GCC 2.95.3 na Amidze otwiera biblioteki np. tak:
MOVEA.L SysBase,a6
LEA DosName,a1
MOVEQ #39,d0
JSR OpenLibrary(a6)
[#9] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@Hexmage960, post #5

Nie ma lekko, bo jak skompilowałem grę, to uwaga uwaga, się zwiesiła, co wcale nie jest dziwne bo z tym parametrem -mregparm=2 kod wrappera nie został zmieniony (tu akurat otwarcie biblioteki
lbC0008A0:	move.l	a6,-(sp)
	move.l	(lbL011F08).l,a6
	move.l	(8,sp),a1
	move.l	(12,sp),d0
	jsr	(-$228,a6)
	move.l	(sp)+,a6
	rts

a kod który to woła
lea	(lbC0008A0).l,a2
	moveq	#$22,d0
	lea	(intuitionlibr.MSG,pc),a0
	jsr	(a2)
	move.l	d0,(lbL012D24).l
	beq.w	lbC003910


A miało być tak pięknie, biuściaste dziewczyny rozdzierające szaty nad moim kodem, ehh, trzeba jednak popracować.

@teh_KaiN
Jak chcesz to zgłoś - ja dzisiaj jestem leniwy :D

@Krashan
To bardzo ciekawe bo z góry obstawiłem że będzie tak jak napisałeś.
[#10] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #9

uwaga, offtopic: koniec z byciem leniwym! czas zabrac sie do roboty:)
[#11] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #9

Nie ma lekko, bo jak skompilowałem grę, to uwaga uwaga, się zwiesiła, co wcale nie jest dziwne bo z tym parametrem -mregparm=2 kod wrappera nie został zmieniony

Czyli tu akurat obnażyłem usterkę w nowym amigowym GCC w związku z -mregparm i tym wrapperem.

Ja obstawiam amiga.lib za ten wrapper (a w zasadzie "stub"), ale czy jest możliwe (w co wątpię), że ten nowy GCC pracuje jak pod AmigaOS4 i potrzebuje __USE_INLINE__?

Ja bym nie kombinował za dużo, może przenieś się na starszą wersję Amigową GCC jaką ma Krashan?

Ja bym (osobiście) po prostu kompilował w DICE z "-mi".

W DICE biblioteki są np. amiga31r.lib, gdzie "r" oznacza, że parametry są przez rejestry.

Ostatnia aktualizacja: 29.06.2018 22:44:00 przez Hexmage960
[#12] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #9

Wiedziałem że nie zgłosisz, więc zapytałem wczoraj wieczorem u źródła i już dzisiaj mam odpowiedź:

Bebbo [10:25 PM]
needs #include <inline/xyz.h>
e.g.
#include <proto/dos.h>
#include <inline/dos.h>


Jeśli nie masz zamiaru zgłaszać problemów Bebbo to albo faktycznie przenieś się na przetestowany 2.95 albo wyżalaj się tutaj, to będę mu forwardował. Ale w takim wypadku bym Cię prosił o źródłowy kod C i wynikowy asm żeby było mu łatwiej sprawdzać, bez angażowania mnie w próbę odtworzenia problemu u siebie.
[#13] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@teh_KaiN, post #12

Dzięki, faktycznie generuje lepiej ale i tak mi się wywala - nie chcę mi się teraz szukać przyczyny, bo chcę zrobić refaktoryzację (to tak delikatnie powiedziane). Pewnie jak będę się ostro nudził to kto wie.
[#14] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #13

Powalczyłem chwilę i okazało się, że przykwasiłem z inkludami, jak podpiąłem te z gcc to wszystko zaczęło śmigać. Ukłony do ziemi dla Cahira i jego opis parametrów dla gcc i amigaos.
Z drugiej strony musze przyznać że gcc mnie zaskoczył na plus. Mam taki oto kod w module Window (otwieranie okna i rzeczy z tym związane) a w module Input mam globalną tablicę, która przechowuje klawisze.
void WindowSignals(void)
{
	while (TRUE)
	{
		struct IntuiMessage* pMsg = (struct IntuiMessage*)GetMsg(g_pWin->UserPort);

		if (NULL == pMsg)
		{
			break;
		}

		tabKeys[pMsg->Code & 0x7f] = pMsg->Code & 0x80;

		ReplyMsg((struct Message*)pMsg);
	}
}

Chodzi mi o linijkę gdzie kod klawisza wędruje do tabKeys. Wygenerowany kod
_WindowSignals:
	move.l a6,-(sp)
	move.l a2,-(sp)
	move.l _SysBase:W(a4),a6
	move.l _g_pWin:W(a4),a0
	move.l 86(a0),a0
#APP
| 104 "src/Window.c" 1
	jsr a6@(-0x174:W)
| 0 "" 2
#NO_APP
	move.l d0,a1
	tst.l d0
	jeq .L15
	lea _tabKeys:W(a4),a2
.L18:
	move.w 24(a1),d1
	move.w d1,d0
	and.w #127,d0
	and.l #65535,d0
	and.b #-128,d1
	move.b d1,(a2,d0.l)
	move.l _SysBase:W(a4),a6
#APP
| 114 "src/Window.c" 1
	jsr a6@(-0x17a:W)
| 0 "" 2
#NO_APP
	move.l _SysBase:W(a4),a6
	move.l _g_pWin:W(a4),a0
	move.l 86(a0),a0
#APP
| 104 "src/Window.c" 1
	jsr a6@(-0x174:W)
| 0 "" 2
#NO_APP
	move.l d0,a1
	tst.l d0
	jne .L18
.L15:
	move.l (sp)+,a2
	move.l (sp)+,a6
	rts

Interesująca mnie linijka została wygenerowana tak:
lea _tabKeys:W(a4),a2
.L18:
	move.w 24(a1),d1
	move.w d1,d0
	and.w #127,d0
	and.l #65535,d0
	and.b #-128,d1
	move.b d1,(a2,d0.l)

I sobie myślę, no bez jaj - na taki marny kod to ja bym nie wpadł. Najlepsze teraz. Postanowiłem kod zapisu klawisza przenieść do innego modułu, bo obsługa klawiszy powinna być w module Input, który to sobie stworzyłem do tego celu. Przy okazji pozbędę się globalniaka co też będzie na plus. Czyli mam taki o to kod w C
--- window ---
void WindowSignals(void)
{
	while (TRUE)
	{
		struct IntuiMessage* pMsg = (struct IntuiMessage*)GetMsg(g_pWin->UserPort);

		if (NULL == pMsg)
		{
			break;
		}

		InputGetKeys(pMsg->Code);

		ReplyMsg((struct Message*)pMsg);
	}
}
--- Input ---
UBYTE tabKeys[128];

void InputGetKeys(UWORD msgCode)
{
	tabKeys[msgCode & 0x7f] = msgCode & 0x80;
}

Najważniejszy dla mnie to kod wygenerowany z InputGetKeys. Oto kod
_InputGetKeys:
	moveq #127,d1
	and.l d0,d1
	lea _tabKeys:W(a4),a0
	and.b #-128,d0
	move.b d0,(a0,d1.l)
	rts

I musze przyznać, że teraz to wygląda to tak jakbym to początkowo zapisał, powyższy kod pomijając linię z lea zajmuje 34 cykle. Całkiem niezły wynik. W zasadzie skoro wiemy że tablica klawiszy ma tylko 128 elementów to nie potrzebujemy andować długiego słowa tylko wystarczy nam słowo (zmieniając tez zapis na a0,d1.w ), utniemy wtedy 4 cykle. A tak naprawdę to mnie interesuje czy w tabKeys pod danym ofsetem klawisz został wciśnięty (bajt ma wartość niezerową) w przeciwnym razie ma wartość zerową. Uzbrojony w taką dodatkową wiedzę jestem w stanie wygenerować lepszy kod, no bo skąd ma to wiedzieć kompilator. A oto kod (26 cykli)
;-- 26c
	and.w	#127,d0
	sne	(a0,d0.w)


Ostatnia aktualizacja: 06.07.2018 10:43:34 przez asman

Ostatnia aktualizacja: 06.07.2018 10:43:58 przez asman
[#15] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #14

Bebbo rozwija GCC nie ingerując zbytnio w sam bazowy kod kompilatora, tylko dodając własne przebiegi optymalizacyjne. Jak masz pomysł na jakiś przebieg tego typu, to możesz mu go podrzucić. Jak se wpiszesz:

m68k-amigaos-gcc --help=target


to dostaniesz między innymi opis parametru -fbbb. Wczoraj zgłaszałem mu problem z optymalizacją "e" bo są z nią problemy. Póki co w sposób stabilny kompiluję ze switchem:

-fomit-frame-pointer -O3 -fbbb=abcfilmprsz


Pewnie to zostanie naprawione w ciągu najbliższych dni. PS czy wspominałem, że Bebbo zrobił obsługę GDB i można sobie systemowy kod debugować zdalnie przy pomocy karty sieciowej? ;)

Ostatnia aktualizacja: 06.07.2018 11:54:17 przez teh_KaiN
[#16] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #14

W twojej optymalizacji troche oszukujesz. Instrukcja sne albo zeruje bajt albo ustawia go na 0xff. W kodzie w C albo zerujesz bajt, albo ustawiasz na 0x80. Skoro juz sie bawisz, to sprobuj jeszcze zmienic twoj kod na:

void InputGetKeys(UWORD msgCode)
{
	UBYTE offset = msgCode & 0x7f;
	tabKeys[offset] = msgCode & 0x80 ? 0xff : 0x00;
}


moze bedziesz mial szczescie i gcc sam wygeneruje ci sne...

PS. Nie wie czy tabKeys[msgCode & 0x7f] nie jest promowane do (a0,d0.l) z powodu uzycia typu unsigned. ZTCP przy takim dostepie rejestr danych jest traktowany jak liczba ze znakiem zeby dac przesuniecie -32768...+32767 wzgledem a0. Dlatego dodalem ta jedna linijke ekstra w kodzie...

Ostatnia aktualizacja: 06.07.2018 12:01:42 przez mschulz
[#17] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@mschulz, post #16

Oczywiście że oszukuje, złapałeś mnie ;)
Sprawdziłem z tym co podałeś i nie ma miodu
_InputGetKeys:
	moveq #127,d1
	and.l d0,d1
	lsr.w #7,d0
	and.b #1,d0
	lea _tabKeys:W(a4),a0
	neg.b d0
	move.b d0,(a0,d1.l)
	rts

I wydaje mnie się, że kiedyś próbowałem już podobnego patentu :)
Przy okazji taki kawałek kodu został nawet nawet klawo wygenerowany
BOOL InputProcessKeys(void)
{
	if (tabKeys[KEY_ESC])
	{
		return TRUE;
	}

	return FALSE;
}
//----
_InputProcessKeys:
	tst.b _tabKeys+69:W(a4)
	seq d0
	ext.w d0
	neg.w d0
	rts
[#18] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@asman, post #1

Dorzuce sie do watkins z krotka informacja. Zrobilem nowy pull-request z poprawkami i informacjami dla tych, ktorzy chcieli by zainstalowac kompilator skrosny od bebbo na macOS.

Kompilator dziala bezblednie i gcc generuje dosc zgrabny kod :)
[#19] Re: gcc od bebbo i wywoływanie funkcji bibliotecznych (dos, inttuition, ...)

@mschulz, post #18

A tu jest dostepny nawet podgląd na żywo. W linku musi być slash na końcu bo inaczej działać nie będzie. Polecam dopisać sobie -O3 po prawej stronie nad kodem.
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem