Aktivaatiotietue Yleiskäsite funktio (aliohjelma) -mekanismin tarvitsemille tiedoille Parametrit ja paluuarvo Paluuosoite Linkkitiedot Kehysosoitin (%fp) missä tiedot ovat Missä edellisen tiedot ovat (palattaessa palautettava)
aktivaatiotietue Sijainti toteutuskohtainen Arkkitehtuuri sanelee toteutustavan Yleensä osin rekistereissä ja osin muistissa Rekistereissä ainakin kehysosoitin (%fp) ja aktiiviset muuttujat
Aktivaatiotietue - konsepti
Sparc-arkkitehtuuri Rekisterit Saapuvat parametrit Kehysosoitin (%fp) ja paluuosoite (%i7) Paikalliset muuttujat Lähtevät parametrit Pino-osoitin (%sp) Yleiset muuttujat Nollarekisteri (%g0)
Sparc-arkkitehtuuri Pinokehys Paikalliset muuttujat Talletustila rekistereille Väliaikaistilaa kääntäjän käyttöön
Koodin generointi Kääntäjä muuntaa korkeantason kielen käskysekvensseiksi Arkkitehtuuri sanelee mitä voi tehdä Missä voi laskea Rekistereissä vai muistissa Missä muuttujia voi säilyttää Rekistereissä vai muistissa
Ohjelman rakenne Ohjelma jakautuu (muistissa) alueisiin (sektioihin) Koodi Data Pino
Koodingenerointi (sparc) Sparc periaatteet Laskenta vain rekistereissä Load-store arkkitehtuuri Muuttujat rekistereihin aina kun mahdollista Parametrit in- ja out rekistereihin Paikalliset ja väliaikaismuuttujat local-rekistereihin Myös out-rekisterit käytettävissä väliaikaisille muuttujille In-rekisterit paikallisille muuttujille
Lausekkeen laskenta (konsepti) x = a + b * c (load b to reg %b) (load c to reg %c) mul %b,%c,%tmp0 (load a to reg %a) add %a,%tmp0,%tmp1 (store %tmp1 to x) Latauksia ei tarvita jos muuttuja on sijoitettu rekisteriin Laskennan tulos voitaisiin sijoittaa suoraan kohteeseen, mikäli se on rekisterissä
ehtolause If a == b then... else.. (load a to reg %a) (load b to reg %b) cmp %a,%b bne 1f nop... bra 2f 1:... 2: Taas lataukset optionaalisia Tulos tallentuu tilalippuihin Totuusarvoista muuttujaa ei tarvita
Silmukka - while While a!= b do... 1: (load a to reg %a) (load b to reg %b) cmp %a,%b beq 2f nop... bra 1b nop 2: Suoraviivaisesti toteutettuna Lähes sama kuin if Vain hypyt hieman eri tavalla
vaihtoehtoisesti - while While a==b do... bra 1f nop 2:... 1: (load a to reg %a) (load b to reg %b cmp %a,%b beq 2b nop 1: Siirretään testi loppuun ja tehdään yksi hyppy vähemmän, tavallinen toteutus
Silmukka - for For( a = 0; a<n;a+ +)... Hyppy taas siirretty loppuun store %g0 to a bra 2f nop 1:... (load a to %a) add 1 to %a (store %a to a) 2: (load a to %a) cmp %a,#n-1 ble 1b nop Naiivi käännös tekee turhia load ja store operaatioita Tavanomaista optimoimattomassa käännöksessä
Silmukka do.. while Do... while (a == b ); 1:... (load a to %a) (load b to %b) cmp %a,%b beq 1b nop Kohtalaisen suoraviivaista
Vaihtoehtolause -- switch Ketjutettuna iflauseena if( x == 1)... else if( x == 2 )... else if( x == 3 )... else... hyppytauluna load label s to %s (load x to %x) (scale %x) add %x,%s,%s jmp [%s] nop s: bra xeq0 nop bra xeq1 nop...
Vaihtoehtolause - switch Kumpaa käytetään? Ketjutettu if turvallinen ratkaisu mutta hidas Käytetään kun ehdon arvoalue harva tai laaja Hyppytaulu Nopea toteutus Vaatii paljon tilaa, mikäli arvoalue laaja Ei sellaisenaan käy mm. kokonaislukutyypille
Vaihtoehtolause - switch Ratkaisuna käytetään yhdistelmää Hahmotetaan arvoalue Tiuhalle kohdalle hyppytaulu Äärialueet hoidetaan if -lauseella
Aliohjelmakutsu void f( int, int );... f( a, b );...... load a to %o1 load b to %o2 call f... Periaatteessa helppoa Parametrit paikalleen Ja menoksi Rekisteriparametrien kanssa ei siivottavaa jälkeenpäin
aliohjelmakutsu C(++)-kielen parametrin välitys Arvoparametrit Välitetään arvo Parametri voi olla vakio, muuttuja tai lauseke Viiteparametrit Välitetään viite (osoite) Parametri voi olla muuttuja Lausekkeilla ja vakioilla ei ole osoitetta
C(++)-kielen parametrin välitys Skalaarimuuttujat arvonvälityksenä Eksplisiittiset viiteparametrit Taulukot viitteenvälityksenä Rakenteet mahdollisia arvonvälityksenä Luodaan väliaikaismuuttuja, johon arvo kopioidaan Eksplisiittiset viiteparametrit
Parametrinvälitys Muita mekanismeja Nimenvälitys Saantifunktio Vähemmän käytettyjä
Funktion paluuarvo Yleensä rekisterissä (%i0 Sparcilla) Kehyksessä, jollei mahdu rekisteriin Jotkut kielet (mm. C-kieli aiemmin) sallivat vain skalaariarvot paluuarvoina Osoittimen käyttö kiersi rajoituksen C:ssä Rakenteiden (tai taulukoiden) palautus arvona vaatii kopiointeja, mikä on tehotonta.
aliohjelma void f( int a, int b ); f: (talleta vanha %fp) (varaa tila kehykselle) (talleta rekisterit) (alusta paikalliset)... (palauta rekisterit) (vapauta kehys) (vapauta tila) (palauta %fp) ret sparc-käytännössä f: save %sp,-112,%sp st %i0,[%fp+68] st %i1,[%fp+72] return %i7+8 nop
Sparc aliohjelma Tehty helpoksi f: save %sp,-112,%sp st %i0,[%fp+68] st %i1,[%fp+72] return %i7+8 nop Save -käsky vaihtaa rekisteri-ikkunaa ja samalla päivittää %fp:n ja %sp:n hoitaessaan tilavarauksen Return palaa ja palauttaa rekisteriikkunan
Entä paluuarvo C-kielen return lause kopioi paluuarvon oikeaan paikkaan Skalaarit rekisteriin Muut kehyksestä löytyvän osoittimen ilmaisemaan paikkaan Kutsuja on varannut tilan paluuarvolle, jos tarvitaan
Paluuarvon käsittely seuraavassa int f( a ); int x;... x=f(f(x+1)+2)+3;... Siis (load x to reg %x) add %x,#1,%o1 call f -- tmp=f(x+1) add %o0,#2,%o1 call f --tmp=f(tmp+2) add %o0,#3,%tmp0 (store %tmp0,x)
Leaf-aliohjelma Jos funktio (aliohjelma) ei kutsu muita funktioita, kutsutaan sitä leaf-aliohjelmaksi (leafprosedure) Tällöin sille ei tarvitse välttämättä rakentaa omaa kehystä, jos se voi toimia pelkästään rekistereiden varassa out-rekisterit käytettävissä In- ja local-rekisterit ovat kutsuja rekistereitä, niihin ei saa koskea
Aliohjelmista Aliohjelma mekanismin yhteydessä määritellään, miten rekistereitä käytetään älä koske rekisterit %sp, %fp, paluuosoite, globaalit osoittimet älä tärvele rekisterit Kutsujan käyttämät rekisterit Vapaat rekisterit Paluuarvo, parametrit
Aliohjelmista Aliohjelma kutsun prologuessa raivataan tila aliohjelman käyttöön Sparcilla rekisteri-ikkunoinnin save-restore protokolla antaa aliohjelmalle käyttöön omat rekisterit Muilla arkkitehtuureilla vastaava asia tehdään käsityönä Muistettava kirjoitettaessa konekielisiä aliohjelmia
Aliohjelmista Tehtävä: talleta prologuessa ne rekisterit, joita aliohjelma käyttää Ongelma: en tiedä mitä rekistereitä käytetään, koska en ole vielä kääntänyt aliohjelmaa Miten asiasta selvitään?
Aliohjelmista Sparc: kovolla talletaan kaikki Mc680x0: movem käskyn parametrina on rekisteri luettelo, jonka voimme määritellä jälkeenpäin (kiitos symbolisen assemblyn) Muutoin: generoidaan koko prologue jälkeenpäin, tähän vain hyppy sinne ja label johon palata
Taulukoiden käsittely Taulukko joukko peräkkäisiä samantyyppisiä alkioita. C-kielessä item_type v[n_items];... x = v[i];...
Taulukoiden käsittely Taulukko vaatii muistia N_ITEMS * sizeof( item_type ) C-kielen tulkinta v[i] <==> *(v+i) Indeksointi vaihtoehtoinen (lyhennys)merkintä osoitearitmetiikasta
Taulukoiden käsittely Toteutus viittaukselle v[k]; On siis sama kuin *(v + k); Huomaa kantaosoitteesta v: globaalilla muuttujalla vakio Paikallisella muuttujalla %fp+offset Joka kääntyy (lataa v rekisteriin %v) (lataa k rekisteriin %k) (eli laske indeksin arvo) mul %k,#item_size,%k add %v,%k,%tmp (osoite rekisterissä %tmp)
Rakenteiden käsittely C-kielen struct struct point { int x, y; }; Analogisia taulukoiden kanssa Kantosoitteeseen lisätään siirtymä
Rakenteista Taulukoilla Kanta vakio, siirtymä (indeksi * koko) muuttuu Rakenteilla Kanta muuttuu, siirtymä pysyy vakiona
Osoittimet Osoittimien käsittely sinällään helppoa Osoitteilla lasketaan kuitenkin Joissakin arkkitehtuureissa apukäskyjä Lea load effective address Pea push effective address
Yleistä Tyyppitiedon käsittely kääntäjän työläinpiä osia Käskykoodin valinta Byte, word, long vai float Tyyppikonversiot
C-kielen piirteitä Ehdollinen lauseke --> expr?expr:expr; Pilkkulauseke --> expr, expr; Increment/decrement --> ++var; Päivitys operaatiot --> var += expr; Ehtojen evaluointi --> && ja
Ehdollinen lauseke Itseasiassa pieni if-lause Kääntyy samalla tavalla Syntaktinen kikka, joka mahdollistaa ehdollisuuden silloinkin kun statement- mahdoton käyttää Arkkitehtuureissa nykyään mm. CMOV -käsky Ehdollinen siirto ARMilla kaikki käskyt ehdollisia, tehostaa liukuhihnaa
pilkkulauseke Myös syntaktinen kikka, jotta useampi sijoitus mahdollinen yhdessä lausekkeessa Evaluointijärjestys?
Increment, decrement Lyhennysmerkintä i++ <=> i += 1 <=> i = i+1 Helpottaa kääntämistä Kääntyy suoraan kaksioperandikäskyksi Osoitinlaskennassa muista skaalaus Evaluointijärjestys Pre- ja post- operaatiot erikseen
Pre- ja post- operaatiot Evaluiointi järjestys määritelty ++i; i++; --i; i--; // ensin kasvatus, sitten käyttö // ensin käyttö, sitten kasvatus // ensin vähennys, sitten käyttö // ensin käyttö, sitten vähennys Osoittimilla skaalaus alkion koolla Mukavasti soveltaa inc, dec käskyjä Tai autoincrement, autodecrement osoitusta
Ehtojen evaluointi Looginen and ja or ( && ja ) C-kielessä evaluiointi ns. oikosulkevaa if( A && B ) {... } Jos A == FALSE ei B:tä evaluoida lainkaan A määrää totuusarvon
Oikosulkeva evaluointi Eli muunnetaan ja if(a && B) {...} ==> if( A ) { if( B ) {..} } if( A B ) {...} ==> if( A ) {..} else if( B ) {..}
Oikosulkeva evaluointi Yksinkertaistaa ehtojen kääntämistä Ei tarvitse muistaa alkuosan tulosta Joissakin kielissä määritelty toisin Vaikuttaa olleellisesti, mikäli ehtoina funktiokutsuja
Totuusarvoista C-kielen totuusarvo Testattaessa nolla <=> false, ei nolla <=> true Mikä tahansa lauseke käy totuusarvoksi Osoittimilla NULL vastaa nollaa Sijoitettaessa nolla <=> false, 1 <=> true Siis vaikkapa x = a < b; Mitä on!!x? x vai 1?
evaluointijärjestys C(++) -kielestä mainitaan The order of evaluation of subexpressions within an expression is undefined. Brarne Stroustrup, The C++ programming language, thhird edition, sivu 122
Eavluointijärjestys muuten C(++)-kielen määrittely sallii kääntäjän evaluoida alilausekkeita haluamassaan järjestyksessä Vaikutus saattaa näkyä, jos alilausekkeilla sivuvaikutuksia int i = 1; v[i] = i++; // joko v[1] =1 tai v[2] = 1
Sivuvaikutuksia Sivuvaikutus Tarkoittaa lauseke muuttaa globaalia tilaa Sijoitus, inkrement, funktiokutsut Joskus syytä olla varovainen Evaluointijärjestys saattaa vaihdella järjestelmästä toiseen Vaikuttaa koodin siirrettävyyteen Vältä lausekkeita, joilla on runsaasti sivuvaikutuksia
Koodin generoinnista vakiolaskenta Indeksointien yhteydessä Rakenteiden yhteydessä Käskynvalinta Yksinkertaiset muunnokset Kertolasku yhteenlaskuksi ja sivuttaissiirroiksi Jakolasku (vakiolla) kertolaskuksi jakojäännös (kahdenpotenssin) maskaukseksi Osoitusmuotojen käyttö Lea (load-effective-address) ja skaalattu indeksointi
Koodin generoinnista Optimointeja Ehdolliset käskyt Mahdollistavat pienten hyppyjen välttämisen CMOV (conditional move) pentiumilla Kaikki käskyt ARMilla Esim max( a, b ) If( a > b ) { return a; } else { return b; } cmp %r0,%r1 ; cmov lt, %r1, %r0 CMOV voidaan emuloida vaikka carrylipun kautta Sub %r1, %r0; sbc %r2, %r2; and %r2,%r0 ; add %r1, %r0