CRL2ALF
- En ¨overs¨attare fr˚
an
PowerPC-maskinkod till h¨ogniv˚
aspr˚
aket
ALF
Jens Bj¨
ornhager
CDT504 - Examensarbete i datavetenskap, avancerad niv˚
a, 30hp
Akademin f¨
or innovation, design och teknik
M¨
alardalens h¨
ogskola, V¨
aster˚
as
ht 2010, vt 2011
Handledare: Linus K¨
allberg
Examinator: Jan Gustafsson
Sammanfattning
Realtidssystem st¨
aller h˚
arda krav p˚
a dess ing˚
aende mjukvaras temporala
beteen-de. Programmen m˚
aste bete sig deterministiskt och ge svar inom satta tidsgr¨
an-ser. Med h˚
arda krav f¨
oljer st¨
orre behov av verktyg att testa koden med. WCET
(Worst Case Execution Time)-analys har som m˚
al att finna en ¨
ovre gr¨
ans f¨
or
ett programs exekveringstid. SWEET (SWEdish Execution Time) ¨
ar ett
verk-tyg f¨
or WCET-analys utvecklat av en forskargrupp vid M¨
alardalens H¨
ogskola.
PowerPC ¨
ar en klassisk processorarkitektur som utvecklades av Apple,
Motoro-la och IBM och sl¨
apptes 1991. Den har bland annat anv¨
ants av Apple i ¨
aldre
versioner av deras Macintosh-datorer och i TV-spelskonsoler s˚
asom Nintendo
GameCube och ¨
ar stor inom inbyggda system.
Tidigare har endast analys av k¨
allkod, C, varit m¨
ojlig i SWEET. M˚
alet f¨
or detta
examensarbete var att m¨
ojligg¨
ora analys av k¨
orbara program f¨
or vilka k¨
allko-den ej ¨
ar tillg¨
anglig, Detta gjordes genom att konstruera en ¨
overs¨
attare fr˚
an
PowerPC-bin¨
arer till det programformat som SWEET anv¨
ander f¨
or sina
statis-ka analyser, ALF, med hj¨
alp av tredjepartsverktyget aiT fr˚
an AbsInt GmbH.
Resultatet blev en med undantag f¨
or flyttalsinstruktioner komplett ¨
overs¨
attare
av PowerPC-program till ALF-kod. De flesta genererade programfiler som har
testats i SWEET har gett lyckat resultat.
Abstract
Real-time systems put tough timing requirements on the software running on
them. The programs must behave deterministically and respond within set time
limits. With these demands comes a higher demand on verification tools. The
goal of a WCET (Worst Case Execution Time) analysis is to derive the upper
bound of a program’s execution time. SWEET (SWEdish Execution Time) is a
tool for WCET analysis developed by a research group at M¨
alardalen University.
PowerPC is a classic processor architecture that was developed by Apple,
Mo-torola and IBM and was released in 1991. It has been used in older versions
of Apple’s Macintosh computers and in video game consoles such as the
Game-Cube from Nintendo, and is a popular choice for embedded solutions.
Previously you could only do analyses on code generated from C in SWEET.
The goal of this MSC thesis was to construct a converter from PowerPC binaries
to the program format that SWEET uses for its analyses, ALF, with the help
of the third-party tool aiT from AbsInt GmbH.
The result is a - with the exception of floating-point instructions - complete
converter from PowerPC programs to ALF. Most of the generated program files
have been tested within SWEET with successful results.
Inneh˚
all
1
Introduktion
3
1.1
Bakgrund . . . .
3
1.2
Id´
e . . . .
3
1.3
ALF . . . .
3
1.4
PowerPC
. . . .
4
1.5
ELF . . . .
5
1.6
aiT . . . .
5
1.7
CRL2 . . . .
5
1.8
libcrl2 . . . .
6
1.9
Plattform . . . .
6
2
Uppgift
7
2.1
Oversikt . . . .
¨
7
3
Overs¨
¨
attning
8
3.1
Header . . . .
8
3.2
Strukturer i CRL2 . . . .
8
3.2.1
Data . . . .
9
3.2.1.1
Bytes . . . .
9
3.2.2
Rutiner . . . .
9
3.2.3
Basblock
. . . .
9
3.2.4
Instruktioner . . . .
12
3.2.5
Operationer . . . .
12
4
Overs¨
¨
attningsmotor
13
4.1
Map . . . .
13
4.2
Pre-preprocessing . . . .
13
4.3
Preprocessing . . . .
14
4.4
Processing . . . .
14
4.5
Postprocessing
. . . .
15
4.6
K¨
ormilj¨
o . . . .
15
4.7
Exempel . . . .
15
4.7.1
add. r1, r2, r3 . . . .
16
4.7.2
bt cr7.gt, 0x100004c8.f . . . .
18
4.7.3
En hel rutin . . . .
19
5
Utf¨
orande
28
5.1
Problem . . . .
29
6
Resultat
30
6.1
Diskussion . . . .
30
6.2
Framtida arbete . . . .
31
Kapitel 1
Introduktion
I det h¨
ar avsnittet ges en introduktion till ¨
amnet, id´
en bakom projektet och
viktiga komponenter d¨
ari.
1.1
Bakgrund
Realtidssystem st¨
aller h˚
arda krav p˚
a dess ing˚
aende mjukvaras temporala
bete-ende. Programmen m˚
aste bete sig deterministiskt och ge svar inom satta
tids-gr¨
anser. Med h˚
arda krav f¨
oljer st¨
orre behov av verktyg att testa sin kod med.
WCET-analys (Worst Case Execution Time) har som m˚
al att finna en ¨
ovre gr¨
ans
f¨
or ett programs exekveringstid. SWEET (SWEdish Execution Time) ¨
ar
insti-tutionens egna verktyg f¨
or programanalys. Verktyget tar i nuvarande version
program i ALF-format som input och kan utf¨
ora fl¨
odes- och v¨
ardeanalys[2].
1.2
Id´
e
Tidigare fanns ett verktyg att ¨
overs¨
atta fr˚
an C-kod, men man ville ut¨
oka m¨
ojlig-heterna f¨
or analys till bin¨
arer. Forskningsgruppen kom med ett erbjudande om
att bygga vidare p˚
a tidigare exjobb[1] att konvertera maskinkod till ett format
som SWEET f¨
orst˚
ar, ALF. De tidigare exjobben inriktade sig p˚
a PowerPC och
NEC850V, men resulterade ej i en f¨
ardig ¨
overs¨
attare.
Det best¨
amdes att PowerPC skulle vara den huvudsakliga arkitekturen f¨
or detta
exjobb, dock skulle det g¨
oras l¨
att att ut¨
oka projektet med st¨
od f¨
or fler
arkitek-turer. F¨
or att begr¨
ansa omfattningen av arbetet valdes st¨
od f¨
or flyttal bort.
1.3
ALF
ALF (ARTIST2 Language for Flow Analysis) ¨
ar ett sekventiellt imperativt
spr˚
ak
1som p˚
aminner om Lisp[2]. ALF delar egenskaper med b˚
ade h¨
ogniv˚
aspr˚
ak
och l˚
agniv˚
aspr˚
ak. Det ¨
ar konstruerat f¨
or att vara enkelt att utf¨
ora analys p˚
a och
f¨
or att kunna genereras fr˚
an m˚
anga olika k¨
allor, till exempel h¨
ogniv˚
aspr˚
ak som
C, intermedi¨
arkod och maskinkod. I ALF ¨
ar minnet uppdelat i segment som
kallas frames och adresseras med en baspekare, fref, och ett offset. I spr˚
aket ¨
ar
kod och data disjunkta; det skiljs mellan program- och dataadresser, detta
med-f¨
or att sj¨
alvmodifierande kod ej kan modelleras p˚
a ett direkt s¨
att. Program ¨
ar
uppdelade i rutiner, func. Rutinerna inneh˚
aller satser som kan ha en tillh¨
orande
label. H¨
ar ¨
ar exempel p˚
a hur en sats kan se ut:
1 { l a b e l 32 { l r e f 32 b l o c k _ a s m s t a r t _ 1 A } { d e c _ u n s i g n e d 32 0 } } 2 /* " add r1 , r2 , r3 " ( add ) */ 3 { s t o r e 4 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } /* r1 < - r2 + r3 */ 5 w i t h 6 { add 32 7 { l o a d 32 { a d d r 32 { f r e f 32 r2 } { d e c _ u n s i g n e d 32 0 } } } 8 { l o a d 32 { a d d r 32 { f r e f 32 r3 } { d e c _ u n s i g n e d 32 0 } } } 9 { d e c _ u n s i g n e d 1 0 } } }
Den h¨
ar koden l¨
agger summan av v¨
ardena i r2 och r3 i r1. F¨
orklaring:
Rad 1 En label som m¨
arker ut satsen med namnet block asmstart 1A och offset
0.
Rad 2 Kommentar i C-stil.
Rad 3 B¨
orjan p˚
a en store-sats
Rad 4 F¨
orsta argumentet till store; den eller de adresser d¨
ar v¨
ardet ska lagras.
I det h¨
ar fallet r1.
Rad 5 with markerar slutet p˚
a lista av adresser. Efter with kommer en lista
med respektive v¨
arden.
Rad 6 Det v¨
arde som ska lagras p˚
a den tidigare definierade adressen. I det h¨
ar
fallet resultatet av en add-operation.
Rad 7 Argument 1 till add. H¨
ar laddas v¨
ardet fr˚
an r2.
Rad 8 Argument 2 till add. H¨
ar laddas v¨
ardet fr˚
an r3.
Rad 9 Argument 3 ¨
ar eventuell carry man vill inkludera i ber¨
akningen. H¨
ar ¨
ar
den 0 ; ingen carry in.
1.4
PowerPC
PowerPC ¨
ar en klassisk processorarkitektur som utvecklades av Apple,
Motoro-la och IBM och sl¨
apptes 1991. Den har bland annat anv¨
ants av Apple i ¨
aldre
versioner av deras Macintosh-datorer och i TV-spelskonsoler s˚
asom Nintendo
GameCube. Arkitekturen r¨
aknas till RISC
2-familjen, och anv¨
ander som regel
big endian
3. Processorn har 32 stycken generella heltalsregister p˚
a 32 bitar och
32 stycken flyttalsregister p˚
a 64 bitar. Statusregistret p˚
a 32 bitar ¨
ar uppdelat
i ˚
atta fyrabitarsf¨
alt cr0-cr7 d¨
ar cr0 s¨
atts av heltalsinstruktioner, cr1 av
flyt-talsinstruktioner och resten av bland annat cmp
4-instruktioner. Ett 32-bitars
l¨
ankregister finns f¨
or tempor¨
ar lagring av returadress vid subrutinanrop. Ett
annat viktigt register ¨
ar xer (Integer Exception Register), som huserar
carry-och overflow -flaggor.
Processorn har dessa typer av instruktioner:
Load/Store Flyttar data till och fr˚
an minnet. Den enda instruktionstypen som
kan p˚
averka minnet.
Heltal Manipulerar data i heltalsregistren r0-r31.
Flyttal Arbetar med flyttalsregistren f0-f31.
Fl¨
odeskontroll Instruktioner som p˚
averkar programr¨
aknaren och
statusregis-ter.
Processorkontroll Flytt av data till och fr˚
an specialregister och
synkronise-ring.
Minneskontroll Styrning av cache.
1.5
ELF
De exekverbara filerna som kommer fr˚
an GCC under Linux, och har i det h¨
ar
fallet formatet ELF
5. Kod och data ¨
ar uppdelade i segment.
1.6
aiT
aiT ¨
ar en del av AbsInt Angewandte Informatik GmbH:s programsvit a
³ (AbsInt
Advanced Analyzer) f¨
or statisk analys och ¨
ar deras program f¨
or WCET-analys.
EXEC2CRL ¨
ar den komponent av aiT som anv¨
ands p˚
a bin¨
arer f¨
or att skapa de
filer inneh˚
allande kontrollfl¨
odesgraf som anv¨
ands av CRL2ALF.
1.7
CRL2
CRL2 ¨
ar formatet p˚
a de filer som inneh˚
aller kod och analysresultat fr˚
an aiT.
Fil-formatet inneh˚
aller k¨
allprogrammet uppdelat i rutiner, basblock, instruktioner
och data. Om aiT lyckades analysera programfilen fullst¨
andigt ¨
ar
destinatio-nerna f¨
or alla hopp och anrop redan utr¨
onta. D˚
a ber¨
aknade hopp ej gick att
implementera i tillg¨
anglig version av SWEET f¨
orkastar CRL-filer som inneh˚
al-ler ofullst¨
andigt analyserade hopp.
3metod f¨or att lagra flerbytestal i minnet. I det h¨ar fallet mest signifikant byte f¨orst. 4compare
1.8
libcrl2
AbsInts bibliotek libcrl2 anv¨
ands f¨
or att l¨
asa in och tolka CRL-filerna. Det har
ett C++-gr¨
anssnitt.
1.9
Plattform
Kapitel 2
Uppgift
Programmet har som uppgift att ¨
overs¨
atta PowerPC-program i CRL2-format
till en motsvarighet i ALF-format som SWEET kan k¨
ora.
2.1
Oversikt
¨
Program skrivs i ren C eller med inl¨ankad PowerPC-assembler och
kom-pileras med en PowerPC-version av GCC i Linux.
Resulterande ELF-bin¨ar k¨ors genom EXEC2CRL, en del av AbsInt
Ad-vaced Analyzer, a
³. P˚a bin¨aren utf¨ors en kontrollfl¨odesanalys som delar
upp programmet i rutiner, basblock, instruktioner och operationer. Den
resulterande kontrollfl¨
odesgrafen skrivs till en fil i CRL2-format.
CRL-filen matas d¨arefter in i projektets CRL2ALF, d¨ar CRL-filen tolkas
med hj¨
alp av AbsInt-levererade libcrl2 och ¨
overs¨
atts till ALF-form.
SWEET laddar filen och kan exekvera av programmet och beroende p˚a
analys kan man f˚
a ut filer med analysresultat.
Input till verktyget ¨
ar en CRL-fil med det program man vill ¨
overs¨
atta. Den
resul-terande ALF-filen skrivs ut till stdout eller till en angiven resultatfil. Det f¨
orsta
som h¨
ander ¨
ar att programmet tar reda p˚
a fr˚
an vilken arkitektur CRL-filen
skapades. Om arkitekturen ¨
ar implementerad finns en textfil med arkitekturens
namn i programmets rotkatalog. Filen inneh˚
aller s¨
okv¨
agen till alla datafiler som
beh¨
ovs f¨
or ¨
overs¨
attning av filer av denna arkitektur. Dessa filer, som ocks˚
a ¨
ar
textfiler, inneh˚
aller prototyper p˚
a ALF-statements och mallar av instruktions¨
o-vers¨
attningar och laddas in i en map<string,string>, indexerad med filnamnet,
f¨
or l¨
att ˚
atkomst av inneh˚
allet.
Kapitel 3
¨
Overs¨
attning
F¨
or att kunna ¨
overs¨
atta program fr˚
an CRL till ALF m˚
aste man f¨
orst˚
a de ing˚
a-ende strukturerna i CRL och hur man kan beskriva dessa med hj¨
alp av ALF.
3.1
Header
F¨
orst f¨
orbereds en ALF-header och skrivs ut till utfilen. Prototypen finns i
header.txt. Headern inneh˚
aller detta:
Arkitekturspecifika deklarationer; storleken p˚a Least Addressable Unit
1och endianness. I fallet PowerPC 8 bitar respektive Big Endian.
Exports och Imports. Anv¨ands egentligen inte av CRL2ALF, men
entry-pointen till programmet l¨
aggs till som en exportering f¨
or att markera f¨
or
m¨
anskliga l¨
asare var programmet b¨
orjar.
Deklarationer av minne. I fallet PowerPC dess heltalsregister med
tillh¨o-rande flaggor, RAM med stackarea och interna tempor¨
ara variabler.
Initialiseringar av RAM, s˚asom datasektioner. Stackpekare och
framepe-kare pekas in i stacframepe-karean i RAM. Storleken p˚
a stacken ¨
ar i nuvarande
version h˚
ardkodad till 128k.
3.2
Strukturer i CRL2
CRL-filen inneh˚
aller strukturer som m˚
aste ¨
overs¨
attas till motsvarande
represen-tation i ALF. Makron i libcrl2 g¨
or det enkelt att iterera genom alla strukturer av
en typ i ett visst sammanhang, till exempel s˚
a loopar crl_graph_forall_routines(graph,routine)
igenom alla rutiner i given graf.
1Anger minsta adresserbara enhet. ¨Ar vanligtvis 8 bitar - en byte. ¨Aven s˚a i fallet med
3.2.1
Data
Data ¨
ar en beh˚
allare f¨
or datasektioner, initialiserade RAM-adresser. Dessa
inne-h˚
aller i sin tur Bytes-strukturer om de ej ska initialiseras till noll. Datasektioner
¨
overs¨
atts till init-satser i ALF-headern som initialiserar datat i minnet n¨
ar filen
laddas.
H¨
ar ¨
ar en datasektion fr˚
an en programfil kompilerad med GCC under Linux:
data d40 : address =0x10011000 , b y t e _ o r d e r = ’ x3210 ’ , e x e c u t a b l e =0 , f i l e _ s i z e =8 , mem_size =8 , name = " . p l t " , r e a d a b l e =1 , s e a r c h _ o r d e r =1 , s u r f a c e _ a d d r e s s ="0 x10011000 " , t y p e = ’ data ’ , w r i t a b l e =1 { . . . }
Det som ¨
ar intressant h¨
ar ¨
ar att man f˚
ar reda p˚
a sektionens namn (name),
basadressen f¨
or blocket (address) och dess storlek (mem size).
3.2.1.1
Bytes
En Data som inneh˚
aller minst en Bytes betyder att de adresser som ing˚
ar i den
Datan ska initialiseras till de bytes som ˚
aterfinns i Bytes-sektionen. Finns det
ingen Bytes ska sektionen noll-initialiseras d˚
a det ¨
ar lokalt minne som nollas av
operativsystemet.
b y t e s by41 0x10011000 : 8 : c o n t e n t = 8 *[ 0x10 , 0x00 , 0x06 , 0x80 , 0x10 , 0x00 , 0x06 , 0x84 ] ;
3.2.2
Rutiner
En rutin ¨
ar en bit kod som analysatorn i EXEC2CRL har identifierat att
mot-svara en subrutin. En CRL-fil inneh˚
aller minst en rutin: entrypoint-rutinen.
Varje CRL2-rutin ¨
overs¨
atts till en funktion i ALF, func.
r o u t i n e r 0 : address =0x10000480 , i n s t r u c t i o n _ s e t ="common " , l o o p _ s c c = 0 * [ ] , loops =1*[ r1 ] , name=" main " , p e r s i s t e n t _ i d =1 , s e c t i o n = " . t e x t " , s u r f a c e _ a d d r e s s ="0 x10000480 " { . . . }
Det enda som anv¨
ands av detta ¨
ar name, som anv¨
ands som en del av namnet
till den ¨
oversatta funktionen.
3.2.3
Basblock
Rutinerna ¨
ar i sin tur uppdelade i s˚
a kallade basblock (eng: basic blocks). De ¨
ar
snuttar kod d¨
ar endast f¨
orsta instruktionen hoppas till och endast sista
instruk-tionen branchar. Basblocken utg¨
or noder i kontrollfl¨
odesgrafen. D˚
a Basblocken
i CRL2 bara ¨
ar en beh˚
allare f¨
or instruktioner ¨
overs¨
atts de bara till en label
som m¨
arker ut b¨
orjan p˚
a blocket.
b l o c k b2 : address =0x10000480 , i n s t r u c t i o n _ s e t ="common " , p e r s i s t e n t _ i d =4 , s u r f a c e _ a d d r e s s ="0 x10000480 " { . . . }
Intressant information h¨
ar ¨
ar persistent_id, som anv¨
ands f¨
or att bygga ett
unikt ID f¨
or labeln.
I CRL2 kan basblocken vara av ett antal olika typer. Varje blocktyp har
oli-ka typer av utg˚
aende kanter. De h¨
ar ¨
ar de hanterade blocktyperna och deras
respektive kanttyper:
NORMAL Den enda blocktypen som inneh˚
aller instruktioner. Kan inneh˚
alla
dessa kanter:
TRUE Ovillkorligt hopp som ¨
overs¨
atts till jump om tillh¨
orande FALSE
-kant ej finns, annars villkorligt hopp som ¨
overs¨
atts till en switch
tillsammans med FALSE-kanten.
FALSE Fallthrough till efterf¨
oljande block. Hamnar som falskt villkor i
switchen.
Ovillkorligt hopp:
b l o c k b3 : address =0x100004b8 , i n s t r u c t i o n _ s e t ="common " , p e r s i s t e n t _ i d =0x16 , s u r f a c e _ a d d r e s s ="0 x100004b8 " { edge e81 ( t r u e ) −> b5 : p e r s i s t e n t _ i d =0x17 ; . . . } 1 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 1 6 } { d e c _ u n s i g n e d 32 0 } } /* C R L _ B L O C K _ N O R M A L */ 2 ... 3 { j u m p 4 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 2 1 } { d e c _ u n s i g n e d 32 0 } } l e a v i n g 0 } /* u n c o n d i t i o n a l j u m p */H¨
ar hoppar koden ovillkorligen till block main 21 (b5).
Villkorligt hopp:
b l o c k b2 : address =0x10000480 , i n s t r u c t i o n _ s e t ="common " , p e r s i s t e n t _ i d =4 , s u r f a c e _ a d d r e s s ="0 x10000480 " { edge e51 ( t r u e ) −> b4 : p e r s i s t e n t _ i d = 7 ; edge e50 ( f a l s e , l i n e a r ) −> b3 : p e r s i s t e n t _ i d = 6 ; . . . } 1 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 4 } { d e c _ u n s i g n e d 32 0 } } /* C R L _ B L O C K _ N O R M A L */ 2 ... 3 { s w i t c h /* c o n d i t i o n a l j u m p */ 4 { l o a d 1 { a d d r 32 { f r e f 32 b r a n c h } { d e c _ u n s i g n e d 32 0 } } } 5 { t a r g e t { d e c _ u n s i g n e d 1 0 } { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 1 6 } { d e c _ u n s i g n e d 32 0 } } } 6 { t a r g e t { d e c _ u n s i g n e d 1 1 } { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 1 C } { d e c _ u n s i g n e d 32 0 } } } }
H¨
ar hoppar koden till antingen block main 16 (b3) eller block main 1C (b4)
beroende p˚
a branch.
CALL Anrop g¨
ors i CRL2 om till ett ovillkorligt hopp till ett tomt block som
fungerar som ansats till sj¨
avla anropet. CRL2ALF genskjuter ovillkorliga
hopp till call-block och ¨
overs¨
atter dem direkt till anrop.
CALL Anger anropets destination, som alltid ¨
ar en rutin. ¨
Overs¨
atts till
call.
LOCAL Pekar dit anropsrutinen returnerar. ¨
Overs¨
atts till ett hopp till
det block som motsvarar anropets ˚
aterhoppsadress. L¨
aggs direkt efter
anropet d˚
a SWEET returnerar till n¨
astf¨
oljande instruktion.
b l o c k b3 ( c a l l ) : address =0x10000480 , c a l l _ i n s t r u c t i o n = i 6 2 , p e r s i s t e n t _ i d =6 , s u r f a c e _ a d d r e s s ="0 x10000480 " { edge e52 ( l o c a l , l i n e a r ) −> b4 : p e r s i s t e n t _ i d = 8 ; edge e54 ( c a l l ) −> r 1 : p e r s i s t e n t _ i d =0xa ; }
1 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 6 } { d e c _ u n s i g n e d 32 0 } } /* C R L _ B L O C K _ C A L L */
2 { c a l l { l a b e l 32 { l r e f 32 r o u t i n e _ a s m s t a r t } { d e c _ u n s i g n e d 32 0 } } r e s u l t } /* C R L _ E D G E _ N O R M A L */
H¨
ar anropas rutinen som heter routine asmstart.
RETURN Denoterar ett anrops ˚
aterhoppsadress.
NORMAL Pekar p˚
a blocket med instruktioner som anropet returnerar
till. ¨
Overs¨
atts till jump.
b l o c k b4 ( r e t u r n ) : address =0x10000480 , p e r s i s t e n t _ i d =7 , s u r f a c e _ a d d r e s s ="0 x10000480 " { edge e55 −> b5 : p e r s i s t e n t _ i d =0xb ; }
1 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 7 } { d e c _ u n s i g n e d 32 0 } } /* C R L _ B L O C K _ R E T U R N */
2 { j u m p { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 1 0 } { d e c _ u n s i g n e d 32 0 } } l e a v i n g 0 } /* C R L _ E D G E _ N O R M A L */
H¨
ar hoppas det till blocket block init 10.
START Tomt block som markerar det f¨
orsta blocket i en rutin.
NORMAL Ensam genomfallskant som pekar p˚
a f¨
orsta blocket med
in-struktioner i en rutin. ¨
Overs¨
atts till jump.
b l o c k b0 ( s t a r t ) : p e r s i s t e n t _ i d =2 { edge e49 ( l i n e a r ) −> b2 : p e r s i s t e n t _ i d = 5 ; } 1 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 2 } { d e c _ u n s i g n e d 32 0 } } /* C R L _ B L O C K _ S T A R T */
2 { j u m p { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 4 } { d e c _ u n s i g n e d 32 0 } } l e a v i n g 0 } /* C R L _ E D G E _ N O R M A L */
END Ett tomt block utan n˚
agra utg˚
aende kanter alls. Betecknar slutet p˚
a en
rutin och inneb¨
ar retur till anropare. ¨
Overs¨
atts till return.
b l o c k b1 ( end ) : p e r s i s t e n t _ i d = 3 ;
1 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 3 } { d e c _ u n s i g n e d 32 0 } } /* C R L _ B L O C K _ E N D */ 2 { r e t u r n } /* C R L _ B L O C K _ E N D */
IMPASSE ¨
Annu ett tomt block utan n˚
agra ut˚
atg˚
aende kanter. Inneb¨
ar en
˚
aterv¨
andsgr¨
and; att det inte g˚
ar att forts¨
atta. Ignoreras av ¨
overs¨
attaren.
3.2.4
Instruktioner
D˚
a CRL har st¨
od f¨
or arkitekturer som kan ha flera instruktioner i samma
ma-skinkodsord, s˚
asom VLIW, ¨
ar en instruktion i CRL-filer en beh˚
allare f¨
or en
eller flera operationer. Vad det g¨
aller PowerPC s˚
a finns det dock bara en
ope-ration per instruktion. Ist¨
allet ¨
ar det operationerna som inneh˚
aller det som ska
¨
overs¨
attas till mostsvarande ALF-instruktioner.
i n s t r u c t i o n i 8 4 0x100004a8 : 4 : b y t e s = 4 *[ 0x7c , 0x22 , 0x1a , 0x15 ] , surface_address ="0x100004a8 " { . . . }
H¨
ar kan man f˚
a fram maskinkoden f¨
or instruktionen fr˚
an f¨
altet bytes, men
ingenting av informationen h¨
ar anv¨
ands av ¨
overs¨
attaren.
3.2.5
Operationer
CRL skiljer mellan olika operationer och varianter av operationer genom att ge
dem ett unikt ID. Det finns tv˚
a former av detta, ett i form av ett heltal, op id,
och ett i textuell form, genname. I det h¨
ar projektet har genname valts f¨
or
identifikation av operationer, bland annat f¨
or att det ¨
ar l¨
attare f¨
or m¨
anniskor
att l¨
asa. F¨
orsta steget i att ¨
overs¨
atta operationen till ALF ¨
ar att kontrollera
huruvida det finns n˚
agon post med nyckeln genname i den map som inneh˚
aller
datat fr˚
an ¨
overs¨
attningsfilerna. Finns den ej ¨
ar operationen ej implementerad. I
s˚
adant fall s¨
atts varningsflaggan och det skrivs ut en varning i en kommentar om
att operationer ej ¨
ar implementerad. Om den i st¨
allet fanns indexeras map:en
med genname och resultatet k¨
ors genom ¨
overs¨
attningsmotorn.
o p e r a t i o n o85 " add . r1 , r2 , r 3 " : arch = ’ UISA ’ , assembly =" add . $ , $ , $ " , c a t = { } , d s t = 4 *[ ’ r1 ’ , 3= ’ cr0 ’ ] , form = ’XO’ , genname = ’ addD ’ , op_ id =0xf7c000215 , optype = 3 *[ ’ GPRegAll ’ , ’ GPRegAll ’ , ’ GPRegAll ’ ] , p e r s i s t e n t _ i d =0x1e , s r c = 3 *[ 1= ’ r2 ’ , ’ r3 ’ ] ;
¨
Overs¨
attaren skriver ut instruktionen i assemblerform fr˚
an mnemonic (f¨
altet efter
o85 inom citationstecken) och genname f¨
or instruktionen i en kommentar f¨
ore
kodkroppen f¨
or att man ska kunna se vad som har blivit ¨
oversatt. I ¨
ovrigt
anv¨
ands bara dst och src.
Kapitel 4
¨
Overs¨
attningsmotor
Motorn ¨
ar skriven f¨
or att l¨
agga s˚
a mycket som m¨
ojligt av funktionaliteten i
data ist¨
allet f¨
or kod, med s˚
a lite specialfall som m¨
ojligt. Den utf¨
or inte n˚
agon
behandling av de v¨
arden den f˚
ar ur crl-filen fr˚
an libcrl2, utan vidarebefordrar de
som de ¨
ar. Detta medf¨
or att en del ber¨
akningar som skulle kunna utf¨
oras under
¨
overs¨
attningen nu m˚
aste g¨
oras under k¨
orning av m˚
alprogrammet. ¨
Overs¨
attning
av instruktioner innefattar fem steg:
4.1
Map
¨
Overs¨
attningen startar med att semantiken f¨
or instruktionen h¨
amtas ur
databas-map:en.
4.2
Pre-preprocessing
Det pre-preprocessningen g¨
or ¨
ar att byta ut vissa f¨
alt utmarkerade med
vinkel-parenteser mot operandv¨
arden fr˚
an CRL, f¨
ore preprocessning. Detta steg
visa-de sig n¨
odv¨
andigt f¨
or att ¨
overs¨
atta branches och de instruktioner som hanterar
multipla data: load/store multiple word och load/store string word.
Exempel (bclr Cond.txt ):
1 [ bo_ < bo >]
blir utbytt till f¨
orsta k¨
alloperanden fr˚
an CRL:
1 [ b o _ 1 2 ]
4.3
Preprocessing
Preprocessorn byter ut alla instanser av str¨
angar inneslutna i hakparenteser
med inneh˚
allet i map:en indexerat med inneh˚
allet i parenteserna. Med andra
ord fungerar hakparenteser som ett include-direktiv.
Exempel (adde.txt ):
1 ...
2 [ carry - a d d e ]
[carry-adde] byts ut till inneh˚
allet i maps[“carry-adde”] :
1 ... 2 ({ a d d r 32 { f r e f 32 x e r _ c a } { d e c _ u n s i g n e d 32 0 } } /* a d d m e c a r r y */) 3 ({ c _ a d d 32 4 { l o a d 32 { a d d r 32 { f r e f 32 < src1 > } { d e c _ u n s i g n e d 32 0 } } } 5 { l o a d 32 { a d d r 32 { f r e f 32 < src2 > } { d e c _ u n s i g n e d 32 0 } } } 6 { l o a d 1 { a d d r 32 { f r e f 32 x e r _ c a } { d e c _ u n s i g n e d 32 0 } } } })
H¨
ar har semantiken f˚
ar carryflaggan i sammanhang med instruktionen adde
inkluderats.
4.4
Processing
Innan det h¨
ar steget har man en textstr¨
ang som kan inneh˚
alla tv˚
a saker: par
av str¨
angar inneslutna i vanliga parenteser och str¨
angar inneslutna mellan
lod-streck, “|”.
1 ({ a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } /* < dst > < - ! < src1 > */) 2 ({ neg 32 3 { l o a d 32 { a d d r 32 { f r e f 32 < src1 > } { d e c _ u n s i g n e d 32 0 } } } }) 4 ({ a d d r 32 { f r e f 32 x e r _ o v } { d e c _ u n s i g n e d 32 0 } } /* neg o v e r f l o w */) 5 ({ eq 32 6 { l o a d 32 { a d d r 32 { f r e f 32 < src1 > } { d e c _ u n s i g n e d 32 0 } } } 7 { h e x _ v a l 32 8 0 0 0 0 0 0 0 } }) 8 |{ s t o r e 9 { a d d r 32 { f r e f 32 x e r _ s o } { d e c _ u n s i g n e d 32 0 } } /* s u m m a r y o v e r f l o w */ 10 w i t h 11 { or 1 12 { l o a d 1 { a d d r 32 { f r e f 32 x e r _ o v } { d e c _ u n s i g n e d 32 0 } } } 13 { l o a d 1 { a d d r 32 { f r e f 32 x e r _ s o } { d e c _ u n s i g n e d 32 0 } } } } } 14 |De parentesinneslutna str¨
angarna best˚
ar av adress/data-par som s¨
atts in i en
gemensam parallell store-instruktion. Parallell store anv¨
ands f¨
or att slippa
skapa tempor¨
ara variabler i de fall som en operation skulle skriva ¨
over en annan
operations inv¨
arde. Avsnitt mellan lodstreck (rad 8-14) ¨
ar sekventiella
instruk-tioner som placeras som de ¨
ar en efter en direkt efter den parallella store:n.
1 { s t o r e 2 { a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } /* < dst > < - ! < src1 > */ 3 { a d d r 32 { f r e f 32 x e r _ o v } { d e c _ u n s i g n e d 32 0 } } /* neg o v e r f l o w */ 4 w i t h 5 { neg 32 6 { l o a d 32 { a d d r 32 { f r e f 32 < src1 > } { d e c _ u n s i g n e d 32 0 } } } } 7 { eq 32 8 { l o a d 32 { a d d r 32 { f r e f 32 < src1 > } { d e c _ u n s i g n e d 32 0 } } } 9 { h e x _ v a l 32 8 0 0 0 0 0 0 0 } } 10 { s t o r e
11 { a d d r 32 { f r e f 32 x e r _ s o } { d e c _ u n s i g n e d 32 0 } } /* s u m m a r y o v e r f l o w */ 12 w i t h 13 { or 1 14 { l o a d 1 { a d d r 32 { f r e f 32 x e r _ o v } { d e c _ u n s i g n e d 32 0 } } } 15 { l o a d 1 { a d d r 32 { f r e f 32 x e r _ s o } { d e c _ u n s i g n e d 32 0 } } } } }
4.5
Postprocessing
Efter processing-steget har man f˚
att koden f¨
or operationen i ALF-form. Det
sista steget fyller i operander och adresser fr˚
an CRL-filen d¨
ar det finns
vinkel-parentesmarkerade platsh˚
allare.
1 { s t o r e 2 { a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } /* < dst > < - < src1 > | < src2 > */ 3 w i t h 4 { or 32 5 { l o a d 32 { a d d r 32 { f r e f 32 < src1 > } { d e c _ u n s i g n e d 32 0 } } } 6 { l o a d 32 { a d d r 32 { f r e f 32 < src2 > } { d e c _ u n s i g n e d 32 0 } } } } }
H¨
ar byts <dst> och <srcn> ut mot respektive destinations- respektive k¨
allo-perander.
1 { s t o r e 2 { a d d r 32 { f r e f 32 r31 } { d e c _ u n s i g n e d 32 0 } } /* r31 < - r1 | r1 */ 3 w i t h 4 { or 32 5 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } 6 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } } }Nu ¨
ar koden f¨
or instruktionen f¨
ardigbehandlad och den skrivs ut.
4.6
K¨
ormilj¨
o
Det var f¨
orst tanken att minnesstrukturen fr˚
an den exekverbara filen skulle
be-h˚
allas i ALF-¨
overs¨
attningen; att allokera hela adressrymden och bevara adresser
som de var. Men d˚
a nuvarande SWEET visade sig ha problem med att
alloke-ra st¨
orre m¨
angder minne best¨
amdes att adressrymden - och det minne som
beh¨
ovde allokeras - skulle minimeras. F¨
or att g¨
ora det r¨
aknar CRL2ALF ut
adressrymdens omfattning och relokerar den till adress noll. Detta inneb¨
ar dock
att alla adresser m˚
aste justeras lika mycket. Det ¨
ar f¨
or n¨
arvarande l¨
ost genom
att under k¨
orning justera den effektiva adressen p˚
a varenda minnesaccess. M¨
oj-ligen skulle det kunna g˚
a att l¨
osa p˚
a ett b¨
attre s¨
att genom att anv¨
anda eventuell
relokeringsinformation.
Stacken har satts som en en del av RAM-minnet.
Oinitialiserade minnesadresser markeras som att ha top value, vilket betyder att
v¨
ardet ¨
ar ok¨
ant.
4.7
Exempel
4.7.1
add. r1, r2, r3
Add-instruktionen summerar tv˚
a register (source) och l¨
agger resultatet i ett
tredje (destination). I PowerPC-assembler skrivs destinationen f¨
orst, s˚
a r1 ¨
ar
v˚
ar destination och r2 och r3 ¨
ar v˚
ara source. Vanligtvis ¨
andrar inte instruktioner
p˚
a flaggorna i statusregistret, men denna variant av instruktionen har en punkt
efter namnet vilket betyder att den ¨
andrar p˚
a f¨
alt cr0 i statusregistret. I CRL
byts punkterna ut mot “D” ist¨
allet. Den information vi beh¨
over f¨
orst fr˚
an CRL
¨
ar genname:
o p e r a t i o n o85 " add . r1 , r2 , r 3 " : . . . genname = ’ addD ’ . . .
Genname sl˚
as upp i maps:
i=maps . f i n d ( key ) ; v a l u e=i −>s e c o n d ;
I value ligger semantiken f¨
or v˚
ar operation AddD :
1 [ add ] 2 [ cr0 ]
[add] inkluderar semantiken fr˚
an operationen som heter add, v˚
ar instruktion i
grundutf¨
orande. [cr0] inkluderar semantik som s¨
atter flaggorna i
statusregist-rets f¨
alt 0, cr0. Efter preprocessningen har hakparentesdirektiven bytts ut mot
sina respektive inneh˚
all:
1 ({ a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } /* < dst > < - < src1 > + < src2 > */) 2 ({ add 32 3 { l o a d 32 { a d d r 32 { f r e f 32 < src1 > } { d e c _ u n s i g n e d 32 0 } } } 4 { l o a d 32 { a d d r 32 { f r e f 32 < src2 > } { d e c _ u n s i g n e d 32 0 } } } 5 { d e c _ u n s i g n e d 1 0 } }) 6 |{ s t o r e /* cr0 */ 7 { a d d r 32 { f r e f 32 c r 0 _ l t } { d e c _ u n s i g n e d 32 0 } } /* lt */ 8 { a d d r 32 { f r e f 32 c r 0 _ g t } { d e c _ u n s i g n e d 32 0 } } /* gt */ 9 { a d d r 32 { f r e f 32 c r 0 _ e q } { d e c _ u n s i g n e d 32 0 } } /* eq */ 10 { a d d r 32 { f r e f 32 c r 0 _ s o } { d e c _ u n s i g n e d 32 0 } } /* cr0 s u m m a r y o v e r f l o w */ 11 w i t h 12 { s _ l t 32 13 { l o a d 32 { a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } } 14 { d e c _ s i g n e d 32 0 } } 15 { s _ g t 32 16 { l o a d 32 { a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } } 17 { d e c _ s i g n e d 32 0 } } 18 { eq 32 19 { l o a d 32 { a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } } 20 { d e c _ u n s i g n e d 32 0 } } 21 { l o a d 1 { a d d r 32 { f r e f 32 x e r _ s o } { d e c _ u n s i g n e d 32 0 } } } } 22 |
De fem f¨
orsta raderna motsvarar add. Det best˚
ar av ett store-operationspar d¨
ar
destinationen finns inom de f¨
orsta parenteserna och k¨
allan inom de andra. De
kommer att s¨
attas ihop till en store-instruktion. Hade det funnits flera andra
store-operationspar hade de hamnat i samma, parallella, store.
Raderna 7-22 har hand om uppdateringen av statusregistret. Det ¨
ar inneslutet
mellan lodstreck och kommer att l¨
aggas som det ¨
ar efter store-satsen.
An-ledningen till att uppdateringen av statusregistret ligger i sin egen store p˚
a
slutet ¨
ar att flaggorna s¨
atts enligt resultatet fr˚
an instruktionen, s˚
a resultatet
m˚
aste r¨
aknas ut f¨
orst. I det h¨
ar exemplet r¨
aknas tre av flaggorna ut - lt, gt och
eq
1- utifr˚
an resultatet av instruktionen som ligger i register <dst>. Den fj¨
arde
flaggan, so
2, kopieras fr˚
an xer.
Efter processningssteget har vi en f¨
ardig mall f¨
or operationen:
1 { s t o r e 2 { a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } /* < dst > < - < src1 > + < src2 > */ 3 w i t h 4 { add 32 5 { l o a d 32 { a d d r 32 { f r e f 32 < src1 > } { d e c _ u n s i g n e d 32 0 } } } 6 { l o a d 32 { a d d r 32 { f r e f 32 < src2 > } { d e c _ u n s i g n e d 32 0 } } } 7 { d e c _ u n s i g n e d 1 0 } } } 8 { s t o r e /* cr0 */ 9 { a d d r 32 { f r e f 32 c r 0 _ l t } { d e c _ u n s i g n e d 32 0 } } /* lt */ 10 { a d d r 32 { f r e f 32 c r 0 _ g t } { d e c _ u n s i g n e d 32 0 } } /* gt */ 11 { a d d r 32 { f r e f 32 c r 0 _ e q } { d e c _ u n s i g n e d 32 0 } } /* eq */ 12 { a d d r 32 { f r e f 32 c r 0 _ s o } { d e c _ u n s i g n e d 32 0 } } /* cr0 s u m m a r y o v e r f l o w */ 13 w i t h 14 { s _ l t 32 15 { l o a d 32 { a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } } 16 { d e c _ s i g n e d 32 0 } } 17 { s _ g t 32 18 { l o a d 32 { a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } } 19 { d e c _ s i g n e d 32 0 } } 20 { eq 32 21 { l o a d 32 { a d d r 32 { f r e f 32 < dst > } { d e c _ u n s i g n e d 32 0 } } } 22 { d e c _ u n s i g n e d 32 0 } } 23 { l o a d 1 { a d d r 32 { f r e f 32 x e r _ s o } { d e c _ u n s i g n e d 32 0 } } } }
Det som ˚
aterst˚
ar ¨
ar att s¨
atta in de aktuella operanderna fr˚
an CRL:
o p e r a t i o n o85 " add . r1 , r2 , r 3 " : . . . d s t = 4 *[ ’ r1 ’ , 3= ’ cr0 ’ ] , . . . src =3*[ 1= ’ r2 ’ , ’ r3 ’ ] ;
Operanderna ˚
aterfinns i vektorerna dst och src. <dst> ¨
ar alltid den f¨
orsta
des-tinationsoperanden, <src1> och <src2> betecknar f¨
orsta respektive andra k¨
al-loperanden. Efter ers¨
attningarna ¨
ar ¨
overs¨
attningen av instruktionen f¨
ardig och
resultatet skrivs ut:
1 { s t o r e 2 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } /* r1 < - r2 + r3 */ 3 w i t h 4 { add 32 5 { l o a d 32 { a d d r 32 { f r e f 32 r2 } { d e c _ u n s i g n e d 32 0 } } } 6 { l o a d 32 { a d d r 32 { f r e f 32 r3 } { d e c _ u n s i g n e d 32 0 } } } 7 { d e c _ u n s i g n e d 1 0 } } } 8 { s t o r e /* cr0 */ 9 { a d d r 32 { f r e f 32 c r 0 _ l t } { d e c _ u n s i g n e d 32 0 } } /* lt */ 10 { a d d r 32 { f r e f 32 c r 0 _ g t } { d e c _ u n s i g n e d 32 0 } } /* gt */ 11 { a d d r 32 { f r e f 32 c r 0 _ e q } { d e c _ u n s i g n e d 32 0 } } /* eq */ 12 { a d d r 32 { f r e f 32 c r 0 _ s o } { d e c _ u n s i g n e d 32 0 } } /* cr0 s u m m a r y o v e r f l o w */ 13 w i t h 14 { s _ l t 32 15 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } 16 { d e c _ s i g n e d 32 0 } } 17 { s _ g t 32 18 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } 19 { d e c _ s i g n e d 32 0 } } 20 { eq 32 21 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } 22 { d e c _ u n s i g n e d 32 0 } } 23 { l o a d 1 { a d d r 32 { f r e f 32 x e r _ s o } { d e c _ u n s i g n e d 32 0 } } } }
1less than, greater than, equal - mindre ¨an, greater than, equal 2summary overflow - sticky overflow-flagga
4.7.2
bt cr7.gt, 0x100004c8.f
bt
¨
ar en pseudoinstruktion
3som utl¨
ases branch true. Det ¨
ar en f¨
orenkling av att
skriva bc 12, d¨
ar bc betyder branch conditional och 12 ¨
ar en flagga som betyder
just branch true. cr7.gt ¨
ar det villkor som ska vara sant; bit gt i
statusregist-rets f¨
alt cr7, som antagligen satts av en tidigare cmp-instruktion. 0x100004c8
¨
ar adressen att hoppa till om villkoret ¨
ar sant och f ¨
ar branch
prediction-information till processorns Branch Processing Unit att den ska anta att hoppet
inte tas. Denna informationen ignoreras av CRL2ALF.
Relevant information fr˚
an CRL:
o p e r a t i o n o79 " b t c r 7 . gt , 0x100004c8 . f <0x100004c8 > " : . . . genname = ’ bc_Cond ’ . . . s r c = 5 *[ 0xc , ’ cr7 ’ , ’ gt ’ , 0x100004c8 , ’ f ’ ] . . .
D¨
ar kan man se att CRL:s namn p˚
a just denna typ av branch ¨
ar bc Cond. Ur
maps f˚
as:
1 [ bo_ < bo >]
F¨
orsta elementet i src i CRL2 ¨
ar BO -f¨
altet i instruktionen som betecknar
hopp-villkoret. I v˚
art fall har vi 0xc = 12, som betyder branch true. Denna siffra
pre-preprocessas in till:
1 [ b o _ 1 2 ]
Preprocessorn h¨
amtar d˚
a fr˚
an bo 12, som inneh˚
aller semantiken f¨
or
hoppa-om-sant :
1 ({ a d d r 32 { f r e f 32 b r a n c h } { d e c _ u n s i g n e d 32 0 } } /* b r a n c h < - c o n d i t i o n */) 2 ({ l o a d 1 { a d d r 32 { f r e f 32 < src2 > _ < src3 > } { d e c _ u n s i g n e d 32 0 } } })
Som i sin tur processas in i en store:
1 { s t o r e
2 { a d d r 32 { f r e f 32 b r a n c h } { d e c _ u n s i g n e d 32 0 } } /* b r a n c h < - c o n d i t i o n */ 3 w i t h
4 { l o a d 1 { a d d r 32 { f r e f 32 < src2 > _ < src3 > } { d e c _ u n s i g n e d 32 0 } } } }
H¨
ar s¨
atts en intern flagga kallad branch, som h˚
aller reda p˚
a huruvida vi ska
hoppa eller ej. V¨
ardet tas fr˚
an en frame i ALF som motsvarar den testade
flaggan. Den aktuella flaggan substitueras in i postprocess-steget:
1 { s t o r e
2 { a d d r 32 { f r e f 32 b r a n c h } { d e c _ u n s i g n e d 32 0 } } /* b r a n c h < - c o n d i t i o n */ 3 w i t h
4 { l o a d 1 { a d d r 32 { f r e f 32 c r 7 _ g t } { d e c _ u n s i g n e d 32 0 } } } }
Sj¨
alva hoppet utf¨
ors av kod som genereras f¨
or den aktuella blocktypen, i det h¨
ar
fallet ett block av typen NORMAL. Om det b˚
ade finns en kant f¨
or TRUE och
en f¨
or FALSE ¨
overs¨
atts slutet av blocket till en switch-sats fr˚
an en prototyp
som kallas conditional jump, som hoppar utifr˚
an branch-flaggan:
3En instruktion som inte egentligen finns i arkitekturen, fast erbjuds av assemblatorn f¨or
1 { s w i t c h /* c o n d i t i o n a l j u m p */
2 { l o a d 1 { a d d r 32 { f r e f 32 b r a n c h } { d e c _ u n s i g n e d 32 0 } } }
3 { t a r g e t { d e c _ u n s i g n e d 1 0 } { l a b e l 32 { l r e f 32 < e d g e _ f a l s e > } { d e c _ u n s i g n e d 32 0 } } } 4 { t a r g e t { d e c _ u n s i g n e d 1 1 } { l a b e l 32 { l r e f 32 < e d g e _ t r u e > } { d e c _ u n s i g n e d 32 0 } } } }
Destinationerna byts ut till de basblock som kanterna pekar p˚
a i CRL och skrivs
ut:
edge e51 ( t r u e ) −> b4 : p e r s i s t e n t _ i d = 7 ; edge e50 ( f a l s e , l i n e a r ) −> b3 : p e r s i s t e n t _ i d = 6 ; 1 { s w i t c h /* c o n d i t i o n a l j u m p */ 2 { l o a d 1 { a d d r 32 { f r e f 32 b r a n c h } { d e c _ u n s i g n e d 32 0 } } } 3 { t a r g e t { d e c _ u n s i g n e d 1 0 } { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 1 6 } { d e c _ u n s i g n e d 32 0 } } } 4 { t a r g e t { d e c _ u n s i g n e d 1 1 } { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 1 C } { d e c _ u n s i g n e d 32 0 } } } }4.7.3
En hel rutin
Vi utg˚
ar fr˚
an ett C-program som kompileras med GCC:
1 int m a i n ( v o i d ) 2 { 3 int a , b , c ; 4 a = 1 0 ; 5 b = 2 0 ; 6 c = a + b ; 7 if ( c < 2 5 ) 8 r e t u r n ( b - a ); 9 e l s e 10 r e t u r n ( a - b ); 11 }
H¨
ar har analysen identifierat de tv˚
a programv¨
agarna som if :en representerar.
Kontrollfl¨
odesgrafen f¨
or rutinen “main” i CRL2-format:
r o u t i n e r 0 : address =0x10000480 , i n s t r u c t i o n _ s e t ="common " , l o o p _ s c c = 0 * [ ] , name=" main " , p e r s i s t e n t _ i d =1 , s e c t i o n = " . t e x t " , s u r f a c e _ a d d r e s s ="0 x10000480 " { b l o c k b0 ( s t a r t ) : p e r s i s t e n t _ i d =2 { edge e49 ( l i n e a r ) −> b2 : p e r s i s t e n t _ i d = 5 ; } b l o c k b1 ( end ) : p e r s i s t e n t _ i d = 3 ; b l o c k b2 : address =0x10000480 , i n s t r u c t i o n _ s e t ="common " , p e r s i s t e n t _ i d =4 , s u r f a c e _ a d d r e s s ="0 x10000480 " { edge e51 ( t r u e ) −> b4 : p e r s i s t e n t _ i d = 7 ; edge e50 ( f a l s e , l i n e a r ) −> b3 : p e r s i s t e n t _ i d = 6 ; i n s t r u c t i o n i 5 2 0x10000480 : 4 : b y t e s = 4 *[ 0x94 , 0x21 , 0 x f f , 0xe0 ] , surface_address ="0 x10000480 " {
o p e r a t i o n o53 " stwu r1 , −32( r 1 ) " : arch = ’ UISA ’ , assembly =" stwu $ , $ ( $ ) " , c a t = { mem_write =1 } , d s t = 4 *[ 2= ’ r1 ’ , ’Mem’ ] , form = ’D’ , genname= ’ stwu ’ , op_id=0x794000000 , optype = 3 *[ ’ GPRegAll ’ , ’ signed ’ , ’GPRegBase ’ ] , p e r s i s t e n t _ i d =8 , src =3*[ ’ r1 ’ , −32, ’ r1 ’ ] ;
}
i n s t r u c t i o n i 5 4 0x10000484 : 4 : b y t e s = 4 *[ 0x93 , 0xe1 , 0x00 , 0x1c ] , surface_address ="0 x10000484 " {
o p e r a t i o n o55 " stw r31 , +28( r 1 ) " : arch = ’ UISA ’ , assembly =" stw $ , $ ( $ ) " , c a t = { mem_write =1 } , d s t = 4 *[ 3= ’Mem’ ] , form = ’D’ , genname= ’ stw ’ , op_id=0x790000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =9 , s r c = 3 *[ ’ r31 ’ , +28 , ’ r1 ’ ] ; }
i n s t r u c t i o n i 5 6 0x10000488 : 4 : b y t e s = 4 *[ 0x7c , 0x3f , 0x0b , 0x78 ] , surface_address ="0 x10000488 " {
o p e r a t i o n o57 " mr r31 , r 1 " : arch = ’ UISA ’ , assembly =" o r $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ r31 ’ ] , form = ’X ’ , genname = ’ or ’ , op_ id =0xf7c000378 , optype = 3 *[ ’ GPRegAll ’ , ’ GPRegAll ’ , ’ GPRegAll ’ ] , p e r s i s t e n t _ i d =0xa , s r c = 3 *[ 1= ’ r1 ’ , ’ r1 ’ ] ;
}
i n s t r u c t i o n i 5 8 0x1000048c : 4 : b y t e s = 4 *[ 0x38 , 0x00 , 0x00 , 0x0a ] , surface_address ="0 x1000048c " {
o p e r a t i o n o59 " l i r0 , + 1 0 " : arch = ’ UISA ’ , assembly =" a d d i $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ r0 ’ ] , form = ’D ’ , genname = ’ addi ’ , op_ id =0x738000000 , optype = 3 *[ ’ GPRegAll ’ , ’ GPRegZero ’ , ’ signed ’ ] , p e r s i s t e n t _ i d =0xb , s r c = 3 *[ 1= ’ zero ’ , +10 ] ;
}
i n s t r u c t i o n i 6 0 0x10000490 : 4 : b y t e s = 4 *[ 0x90 , 0x1f , 0x00 , 0x08 ] , surface_address ="0 x10000490 " {
o p e r a t i o n o61 " stw r0 , +8( r31 ) " : arch = ’ UISA ’ , assembly =" stw $ , $ ( $ ) " , c a t = { mem_write=1 } , d s t = 4 *[ 3= ’Mem’ ] , form = ’D’ , genname= ’ stw ’ , op_id=0x790000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0xc , s r c = 3 *[ ’ r0 ’ , +8 , ’ r31 ’ ] ; }
i n s t r u c t i o n i 6 2 0x10000494 : 4 : b y t e s = 4 *[ 0x38 , 0x00 , 0x00 , 0x14 ] , surface_address ="0 x10000494 " {
o p e r a t i o n o63 " l i r0 , + 2 0 " : arch = ’ UISA ’ , assembly =" a d d i $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ r0 ’ ] , form = ’D ’ , genname = ’ addi ’ , op_ id =0x738000000 , optype = 3 *[ ’ GPRegAll ’ , ’ GPRegZero ’ , ’ signed ’ ] , p e r s i s t e n t _ i d =0xd , s r c = 3 *[ 1= ’ zero ’ , +20 ] ;
}
i n s t r u c t i o n i 6 4 0x10000498 : 4 : b y t e s = 4 *[ 0x90 , 0x1f , 0x00 , 0x0c ] , surface_address ="0 x10000498 " {
o p e r a t i o n o65 " stw r0 , +12( r31 ) " : arch = ’ UISA ’ , assembly =" stw $ , $ ( $ ) " , c a t = { mem_write =1 } , d s t = 4 *[ 3= ’Mem’ ] , form = ’D’ , genname= ’ stw ’ , op_id=0x790000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0xe , s r c = 3 *[ ’ r0 ’ , +12 , ’ r31 ’ ] ; }
i n s t r u c t i o n i 6 6 0x1000049c : 4 : b y t e s = 4 *[ 0x81 , 0x3f , 0x00 , 0x08 ] , surface_address ="0 x1000049c " {
o p e r a t i o n o67 " lwz r9 , +8( r31 ) " : arch = ’ UISA ’ , assembly =" lwz $ , $ ( $ ) " , c a t = { mem_read=1 } , d s t = 1 *[ ’ r9 ’ ] , form = ’D’ , genname= ’ lwz ’ , op_id=0x780000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0 x f , s r c = 4 *[ 1=+8 , ’ r31 ’ , ’Mem’
] ; }
i n s t r u c t i o n i 6 8 0x100004a0 : 4 : b y t e s = 4 *[ 0x80 , 0x1f , 0x00 , 0x0c ] , surface_address ="0 x100004a0 " {
o p e r a t i o n o69 " lwz r0 , +12( r31 ) " : arch = ’ UISA ’ , assembly =" lwz $ , $ ( $ ) " , c a t = { mem_read=1 } , d s t = 1 *[ ’ r0 ’ ] , form = ’D’ , genname= ’ lwz ’ , op_id=0x780000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0x10 , s r c = 4 *[ 1=+12, ’ r31 ’ , ’Mem ’ ] ;
}
i n s t r u c t i o n i 7 0 0x100004a4 : 4 : b y t e s = 4 *[ 0x7c , 0x09 , 0x02 , 0x14 ] , surface_address ="0 x100004a4 " {
o p e r a t i o n o71 " add r0 , r9 , r 0 " : arch = ’ UISA ’ , assembly =" add $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ r0 ’ ] , form = ’XO’ , genname = ’ add ’ , op _id =0xf7c000214 , optype = 3 *[ ’ GPRegAll ’ , ’
GPRegAll ’ , ’ GPRegAll ’ ] , p e r s i s t e n t _ i d =0x11 , s r c = 3 *[ 1= ’ r9 ’ , ’ r0 ’ ] ; }
i n s t r u c t i o n i 7 2 0x100004a8 : 4 : b y t e s = 4 *[ 0x90 , 0x1f , 0x00 , 0x10 ] , surface_address ="0 x100004a8 " {
o p e r a t i o n o73 " stw r0 , +16( r31 ) " : arch = ’ UISA ’ , assembly =" stw $ , $ ( $ ) " , c a t = { mem_write =1 } , d s t = 4 *[ 3= ’Mem’ ] , form = ’D’ , genname= ’ stw ’ , op_id=0x790000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0x12 , s r c = 3 *[ ’ r0 ’ , +16 , ’ r31 ’
] ; }
i n s t r u c t i o n i 7 4 0x100004ac : 4 : b y t e s = 4 *[ 0x80 , 0x1f , 0x00 , 0x10 ] , surface_address ="0 x100004ac " {
o p e r a t i o n o75 " lwz r0 , +16( r31 ) " : arch = ’ UISA ’ , assembly =" lwz $ , $ ( $ ) " , c a t = { mem_read=1 } , d s t = 1 *[ ’ r0 ’ ] , form = ’D’ , genname= ’ lwz ’ , op_id=0x780000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0x13 , s r c = 4 *[ 1=+16, ’ r31 ’ , ’Mem ’ ] ;
}
i n s t r u c t i o n i 7 6 0x100004b0 : 4 : b y t e s = 4 *[ 0x2f , 0x80 , 0x00 , 0x18 ] , surface_address ="0 x100004b0 " {
o p e r a t i o n o77 " cmpi cr7 , 0 , r0 , + 2 4 " : arch = ’ UISA ’ , assembly =" cmpi $ , $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ cr7 ’ ] , form = ’D’ , genname= ’ cmpi ’ , op_id=0x72c000000 , optype =4*[ ’CondReg ’ , ’ unsigned ’ , ’ GPRegAll ’ , ’ signed ’ ] , p e r s i s t e n t _ i d =0x14 , s r c = 4 *[ 1=0 , ’ r0 ’ , +24 ] ;
}
i n s t r u c t i o n i 7 8 0x100004b4 : 4 : b y t e s = 4 *[ 0x41 , 0x9d , 0x00 , 0x14 ] , surface_address ="0 x100004b4 " {
o p e r a t i o n o79 " b t c r 7 . gt , 0x100004c8 . f <0x100004c8 > " : arch = ’ UISA ’ , assembly =" bc $ , $ . $ , $ . $ " , c a t = { branch =1 , tak en =1 } , computed =0 , c o n d i t i o n a l =1 , form = ’B ’ , genname = ’ bc_Cond ’ , o p_i d =0x740800000 , optype = 5 *[ ’ unsigned ’ , ’CondReg ’ , ’ CondBit ’ , ’ address ’ , ’ B r a n c h P r e d i c t i o n ’ ] , p e r s i s t e n t _ i d =0x15 , s r c = 5 *[ 0xc , ’ cr7 ’ , ’ gt ’ , 0x100004c8 , ’ f ’ ] , t y p e = ’ branch ’ ; } } b l o c k b3 : address =0x100004b8 , i n s t r u c t i o n _ s e t ="common " , p e r s i s t e n t _ i d =0x16 , s u r f a c e _ a d d r e s s ="0 x100004b8 " { edge e81 ( t r u e ) −> b5 : p e r s i s t e n t _ i d =0x17 ; i n s t r u c t i o n i 8 2 0x100004b8 : 4 : b y t e s = 4 *[ 0x81 , 0x3f , 0x00 , 0x0c ] , surface_address ="0 x100004b8 " {
o p e r a t i o n o83 " lwz r9 , +12( r31 ) " : arch = ’ UISA ’ , assembly =" lwz $ , $ ( $ ) " , c a t = { mem_read=1 } , d s t = 1 *[ ’ r9 ’ ] , form = ’D’ , genname= ’ lwz ’ , op_id=0x780000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0x18 , s r c = 4 *[ 1=+12, ’ r31 ’ , ’Mem ’ ] ;
}
i n s t r u c t i o n i 8 4 0x100004bc : 4 : b y t e s = 4 *[ 0x80 , 0x1f , 0x00 , 0x08 ] , surface_address ="0 x100004bc " {
o p e r a t i o n o85 " lwz r0 , +8( r31 ) " : arch = ’ UISA ’ , assembly =" lwz $ , $ ( $ ) " , c a t = { mem_read=1 } , d s t = 1 *[ ’ r0 ’ ] , form = ’D’ , genname= ’ lwz ’ , op_id=0x780000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0x19 , s r c = 4 *[ 1=+8 , ’ r31 ’ , ’Mem’
] ; }
i n s t r u c t i o n i 8 6 0x100004c0 : 4 : b y t e s = 4 *[ 0x7c , 0x00 , 0x48 , 0x50 ] , surface_address ="0 x100004c0 " {
o p e r a t i o n o87 " s u b f r0 , r0 , r 9 " : arch = ’ UISA ’ , assembly =" s u b f $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ r0 ’ ] , form = ’XO’ , genname = ’ subf ’ , op_ id =0xf7c000050 , optype = 3 *[ ’ GPRegAll ’ , ’ GPRegAll ’ , ’ GPRegAll ’ ] , p e r s i s t e n t _ i d =0x1a , s r c = 3 *[ 1= ’ r0 ’ , ’ r9 ’ ] ;
}
i n s t r u c t i o n i 8 8 0x100004c4 : 4 : b y t e s = 4 *[ 0x48 , 0x00 , 0x00 , 0x10 ] , surface_address ="0 x100004c4 " {
o p e r a t i o n o89 " b 0x100004d4 <0x100004d4 > " : arch = ’ UISA ’ , assembly =" b $ " , c a t = { branch =1 , ta ken =1 } , computed =0 , c o n d i t i o n a l =0 , form = ’ I ’ , genname = ’ b ’ , op_ id =0x748000000 , optype = 1 *[ ’ address ’ ] , p e r s i s t e n t _ i d =0x1b , src =1*[ 0x100004d4 ] , type = ’ branch ’ ; } } b l o c k b4 : address =0x100004c8 , i n s t r u c t i o n _ s e t ="common " , p e r s i s t e n t _ i d =0x1c , s u r f a c e _ a d d r e s s ="0 x100004c8 " { edge e91 −> b5 : p e r s i s t e n t _ i d =0x1d ; i n s t r u c t i o n i 9 2 0x100004c8 : 4 : b y t e s = 4 *[ 0x81 , 0x3f , 0x00 , 0x08 ] , surface_address ="0 x100004c8 " {
o p e r a t i o n o93 " lwz r9 , +8( r31 ) " : arch = ’ UISA ’ , assembly =" lwz $ , $ ( $ ) " , c a t = { mem_read=1 } , d s t = 1 *[ ’ r9 ’ ] , form = ’D’ , genname= ’ lwz ’ , op_id=0x780000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0x1e , s r c = 4 *[ 1=+8 , ’ r31 ’ , ’Mem’
] ; }
i n s t r u c t i o n i 9 4 0x100004cc : 4 : b y t e s = 4 *[ 0x80 , 0x1f , 0x00 , 0x0c ] , surface_address ="0 x100004cc " {
o p e r a t i o n o95 " lwz r0 , +12( r31 ) " : arch = ’ UISA ’ , assembly =" lwz $ , $ ( $ ) " , c a t = { mem_read=1 } , d s t = 1 *[ ’ r0 ’ ] , form = ’D’ , genname= ’ lwz ’ , op_id=0x780000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0 x 1 f , s r c = 4 *[ 1=+12, ’ r31 ’ , ’Mem ’ ] ;
}
i n s t r u c t i o n i 9 6 0x100004d0 : 4 : b y t e s = 4 *[ 0x7c , 0x00 , 0x48 , 0x50 ] , surface_address ="0 x100004d0 " {
o p e r a t i o n o97 " s u b f r0 , r0 , r 9 " : arch = ’ UISA ’ , assembly =" s u b f $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ r0 ’ ] , form = ’XO’ , genname = ’ subf ’ , op_ id =0xf7c000050 , optype = 3 *[ ’ GPRegAll ’ , ’ GPRegAll ’ , ’ GPRegAll ’ ] , p e r s i s t e n t _ i d =0x20 , s r c = 3 *[ 1= ’ r0 ’ , ’ r9 ’ ] ; } } b l o c k b5 : address =0x100004d4 , i n s t r u c t i o n _ s e t ="common " , p e r s i s t e n t _ i d =0x21 , s u r f a c e _ a d d r e s s ="0 x100004d4 " { edge e99 ( t r u e ) −> b1 : p e r s i s t e n t _ i d =0x22 ; i n s t r u c t i o n i 1 0 0 0x100004d4 : 4 : b y t e s = 4 *[ 0x7c , 0x03 , 0x03 , 0x78 ] , surface_address ="0 x100004d4 " {
o p e r a t i o n o101 " mr r3 , r 0 " : arch = ’ UISA ’ , assembly =" o r $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ r3 ’ ] , form = ’X ’ , genname = ’ or ’ , op_ id =0xf7c000378 , optype = 3 *[ ’ GPRegAll ’ , ’ GPRegAll ’ , ’ GPRegAll ’ ] , p e r s i s t e n t _ i d =0x23 , s r c = 3 *[ 1= ’ r0 ’ , ’ r0 ’ ] ;
}
i n s t r u c t i o n i 1 0 2 0x100004d8 : 4 : b y t e s = 4 *[ 0x39 , 0x7f , 0x00 , 0x20 ] , surface_address ="0 x100004d8 " {
o p e r a t i o n o103 " a d d i r11 , r31 , + 3 2 " : arch = ’ UISA ’ , assembly =" a d d i $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ r11 ’ ] , form = ’D’ , genname= ’ addi ’ , op_id=0x738000000 , optype =3*[ ’ GPRegAll ’ , ’ GPRegZero ’ , ’ signed ’ ] , p e r s i s t e n t _ i d =0x24 , s r c = 3 *[ 1= ’ r31 ’ , +32 ] ;
}
i n s t r u c t i o n i 1 0 4 0x100004dc : 4 : b y t e s = 4 *[ 0x83 , 0xeb , 0 x f f , 0 x f c ] , surface_address ="0 x100004dc " {
o p e r a t i o n o105 " lwz r31 , −4(r11 ) " : arch = ’ UISA ’ , assembly =" lwz $ , $ ( $ ) " , c a t = { mem_read =1 } , d s t = 1 *[ ’ r31 ’ ] , form = ’D’ , genname= ’ lwz ’ , op_id=0x780000000 , optype =3*[ ’ GPRegAll ’ , ’ signed ’ , ’ GPRegZero ’ ] , p e r s i s t e n t _ i d =0x25 , s r c = 4 *[ 1=−4, ’ r11 ’ , ’Mem’
] ; }
i n s t r u c t i o n i 1 0 6 0x100004e0 : 4 : b y t e s = 4 *[ 0x7d , 0x61 , 0x5b , 0x78 ] , surface_address ="0 x100004e0 " {
o p e r a t i o n o107 " mr r1 , r11 " : arch = ’ UISA ’ , assembly =" o r $ , $ , $ " , c a t = { } , d s t = 1 *[ ’ r1 ’ ] , form = ’X ’ , genname = ’ or ’ , op_ id =0xf7c000378 , optype = 3 *[ ’ GPRegAll ’ , ’ GPRegAll ’ , ’ GPRegAll ’ ] , p e r s i s t e n t _ i d =0x26 , s r c = 3 *[ 1= ’ r11 ’ , ’ r11 ’ ] ;
}
i n s t r u c t i o n i 1 0 8 0x100004e4 : 4 : b y t e s = 4 *[ 0x4e , 0x80 , 0x00 , 0x20 ] , surface_address ="0 x100004e4 " {
o p e r a t i o n o109 " b l r " : arch = ’ UISA ’ , assembly =" b c l r $ " , c a t = { computed =1 , p r e d i c t a b l e =1 , r e t u r n =1 , t ake n =1 } , computed =1 , c o n d i t i o n a l =0 , form = ’ XL ’ , genname = ’ b c l r ’ , op _id =0 x74e800020 , optype = 1 *[ ’ unsigned ’ ] , p e r s i s t e n t _ i d =0x27 , src =2*[ 0x14 , ’ l r ’ ] , t y p e = ’ b r a n c h _ o r _ r e t u r n ’ ;
} } }
Samma rutin ¨
oversatt till ALF:
1 { f u n c 2 { l a b e l 32 { l r e f 32 r o u t i n e _ m a i n } { d e c _ u n s i g n e d 32 0 } } 3 { a r g _ d e c l s } 4 { s c o p e 5 { d e c l s } 6 { i n i t s } 7 { s t m t s 8 { n u l l } /* f u n c id */ 9 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 2 } { d e c _ u n s i g n e d 32 0 } } /* C R L _ B L O C K _ S T A R T */ 10 { j u m p { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 4 } { d e c _ u n s i g n e d 32 0 } } l e a v i n g 0 } /* C R L _ E D G E _ N O R M A L */ 11 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 3 } { d e c _ u n s i g n e d 32 0 } } /* C R L _ B L O C K _ E N D */ 12 { r e t u r n } /* C R L _ B L O C K _ E N D */ 13 { l a b e l 32 { l r e f 32 b l o c k _ m a i n _ 4 } { d e c _ u n s i g n e d 32 0 } } /* C R L _ B L O C K _ N O R M A L */ 14 /* " s t w u r1 , -32( r1 )" ( s t w u ) */ 15 { s t o r e 16 { add 32 /* mem ea < - r1 */ 17 { a d d r 32 { f r e f 32 ram } { d e c _ u n s i g n e d 32 0 } } 18 { sub 32 /* a d j u s t a d d r e s s */ 19 { add 32 /* e f f e c t i v e a d d r e s s */ 20 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } }
21 { d e c _ s i g n e d 32 { m i n u s 32 } } 22 { d e c _ u n s i g n e d 1 0 } } 23 { h e x _ v a l 32 1 0 0 0 0 1 7 4 } 24 { d e c _ u n s i g n e d 1 1 } } 25 { d e c _ u n s i g n e d 1 0 } } 26 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } /* r1 < - { m i n u s 32 } + r1 */ 27 w i t h 28 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } 29 { add 32 30 { d e c _ s i g n e d 32 { m i n u s 32 } } 31 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } 32 { d e c _ u n s i g n e d 1 0 } } } 33 /* " stw r31 , + 2 8 ( r1 )" ( stw ) */ 34 { s t o r e 35 { add 32 /* mem ea < - r31 */ 36 { a d d r 32 { f r e f 32 ram } { d e c _ u n s i g n e d 32 0 } } 37 { sub 32 /* a d j u s t a d d r e s s */ 38 { add 32 /* e f f e c t i v e a d d r e s s */ 39 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } 40 { d e c _ s i g n e d 32 28 } 41 { d e c _ u n s i g n e d 1 0 } } 42 { h e x _ v a l 32 1 0 0 0 0 1 7 4 } 43 { d e c _ u n s i g n e d 1 1 } } 44 { d e c _ u n s i g n e d 1 0 } } 45 w i t h 46 { l o a d 32 { a d d r 32 { f r e f 32 r31 } { d e c _ u n s i g n e d 32 0 } } } } 47 /* " mr r31 , r1 " ( or ) */ 48 { s t o r e 49 { a d d r 32 { f r e f 32 r31 } { d e c _ u n s i g n e d 32 0 } } /* r31 < - r1 | r1 */ 50 w i t h 51 { or 32 52 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } 53 { l o a d 32 { a d d r 32 { f r e f 32 r1 } { d e c _ u n s i g n e d 32 0 } } } } } 54 /* " li r0 , + 1 0 " ( a d d i ) */ 55 { s t o r e 56 { a d d r 32 { f r e f 32 r0 } { d e c _ u n s i g n e d 32 0 } } /* r0 < - z e r o + 10 */ 57 w i t h 58 { add 32 59 { l o a d 32 { a d d r 32 { f r e f 32 z e r o } { d e c _ u n s i g n e d 32 0 } } } 60 { d e c _ s i g n e d 32 10 } 61 { d e c _ u n s i g n e d 1 0 } } } 62 /* " stw r0 , +8( r31 )" ( stw ) */ 63 { s t o r e 64 { add 32 /* mem ea < - r0 */ 65 { a d d r 32 { f r e f 32 ram } { d e c _ u n s i g n e d 32 0 } } 66 { sub 32 /* a d j u s t a d d r e s s */ 67 { add 32 /* e f f e c t i v e a d d r e s s */ 68 { l o a d 32 { a d d r 32 { f r e f 32 r31 } { d e c _ u n s i g n e d 32 0 } } } 69 { d e c _ s i g n e d 32 8 } 70 { d e c _ u n s i g n e d 1 0 } } 71 { h e x _ v a l 32 1 0 0 0 0 1 7 4 } 72 { d e c _ u n s i g n e d 1 1 } } 73 { d e c _ u n s i g n e d 1 0 } } 74 w i t h 75 { l o a d 32 { a d d r 32 { f r e f 32 r0 } { d e c _ u n s i g n e d 32 0 } } } } 76 /* " li r0 , + 2 0 " ( a d d i ) */ 77 { s t o r e 78 { a d d r 32 { f r e f 32 r0 } { d e c _ u n s i g n e d 32 0 } } /* r0 < - z e r o + 20 */ 79 w i t h 80 { add 32 81 { l o a d 32 { a d d r 32 { f r e f 32 z e r o } { d e c _ u n s i g n e d 32 0 } } } 82 { d e c _ s i g n e d 32 20 } 83 { d e c _ u n s i g n e d 1 0 } } } 84 /* " stw r0 , + 1 2 ( r31 )" ( stw ) */ 85 { s t o r e 86 { add 32 /* mem ea < - r0 */ 87 { a d d r 32 { f r e f 32 ram } { d e c _ u n s i g n e d 32 0 } } 88 { sub 32 /* a d j u s t a d d r e s s */ 89 { add 32 /* e f f e c t i v e a d d r e s s */ 90 { l o a d 32 { a d d r 32 { f r e f 32 r31 } { d e c _ u n s i g n e d 32 0 } } } 91 { d e c _ s i g n e d 32 12 } 92 { d e c _ u n s i g n e d 1 0 } } 93 { h e x _ v a l 32 1 0 0 0 0 1 7 4 } 94 { d e c _ u n s i g n e d 1 1 } }
95 { d e c _ u n s i g n e d 1 0 } } 96 w i t h 97 { l o a d 32 { a d d r 32 { f r e f 32 r0 } { d e c _ u n s i g n e d 32 0 } } } } 98 /* " lwz r9 , +8( r31 )" ( lwz ) */ 99 { s t o r e 100 { a d d r 32 { f r e f 32 r9 } { d e c _ u n s i g n e d 32 0 } } /* r9 < - mem 8 + r31 */ 101 w i t h 102 { l o a d 32 103 { add 32 /* add to a d d r e s s */ 104 { a d d r 32 { f r e f 32 ram } { d e c _ u n s i g n e d 32 0 } } 105 { sub 32 /* a d j u s t a d d r e s s */ 106 { add 32 /* e f f e c t i v e a d d r e s s */ 107 { l o a d 32 { a d d r 32 { f r e f 32 r31 } { d e c _ u n s i g n e d 32 0 } } } 108 { d e c _ s i g n e d 32 8 } 109 { d e c _ u n s i g n e d 1 0 } } 110 { h e x _ v a l 32 1 0 0 0 0 1 7 4 } 111 { d e c _ u n s i g n e d 1 1 } } 112 { d e c _ u n s i g n e d 1 0 } } } } 113 /* " lwz r0 , + 1 2 ( r31 )" ( lwz ) */ 114 { s t o r e 115 { a d d r 32 { f r e f 32 r0 } { d e c _ u n s i g n e d 32 0 } } /* r0 < - mem 12 + r31 */ 116 w i t h 117 { l o a d 32 118 { add 32 /* add to a d d r e s s */ 119 { a d d r 32 { f r e f 32 ram } { d e c _ u n s i g n e d 32 0 } } 120 { sub 32 /* a d j u s t a d d r e s s */ 121 { add 32 /* e f f e c t i v e a d d r e s s */ 122 { l o a d 32 { a d d r 32 { f r e f 32 r31 } { d e c _ u n s i g n e d 32 0 } } } 123 { d e c _ s i g n e d 32 12 } 124 { d e c _ u n s i g n e d 1 0 } } 125 { h e x _ v a l 32 1 0 0 0 0 1 7 4 } 126 { d e c _ u n s i g n e d 1 1 } } 127 { d e c _ u n s i g n e d 1 0 } } } } 128 /* " add r0 , r9 , r0 " ( add ) */ 129 { s t o r e 130 { a d d r 32 { f r e f 32 r0 } { d e c _ u n s i g n e d 32 0 } } /* r0 < - r9 + r0 */ 131 w i t h 132 { add 32 133 { l o a d 32 { a d d r 32 { f r e f 32 r9 } { d e c _ u n s i g n e d 32 0 } } } 134 { l o a d 32 { a d d r 32 { f r e f 32 r0 } { d e c _ u n s i g n e d 32 0 } } } 135 { d e c _ u n s i g n e d 1 0 } } } 136 /* " stw r0 , + 1 6 ( r31 )" ( stw ) */ 137 { s t o r e 138 { add 32 /* mem ea < - r0 */ 139 { a d d r 32 { f r e f 32 ram } { d e c _ u n s i g n e d 32 0 } } 140 { sub 32 /* a d j u s t a d d r e s s */ 141 { add 32 /* e f f e c t i v e a d d r e s s */ 142 { l o a d 32 { a d d r 32 { f r e f 32 r31 } { d e c _ u n s i g n e d 32 0 } } } 143 { d e c _ s i g n e d 32 16 } 144 { d e c _ u n s i g n e d 1 0 } } 145 { h e x _ v a l 32 1 0 0 0 0 1 7 4 } 146 { d e c _ u n s i g n e d 1 1 } } 147 { d e c _ u n s i g n e d 1 0 } } 148 w i t h 149 { l o a d 32 { a d d r 32 { f r e f 32 r0 } { d e c _ u n s i g n e d 32 0 } } } } 150 /* " lwz r0 , + 1 6 ( r31 )" ( lwz ) */ 151 { s t o r e 152 { a d d r 32 { f r e f 32 r0 } { d e c _ u n s i g n e d 32 0 } } /* r0 < - mem 16 + r31 */ 153 w i t h 154 { l o a d 32 155 { add 32 /* add to a d d r e s s */ 156 { a d d r 32 { f r e f 32 ram } { d e c _ u n s i g n e d 32 0 } } 157 { sub 32 /* a d j u s t a d d r e s s */ 158 { add 32 /* e f f e c t i v e a d d r e s s */ 159 { l o a d 32 { a d d r 32 { f r e f 32 r31 } { d e c _ u n s i g n e d 32 0 } } } 160 { d e c _ s i g n e d 32 16 } 161 { d e c _ u n s i g n e d 1 0 } } 162 { h e x _ v a l 32 1 0 0 0 0 1 7 4 } 163 { d e c _ u n s i g n e d 1 1 } } 164 { d e c _ u n s i g n e d 1 0 } } } } 165 /* " c m p i cr7 , 0 , r0 , + 2 4 " ( c m p i ) */ 166 { s t o r e 167 { a d d r 32 { f r e f 32 c r 7 _ l t } { d e c _ u n s i g n e d 32 0 } } /* lt */ 168 { a d d r 32 { f r e f 32 c r 7 _ g t } { d e c _ u n s i g n e d 32 0 } } /* gt */