Portování GCC na daný procesor Antonín Král
[email protected] [email protected] 3. září 2002
Obsah 1 Úvod 1.1 Motivace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Zdroje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 2 2
2 Cílový systém – CRIS 2.1 Cílová architektura . . . . 2.1.1 Registry . . . . . . 2.1.2 Velikosti operandů 2.2 Adresovací módy . . . . . 2.2.1 Instrukce . . . . . . 2.3 Knihovny . . . . . . . . .
3 3 3 3 4 4 4
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
3 GCC – GNU C Compiler 3.1 Komponenty překladače gcc . . . . 3.2 Mechanismus portace . . . . . . . . 3.2.1 Soubor maker – tm.h . . . . 3.2.2 Soubor zdrojového kódu v C 3.2.3 Popis cílového stroje – md . 3.2.4 Definice časových parametrů
. . . – . –
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tm.c . . . . . . . . . . . . . . . . . Delay definitions
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
5 . 5 . 5 . 6 . 9 . 9 . 13
4 Závěr
14
Literatura
15
1
Kapitola 1 Úvod 1.1
Motivace
Používání různých architektur procesorů a počítačů není žádnou novinkou. Pro účelné využití dané architektury jsou potřebné nástroje pro vývoj aplikací. Mezi ty hlavní patří jednoznačně překladače. Protože vývoj aplikací probíhá v drtivé většině případů na jiné hostitelské platformě (typicky i386) bylo vytvořeno mnoho tzv. cross-compilerů, které pracují na hostitelské platformě, ale výstupem je kód pro cílový procesor. Existuje celá řada překladačů. Mezi velice rozšířené patří GCC, které je dostupné pod licencí GPL. Krom jiných předností má i dobrou podporu portování na různé druhy procesorů. Tato podpora je dána obecným návrhem vlastního překladače, kterému se dá předložit popis cílové architektury. Tento dokument vznikl jako samostatná práce do předmětu Speciální Architektury na Katedře počítačů FEL ČVUT.
1.2
Zdroje
Hlavním zdrojem informací při psaní této práce byl jedna manuál k překladači gcc [gcc] a také diplomová práce [Nilsson]. Celá ukázka portování gcc na jinou architekturu se ukázala netriviální. Proto jsem se rozhodl nevytvářet ještě neexistující portaci, ale spíše vyjít z existujících dokumentů a vytvořit přehled potřebných kroků s odkazy na zdroje, ze kterých je možné čerpat.
2
Kapitola 2 Cílový systém – CRIS Tato kapitola má za cíl podat krátký informativní přehled o zvolené cílové architektuře.
2.1
Cílová architektura
GCC je určeno především pro procesory, které mají několik obecných 32-bitových registrů a bytově adresovatelnou paměť. Je možné vytvořit překladač pro jinou architekturu, např. se 16-bitovými registry, ale na druhou stranu nelze použít GCC pro překlad na architekturu, která má pouze jeden hlavní registr1 . Další omezení je kladeno na paměť – tato by neměla být větší než je možné adresovat registrem. Architektura, která je použita v této práci jako cílová se jmenuje CRIS [cris]. Jedná se o architekturu, která splňuje všechny požadavky, které jsou kladeny na cílovou architekturu ze strany překladače. Tento procesor se používá v ETRAX system-on-a-chip produktech. V dalším textu jsou popisovány vlastnosti a problémy, které se týkají především zvolené cílové architektury. Zvolená architektura má takové vlastnosti, že by měly být zároveň pokryty obecné vlastnosti návrhu portu překladače.
2.1.1
Registry
CRIS má 32-bitové registry, které jsou značeny r0 . . . r15. Registry se dají použít podle uvážení programátora, pouze registr r15 je vyhrazen pro použití jako program counter – dále jej budu označovat jako pc. Dále má procesor 16 speciálních registrů, avšak pouze některé jsou přímo použitelné pro gcc. Jedním z nich je condition-code registr (ccr), dále např. subroutine-return pointer registr (srp), který je používán při instrukcích jsr a ret. Procesor neimplementuje hw podporu zásobníku. Avšak vzhledem k implementaci instrukce movem se jako stack-pointer používá registr r14 – budeme jej tedy dále označovat jako sp.
2.1.2
Velikosti operandů
Typy operandů jsou byte, word a dword (značení b, w a d, písmeno S použijeme pro označení libovolného typu). Operace nad byty a wordy nemení horní část registrů. 1
tzv. „akumulátorovéÿ architektury, protože tento jediný registr se nazývá akumulátor.
3
2.2
Adresovací módy
Většina instrukcí, které realizují nějakou binární operaci je implementována jako dvou operandová, kde první operand je registr a slouží zároveň pro uložení výsledku. Druhý operand může být v paměti, konstanta nebo také registr. Základní adresační módy jsou tedy: konstanta (quick immediate), hodnota registru (register), nepřímé adresování (indirect register) a nepřímé adresování s post inkrementací (indirect register with post-increment). Komplexnější adresní módy jsou implementovány pomocí speciálních instrukcí (address prefix instructions). Překladač transformuje adresní módy z následující tabulky na volaní těchto funkcí. Adresovací mód Zápis v assembleru Poznámka Nepřímý s posunem [rX + I] I je konstanta, −128 ≤ I ≤ 127 [rX + [rY].S] [rX + [rY+].S] Double indirect
[[rX]] [[rX+]]
Nepřímý s posunem podle velikosti operandu [rX + rY.S] rY je vynásobena velikostí S Podrobnější přehled dalších adresních módů je uvedem v dokumentaci k procesorům.
2.2.1
Instrukce
Podrobný popis operačního kódu je opět dostupný v dokumentaci procesorů. Dále zdůrazním několik skutečností, kterými se CRIS liší od běžných procesorů. • Hodnota pc se při skodu do podprogramu (instrukce jsr) neukládá na zásobník, ale do srp. Podprogram se musí postarat o jeho uložení, pokud bude registr potřebovat pro svou práci. • Instrukce větvení a návratu (ret) vykonávají při spuštění bezprostředně následující instrukci (delay-slot). • Neexistují instrukce pro násobení a dělení. Dělení i násobení je ponecháno na knihovních funkcích při kompilaci (linkování). • Neexistují instrukce pro počítání v plovoucí řádové čárce. Operace jsou opět ponechány na knihovní implementaci.
2.3
Knihovny
Pro CRIS jsou dostupné různé knihovny. Mezi základní patří např. implementace operací v pohyblivé řádové čárce. Většina knihoven je dostupná pod GNU licencí.
4
Kapitola 3 GCC – GNU C Compiler Obsah této kapitoly je z velké části extraktem [gcc]. Vlasní manuál je velice obsáhlý a obsahuje množství dalších informací a upřesnění.
3.1
Komponenty překladače gcc
Program gcc tvoří pouze front-end k několika dalším komponentám, která dohromady poskytují celkovou funkcionalitu překladače (včetně linkeru). Základní součásti jsou tyto: cpp tvoří preprocesor jazyka C. Stará se tedy o expanzi maker, odstranění komentářů, vložení includů apod. (je součástí gcc) cc1 Vlastní jádro kompilátoru. Tvoří jej tedy jazykový font-end i back-end závislý na cílové architektuře. (je součástí gcc) as Assembler ld Linker Při spuštění uživatlem se tedy gcc rozhodne, kdy a kterou komponentu je tedy potřeba použít. Standardně se použijí všechny komponenty v uvedeném pořadí, ale pokud chce uživatel např. pouze slinkovat již existující object-files spustí se pouze linker. Při tvorbě portu gcc se tedy zaměříme na jádro systému – komponentu cc1.
3.2
Mechanismus portace
Pro portování gcc na jinou platformu je důležité popsat cílovou platformu do nejmenších detailů. Tohoto se dosahuje společným použítím céčkových maker, vhodným nastavením parametrů překladače a případné speciality se popisují pomocí detailního popisu jednotlivých instrukcí. Popis cílové architektury je tvořen třemi soubory: céčková makra (kanonické jméno souboru tm.h, zdrojový kód v C (soubor tm.c) a popis cílové architektury (tzv. machine description, soubor md). Pokud se podíváte do zdrojového kódu gcc naleznete množství souborů s názvy target.h, target.c a target.md. V ostatních částech zdrojových textů se ale používají právě kanonická jména, která jsou v průběhu konfiguračního procesu nahrazena příslušnými (již reálnými) odkazy.
5
3.2.1
Soubor maker – tm.h
Vlastnosti cílové architektury (včetně věcí jako je organizace paměti, jak se předávají parametry funkcím, při volání apod. Souhrnně nazýváno ABI – application binary interface). Počet maker, která se vyskytují v gcc je veliký. Pro úplný souhrn včetně podrobného popisu je nejlepší obrátit se na [gcc]. V následujícím přehledu jsou zmíněna pouze některá makra, která jsou zajímavá pro náš konkrétní případ. Makra jsou v dokumentaci rozdělena do několika kategorií. Jsou to tyto kategorie: Prostředí překladače – Compiler environment do této kategorie patří věci jako je syntaxe assembleru, umístění hlavičkových souborů, systémových knihoven apod. Základní vlastnosti architektury – Fundamental machine properties definice, zda se jedná o big endian nebo little endian architekturu, počet registrů, typy registrů, adresní módy. ABI – Application binary interface definují jak jsou volány funkce. Jaké kroky jsou potřebné ke korektnímu zavolání céčkové funkce, při volání z assembleru apod. Machine description support definice, které se buď přímo používají v md souborech nebo při výstupu z interních metod. Makra jsou většinou ve tvaru funkce, která vrací celočíselnou hodnotu nebo se rozlišuje zda je dané makro definované, či nikoli (typicky vlastnosti ano/ne). Prostředí překladače – Compiler environment Jméno makra SWITCH TAKES ARG. . . INCLUDE DEFAULTS
CPP PREDEFINES
TARGET SWITCHES
TARGET VERSION
Význam Makra definující prostředí překladu – umístění základních souborů, volba parametrů, které se předávají jednotlivým součástem překladače. Tyto nastavení se týkají vlastního cross compileru. Např. include-path neobsahuje cesty k hlavičkovým souborů hostitelské architektury, na které je cross compiler překládán. Obsahuje seznam maker, která mají být uvažována a jsou specifická pro daný systém a/nebo architekturu. Pokud je nastaven musí být ve tvaru řetězce s položkami oddělenými mezerami. Seznam parametrů, které jsou překladači předávány s prefixem -m. Strukturálně se jedná o pole, které obsahuje příznaky ano/ne. Tyto příznaky se dají používat pro drobné modifikace ABI jednotlivých překladových cílů, pro testování apod. Pokud je nastaven měl by obsahovat něco jako fprintf (stderr, "target v1.0");, jedná se o výstup, který vrátí volání gcc -v.
6
Jméno makra TARGET BELL. . . TARGET CR
Význam
Definuje hodnoty pro a . . . r. Toto makro nemá defaultní hodnoty. {MUL, DIV, UDIV, MOD, Obsahuje volání knihovních funkcí pro příslušné operace UMOD}{DI,SI3} LIBCALL v příslušné přesnosti. Není potřeba je definovat ve chvíli, kdy pro danou operaci existuje instrukce. TARGET MEM FUNCTIONS Definuje zda se používat volání funkcí memcpy() a memset() (ANSI a System V). Jinak se místo nich použijí BSD funkce bcopy() a bzero(). ASM FILE FILE START Kód v C, který zajistí vložení potřebného úvodního textu do generovaného assemblerového zdrojového textu. ASM FILE END Obdoba předchozího, ale na konci souboru. ASM OUTPUT {DOUBLE, Metody, které zajišťují výstup zadaného datového typu FLOAT, INT, SHORT, CHAR, do assembleru. BYTE} ASM OUTPUT ASCII Metoda zajišťující výstup řetězu do assembleru. REGISTER NAMES Seznam jmen jednotlivých registrů Základní vlastnosti architektury – Fundamental machine properties Jméno makra {BITS, BYTES, WORDS, FLOAT} BIG ENDIAN FUNCTION BOUNDARY BIGGEST ALIGNMENT STRICT ALIGNMENT
TARGET FLOAT FORMAT
FIRST PSEUDO REGISTER FIXED REGISTERS CALL USED REGISTERS REG ALLOC ORDER NO REGS, ..., GENERAL REGS, ALL REGS
Význam Makro vrací nenulovou hodnotu pokud je cílová architektura pro daný datový typ big-endian. Toto makro definuje potřebu a velikost případného zarovnání startovní adresy funkce. Největší zarovnání jaké se může vyskytnout (pro jakýkoli datový typ). Pokud má nenulovou hodnotu signalizuje nutnost zarovnávání na hranice velikosti datových typů nebo podle příslušných maker. Znamená, že cílová architektura neumí přistupovat k nezarovnaným datům. Pokud není nastaven předpokládá se IEEE FLOAT FORMAT. Dovoluje změnit reprezentaci čísel v pohyblivé řadové čárce. Počet registrů architektury. Nezapočítávají se speciální registry pokud nejsou přímo využitelné gcc. Registry, které nejsou určeny k obecnému použití. Registry, u kterých se má předpokládat změna po volání funkce. Musí obsahovat FIXED REGISTERS. Pole, které definuje preferované pořadí alokace jednotlivých registrů. Registry se dělí do registrových tříd. Minimálně musí být definovány tři třídy (NO REGS, GENERAL REGS, ALL REGS). Poslední dvě mohou mít stejnou hodnotu. Registrová třída je vyjádřena pomocí typu enum reg class.
7
Jméno makra N REG CLASSES REG CLASS NAMES BASE REG CLASS
Význam Počet registrových tříd. Jména jednotlivých registrových tříd jako char *. Definuje která registrová třída je schopna obsahovat adresu. INDEX REG CLASS Definuje která registrová třída je schopna sloužit jako index v některých adresních módech. HAVE {PRE, POST} {INC, Definuje, zda má architektura adresní módy s vedlejším DEC}REMENT efektem. MEMORY MOVE COST (M) Cena přesunu čehokoli v paměťovém módu M mezi registrem a pamětí. Slouží pro ocenění a případnou penalizaci nějaké možnosti při kompilaci. Překladač tímto způsobem realizuje výběr mezi několika možnostmi a tím optimalizuje. Implicitně je hodnota 2. BRANCH COST Cena instrukce větvení. Implicitní cena je 1. Při vyšší ceně se gcc bude snažit větvení nahradit alternativní sekvencí instrukcí bez větvení.
ABI – Application binary interface Jméno makra PARM BOUNDARY
Význam Zarovnání v paměti v bitech parametrů předávaných na zásobníku. LONG, Velikosti jednotlivých C typů v bitech. DOUBLE,
{INT, SHORT, CHAR, FLOAT, LONG DOUBLE, WCHAR} TYPE SIZE STACK GROWS DOWNWARD
Definován pokud stack-pointer (ukazatel zásobníku) se s přidání nové položky na zásobník zmenší (jde k nižším adresám). Pro většinu architektur je pravda. ARGS GROW DOWNWARD Definován pokud argumenty funkce zprava doleva při jejím volání předány v klesajícím pořadí. Pro většinu architektur není pravda. . . . ARGS . . . Definují práci s argumenty funkcí. Jejich reprezentaci na zásobníku, interní podobu kumulovaných parametrů pro předání apod. FUNCTION VALUE Vrací popis vnitřní struktury ve které je možné nalézt návratovou hodnotu po volání funkce (pro jednoduché typy). FUNCTION PROLOGUE Toto makro vypíše do FILE assemblerový kód pro za(FILE, SIZE) čátek funkce. V tomto kódu bývají typicky věci jako uložení registrů a nastavení frame-pointeru. FUNCTION EPILOGUE (FILE, Toto makro vypíše do FILE assemblerový kód pro konec SIZE) funkce. Musí být schopno se vyrovnat s více násobným výskytem return v kódu. V takovém případě nic nevrací.
8
Jméno makra
Význam
Machine description support Jméno makra REG CLASS FROM LETTER (CHAR) CONST OK FOR LETTER P (VALUE, C) CONST DOUBLE OK FORLETTER P (VALUE, C) EXTRA CONSTRAINT LUE, C)
3.2.2
(VA-
Význam Registrová třída, která odpovídá předanému registrovému znaku CHAR. Vrací nenulovou hodnotu pokud hodnota VALUE odpovídá floating-point hodnotám reprezentovaných písmenem C. Vrací nenulovou hodnotu pokud hodnota VALUE odpovídá floating-point hodnotám reprezentovaných písmenem C. Vrací nenulovou hodnotu pokud VALUE odpovídá některému ze speciálních operandů reprezentovaných C (jiné typy než floating-point, integer constant, floatingpoint constant).
Soubor zdrojového kódu v C – tm.c
Vzhledem k tomu, že většina maker definovaných v tm.h by byla příliš náročná pro další ladění, kdyby byla definována přímo. Používá se místo přímého vložení kódu do makra volání funkce, která plní jeho úkol. Tyto funkce se dají již běžnými prostředky celkem pohodlně ladit. Je zavedena jmenná konvence, která říká, že funkce se jmenují stejně jako makra, ale jsou psána malými písmeny. Vlastní definice makra tedy vypadá nějak takto: #define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc (EXP, INSN) extern void notice_update_cc(); Dále se v tomto souborů deklarují pomocné funkce např. pro popis cílového stroje – md.
3.2.3
Popis cílového stroje – md
Popis cílového stoje je napsán ve speciálním jazyce RTL. Tento jazyk je podobný jazyku, který je používán pro popis interních reprezentací dat – RTX. Popis instrukcí sestává z instruction template patterns, která se používají jak při generování (generation) tak při porovnávání (matching). Při překladu se nejdříve vytvoří základní sekvence instrukcí, které se pak několika dalšími průchody optimalizují do výsledného kódu. Definice instrukce – Instruction definition patterns Syntaxe struktury popisující instrukci je následující: (define_pattern-type "(optional) pattern name" [(set (target) (the operand)) optionally more setting-effects] "optional pattern-condition" 9
"output template" (optionally: [attribute settibgs]) ) pattern name Jméno je nepovinné, prázdný řetěz vytvoří anonymní vzor. Pokud je jméno uvedeno musí být unikátní. Některá jména jsou rezervovaná. Pokud některá ze standardních operací není definovaná zavolá se knihovní funkce. pattern-type Existují dva typy: define insn Nejčastěji používaný typ. Možný jak pro generační tak srovnávací vzor. defina expand U některých standardních operací se místo volání knihovní funkce více hodí rozklad do více instrukcí ({pattern expansion}). Tento typ vzorů je používán pouze pro rozklad standardní funkce na posloupnost instrukcí, nepoužívá se při syntéze komplexních instrukcí z jednodušších. the operand Tvořen kompozitem popisujícím operandy. Např. pro součet by vypadal takto: (plus:M (opernad1) (operand2)), kde M znamená mód a operandy mohou být zase složené operandy. target Formální popis výstupu instrukce. more setting-expressions Další (set ...) výrazy. Není u nich zajištěno pořadí vyhodnocování (ideálně jsou spouštěny paralelně), proto je nelze používat navzájem mezi sebou. pattern-condition Nepovinný test, zda se vzor má uplatnit (implicitně pravda). Testovat lze nastavení TARGET FLAGS, hodnota podmínky musí být známa již při kompilaci a je tedy konstantní po celou dobu běhu. output template Vlastní assemblerový kód realizovaný tímto vzorem. Může být také část C zdrojového kódu. attribute settings Pokud některý z atributů instrukce není pokryt standardním nastavením lze jej nastavit v tomto místě. Ukažme si definici šablony na konkrétním příkladu z portu na CRIS: (define_insn "xorsi3" [(set (match_operand:SI 0 "register_operand" "=r") (xor:SI (match_operand:SI 1 "register_operand" "%0") (match_operand:SI 2 "register_operand" "r")))] "" "xor %2,$0" [(set_attr "slottable" "yes")] ) Definovali jsme šablonu pro operaci xor. Operandy jsou 32b registry (mód SI). Instrukce platí pouze pro registry, proto je u všech operandů predikát register operand. Dále platí, že cíl operace musí být stejný jako jeden z operandů. Proto je u prvního operandu uvedeno pravidlo %0, které povoluje prohození s dalším operandem (číslo 2) při porovnávání, ale musí být stejný jako cílový operand číslo 0. 10
Prázdná část pattern-condition dává tušit, že šablona je vždy platná. Assemblerový výstup je jednoduchý, protože se přímo použije instrukce xor, kde výstupní operand je ten poslední. Operand číslo 1 není použit, protože se musí shodovat s operandem 0 – cílem operace. Dále jsme instrukci nastavily vlastnost slottable. Dáváme tím překladači na jeho možnost použití instrukce ve volném slotu po rozhodovacích funkcích (místo implicitního nop). Rozklad instrukcí – Instruction splitting V některých případech může být rychlejší rozdělit komplexnější instrukci na volání několika jednodušších. K takovýmto situacím může docházet pokud architektura obsahuje instrukce, které potřebují pro vykonání čas navíc. Ke zrychlení potom může např. dojít vyplněním čekacích slotů užitečnými instrukcemi. Pro realizaci rozkladu instrukcí jsou potřeba vzory/šablony, které jej popisují. Pokud se gcc rozhodne pro rozklad nějaké instrukce neprovádí při neúspěch opět její složení. Proto je dobré, když rozklad instrukce je v nejhorším stejně náročný jako původní instrukce. Syntaxe struktury popisující rozklad instrukce je následující: (define_split [(set (target) (the operand)) optionally more setting-patterns] "optional pattern-condition" [(replacement-setting-pattern) optionally-more-replacement-setting-patterns] "optional-preparation-statements" ) Pokud je pattern-condition pravda a po vykonání preparation-statements se nahradí první seznam ohraničený [ a ] druhým seznamem. Opět si ukažme definici šablony na konkrétním příkladu z portu na CRIS: (define_split [(set (match_operand 0 "register_operand" "=r") (match_operand 1 "indirect_operand" "m"))] "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD && (GET_CODE (XEXP (operands[1],0)) == MEM || CONSTANT_P (XEXP (operands[1],0)))" [(set (match_dup 2) (match_dup 4)) (set (match_dup 0) (match_dup 3))] "operands[2] = gen_rxt (REG, Pmode, REGNO (operands[0])); operands[3] = gen_rxt (MEM, GET_MODE (operands[0]), operands[2]); operands[4] = XEXP (operands[1],0);" ) Co vlastně tato šablona rozpoznává? Šablona pozná instrukci move.S [address],rX, kterou transformuje do dvou instrukcí move.d address,rX a move.S [rX],rX. Predikát šablony určuje, že address je paměťový operand jehož adresa je general operand. Dále se v podmínkové části deklarují další omezující podmínky pro použití šablony. 11
Nejdříve se ověří, že operandy mají takový mód, který odpovídá registru, dále ověří, že address je konstanta nebo reference do paměti. Přípravná část šablony použije cílový registr jako pomocný pro operand 2, dále provede indirect pro operand 3, nastaví korektně jeho mód. address je uložena v operandu 4. Povšimněte si, že nejsou použity žádné nové registry1 . Peephole optimalization U některých sekvencí instrukcí nemusí být právě jednoduché rozpoznat možnou optimalizaci. Může gcc dát návod jak má určitou sekvenci optimalizovat, takovéto optimalizaci se říká peephole optimalization2 a deklaruje se pomocí define peephole. Formát definice je obdobou define expand a define insn. Uveďme si tedy rovnou příklad: (define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "const_int_operand" "n"))) (set (match_operand 3 "register_operand" "=r") (mem (match_dup 0)))] "GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD && REGNO (operands[3]) != REGNO (operands[0]) && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)" "move.%s3 [%0=%1%S2],%3" ) Šablona pozná poměrně vzácný sled instrukcí, kdy instrukce add.d n,rX následuje po instrukci move.S [rX],rY. Takováto dvojice se dá transformovat do jedné instrukce move.S [rX=rX+n],rY. Podmínková část ověřuje velikost operandů, dále provádí kontrolu, zda není cílový registr stejný jako registr použitý pro nepřímý přístup, a na závěr otestuje povolené rozsahy offsetu. Definice atributů Pro zjednodušení popisu architektury lze zavést různé atributy. Atributy lze dále používat pro spojování instrukcí do skupin, s jejichž prvky lze zacházet podobně. Základní tvar definice atributu je tento: (define_attr name list-of-values default) V portu na CRIS je dodefinován pouze jeden atribut, uveďme si jej tedy jako příklad: (define_attr "slottable" "no,yes,branch" (const_string "no")) 1
Pokud je potřeba alokovat nějaké nové registry, je dobré přidat test globální proměnné reload completed do podmínkové části. Proměnná bude nenulová, pokud nemohou být nové registry alokovány. 2 Jak tento termín říci česky opravdu netuším, něco mi říká, že průzorová optimalizace nebude to pravé. . .
12
Tímto byl zadefinován atribut slottable, který indikuje možnost vložení instrukce do volného slotu po instrukci větvení. Třetí možná hodnota branch slouží k indikaci instrukce větvení a instrukce ret a znamená tedy také ne, protože tyto instrukce se do slotu vložit nemohou. Hodnoty atributů mohou být čteny i z céčkových funkcí, které slouží ke generování assemblerového kódu a i z jiných pomocných funkcí.
3.2.4
Definice časových parametrů – Delay definitions
Existuje popisný mechanismus pro vyjádření čekání v různých částech programu, pro popis časového chování jednotlivých instrukcí. GCC se potom při překladu snaží zaplnit všechny volné sloty, aby dosáhl kratších vykonávacích časů. Syntaxe struktury je následující: (define_delay attribute-test-expression [first-delay-filler first-annul-taken first-annul-not-taken more-optional-delay-filler-expressions-when-taken-or-not-taken] ) attribute-test-expression Výraz vyhodnocující hodnotu atributu (nebo více atributů). Je pravda, pokud takové kombinaci atributů odpovídá takovýto delay-slot. first-delay-filler Výraz, který odpovídá instrukcím, které se mohou vložit do delay-slotu a jsou vždy spuštěny, nezávisle na vyhodnocení podmínky. first-annul-taken Výraz, který odpovídá instrukcím, které mohou být vloženy do delayslotu, ale nejsou vykonány pokud je podmínka větvení splněna. first-annul-not-taken Výraz, který odpovídá instrukcím, které mohou být vloženy do delay-slotu, ale jsou vykonány pouze tehdy, když je podmínka větvení splněna. more-optional-delay-filler-expressions-when-taken-or-not-taken Pokud definujeme čekání, které obsahuje více delay-slotů může se zde pro každý z nich definovat kombinace předchozích výrazů. Pokud neexistuje instrukce, která by odpovídala některému typu, umisťuje se do popisu (nil). Pro CRIS mají jeden delay-slot instrukce větvení a instrukce ret (atribut slottable je pro ně nastaven na hodnotu branch). (define_delay (eq_attr "slottable" "branch") [(eq_attr "slottable" "yes") (nil) (nil)] )
13
Kapitola 4 Závěr Pokusil jsem se v této práci shrnout některé základní informace o gcc a jeho portování na nějkou architekturu. Velká část obsahuje je, ale tvořena upravenými částmi dokumentace, protože tato je velice dobře napsaná a obsahuje spoustu informací, které se poměrně těžko zjednodušují, aniž by se člověk dopouštěl snižování informační hodnoty. Také jsem zjistil, že napsání portu není na jednu stranu jednoduchá věc (jeden z hlavních materiálů, které jsem použil, byla diplomová práce), ale na druhou stranu to není ani nepřekonatelný problém. V rámci samostatné semestrální práce v jednom předmětu není dostatek času na vypracování návodu, jak napsat port. Pokud by někdo, např. jako svou diplomovou práci, měl portovat gcc na nějaký procesor mohl by tento návod vytvořit v rámci semestrálního projektu, jakožto přípravu k diplomové práci. Klíčem k pochopení způsobu portace je jednoznačně studium manuálu ke gcc společně se zdrojovými texty již existujících portů.
14
Literatura [gcc]
Dokumentace k překladači gcc Dostupné v elektronické formě na adrese http://gcc.gnu.org/onlinedocs/
[Nilsson]
Hans-Peter Nilsson. Porting The Gnu C Compiler to the CRIS architecture. Dostupné v elektronické formě na adrese ftp://ftp.axis.se/pub/axis/tools/cris/misc/ pod jménem rapport.formát (např. rapport.ps).
[cris]
Popis architektury CRIS (Code Reduced Instruction Set) Výrobce: Axis Communications Dokumentace je dostupná na adrese http://developer.axis.com/
15