Obsah
1. RISCová architektura PowerPC
2. Specifikace stará čtvrt století a její pozdější modifikace
3. Pracovní registry dostupné programátorům
4. Registr s příznakovými bity (CR – Condition Register)
7. Příznakové bity nastavené po porovnání dvou operandů
8. Registr s příznakovými bity celočíselných operací (XER – Fixed-Point Exception Register)
9. Registr s návratovou adresou ze subrutiny (LR – Link Register)
10. Registr pro implementaci smyček (CTR – Count Register)
11. Instrukční sada a základní formáty instrukcí
12. Modul pro řízení běhu programu (Branch Processor)
14. Bit obsahující „nápovědu“ pro prediktor skoků
1. RISCová architektura PowerPC
Architektura PowerPC patří společně s již popsanými architekturami MIPS, SPARC, Motorola 88000, AMD 29000, PA-RISC, RISC-V, ARM či OpenRISC do rodiny RISCových architektur postavených na principech, které byly poprvé implementovány v procesorech RISC-I. Tyto architektury se vyznačují některými společnými vlastnostmi, mezi něž patří zejména (relativně) jednoduchý formát instrukcí (někdy existují pouze tři formáty instrukcí, viz například klasický MIPS), velké množství pracovních registrů, instrukce mají typicky pevnou délku, operace s daty uloženými v paměti jsou většinou redukovány na instrukce typu LOAD a STORE a většina RISCových procesorů taktéž implementuje buď nějakou formu prediktoru skoků nebo alespoň takzvaný branch delay slot. Tyto vlastnosti nebyly vybrány náhodou: snaha architektů směřovala a stále směřuje k tomu, aby se instrukce mohly v RISCových procesorech provádět v pipeline, což vede ke zrychlení běhu programů a taktéž k mnohem lepšímu využití plochy čipu (zjednodušeně řečeno – díky pipeline mají všechny tranzistory na čipu „co na práci“).
2. Specifikace stará čtvrt století a její pozdější modifikace
Samotná architektura PowerPC existuje již téměř 25 let (konkrétně od roku 1992) a za tuto dlouhou dobu prošla několika modifikacemi. Moderní čipy se od původní specifikace v některých ohledech liší. Zejména byly odstraněny některé příliš komplexní a ne zcela nezbytné instrukce, mezi něž patří například operace s číselnými hodnotami s plovoucí řádovou čárkou se čtyřnásobnou přesností (quad precision, quadruple precision), dále některé instrukce určené pro podmíněné přenosy dat apod. Naopak se postupně přidávaly další užitečné instrukce, typicky instrukce pro operace s hodnotami typu float (původně jen double a quad), operace typu multiply-add určená pro algoritmy pro zpracování signálu, režimy big-endian nebo little-endian, 64bitový režim plně zpětně kompatibilní s 32bitovým režimem a nesmíme zapomenout ani na AltiVec, což je specifikace SIMD (vektorové) instrukční sady se 128bitovými „vektory“ (toto rozšíření se někdy označuje taktéž jmény Velocity Engine nebo Vector Multimedia Extension.
Complex/ Simple/ CISC______________________________________________________________RISC | 14500B* | 4-bit | *Am2901 | | *4004 | | *4040 | 8-bit | 6800,650x *1802 | | 8051* * *8008 * SC/MP | | Z8 * * *F8 | | F100-L* 8080/5 2650 | | * *NOVA * *PIC16x | | MCP1600* *Z-80 *6809 IMS6100 | 16-bit| *Z-280 *PDP11 80C166* *M17 | | *8086 *TMS9900 | | *Z8000 *65816 | | *56002 | | 32016* *68000 ACE HOBBIT Clipper R3000 | 32-bit|432 96002 *68020 * * * * *AMD 29000 * *ARM | | * *VAX * 80486 68040 *PSC i960 *SPARC *SH | | Z80000* * * TRON48 PA-RISC | | PPro Pent* -- T9000 -*------- * *88100 | | * * -- 860 -*--*----- * *88110 | 64-bit|Rekurs POWER PowerPC * CDC6600 *R4000 | | x86-64* *620 U-SPARC * *R8000 *Alpha | | ------- IA-64 ------- R10000 | CISC______________________________________________________________RISC
Obrázek 1: Poměrně hrubé rozdělení architektur mikroprocesorů podle bitové šířky zpracovávaných operandů a taktéž podle toho, jak blízko má daná architektura k ortodoxně pojatému konceptu RISC nebo naopak CISC (pozice na horizontální ose je ovšem v mnoha případech sporná).
3. Pracovní registry dostupné programátorům
Podívejme se nyní na mikroprocesory s architekturou PowerPC z pohledu programátora. Procesory PowerPC obsahují poměrně rozsáhlou sadu registrů, kterou lze rozdělit na pracovní registry a na registry stavové a řídicí. Jak je u RISCových architektur dobrým zvykem, je skupina pracovních registrů poměrně rozsáhlá, což zde konkrétně znamená, že pro celočíselné operace je možné použít 32 pracovních registrů nazvaných GPR0 až GPR31, z nichž každý má šířku 64bitů (v 64bitovém režimu PowerPC) a pro operace s hodnotami s plovoucí řádovou čárkou se používají pracovní registry FPR0 až FPR31, které mají taktéž šířku 64 bitů. Mezi stavové a řídicí registry pak patří CR (32bitový), LR, CTR, XER a FPSCR (taktéž 32bitový). Všechny viditelné registry jsou pro přehlednost vypsány v následující tabulce:
Označení | Šířka | Význam označení |
---|---|---|
GPR0 – GPR31 | 64 bitů | General Purpose Register(s) |
FPR0 – FPR31 | 64 bitů | Floating-Point Register(s) |
CR | 32 bitů | Condition Register |
LR | 64 bitů | Link Register |
CTR | 64 bitů | Count Register |
XER | 32 bitů | Fixed-Point Exception Register |
FPSCR | 32 bitů | Floating-Point Status and Control Register |
Poznámka: nenechte se zmást označením „Fixed-Point“. Tyto registry můžeme považovat za registry celočíselné, i když je samozřejmě možné hodnotu v nich uloženou považovat za hodnotu s pevnou řádovou čárkou (což je některými instrukcemi podporováno).
4. Registr s příznakovými bity (CR – Condition Register)
Rozvětvení (rozeskoky) a programové smyčky se většinou na úrovni strojového kódu realizují s využitím takzvaných příznakových bitů (flags). Ty jsou používány u mnoha mikroprocesorových architektur, včetně populárních čipů typu ARM, i386, x86–64 apod. (určitou výjimku z tohoto trendu představují čipy s architekturami MIPS, RISC-V, DEC Alpha a taktéž některé VLIW architektury). S příznakovými bity se setkáme i u procesorů PowerPC, i když v poněkud odlišné a zobecněné podobně. První registr, v němž se pracuje s příznakovými bity, se jmenuje příznačně CR neboli Condition Registr. Tento registr má šířku 32 bitů a je rozdělen do osmi čtyřbitových polí označovaných symboly CR0 až CR7:
31 28 24 20 16 12 8 4 0 +----+----+----+----+----+----+----+----+ | CR7| CR6| CR5| CR4| CR3| CR2| CR1| CE0| +----+----+----+----+----+----+----+----+
5. Význam pole CR0
První pole se jménem CR0, tj. nejnižší čtyři bity registru CR, má speciální význam, neboť první tři bity v něm jsou nastavovány běžnými celočíselnými instrukcemi (sčítání atd.) a to konkrétně porovnáním výsledku operace s nulou:
Bit v CR0 | Zkratka | Význam |
---|---|---|
0 | LT | Negative (kladný výsledek) |
1 | GT | Positive (záporný výsledek) |
2 | EQ | Zero (nulový výsledek) |
3 | SO | Summary Overflow (zkopírován z registru XER) |
Bit SO je v tomto ohledu výjimečný, neboť neobsahuje příznak nastavený po porovnání výsledku nějaké celočíselné operace s nulou, ale kopii stejnojmenného bitu SO z registru XER, který bude popsán v dalším textu.
6. Význam pole CR1
Druhé pole se jménem CR1, tj. bity 4 až 7 z příznakového registru CR, má taktéž speciální význam, neboť bity v něm jsou nastavovány při operacích s hodnotami s plovoucí řádovou čárkou:
Bit v CR0 | Zkratka | Význam |
---|---|---|
4 | FX | (kopie z FPSCR) Floating-Point Exception Summary |
5 | FEX | (kopie z FPSCR) Floating-Point Enabled Exception Summary |
6 | VX | (kopie z FPSCR) Floating-Point Invalid Operation Exception Summary |
7 | OX | (kopie z FPSCR) Floating-Point Overflow Exception |
Význam těchto příznaků zkopírovaných ze stavového registru FPSCR:
Příznak | Význam |
---|---|
FX | obsahuje bitové OR všech ostatních výjimek, které mohou nastat při FP operaci |
FEX | obsahuje bitové OR všech ostatních výjimek, které ovšem nejsou maskovány |
VX | nevalidní operace typu 0/0, ∞-∞, ∞/∞, 0×∞ a podobné chuťovky |
OX | přetečení FP operace (typicky při překročení maximální hodnoty exponentu) |
První dva bity obsahují hodnotu 1, pokud došlo alespoň k jedné výjimce (přetečení, podtečení, dělení nulou, nepřesný výsledek). U bitu FEX je navíc možné selektivně jednotlivé typy výjimek maskovat.
7. Příznakové bity nastavené po porovnání dvou operandů
Dále existuje několik instrukcí určených pro porovnání dvou operandů, a to jak operandů celočíselných, tak operandů s plovoucí řádovou čárkou. Tyto instrukce nastavují čtyři bity libovolného pole CR0 až CR7, a to následujícím způsobem:
Bit | Příznak | Význam |
---|---|---|
CRx+0 | LT | první operand menší než druhý |
CRx+1 | GT | první operand větší než druhý |
CRx+2 | EQ | operandy jsou shodné |
CRx+3 | SO | opět zkopírováno z registru XER |
Pro operace s plovoucí řádovou čárkou jsou významy příznaků nepatrně odlišné:
Bit | Příznak | Význam |
---|---|---|
CRx+0 | FL | první operand menší než druhý |
CRx+1 | FG | první operand větší než druhý |
CRx+2 | FE | operandy jsou shodné |
CRx+3 | FU | unordered – nelze porovnat, neboť jeden z operandů je NaN |
8. Registr s příznakovými bity celočíselných operací (XER – Fixed-Point Exception Register)
Stavový registr CR je doplněn dalšími dvěma stavovými registry. Pro celočíselné operace se používá registr nazvaný XER a pro operace s plovoucí řádovou čárkou pak registr FPSCR. Registr XER je sice 64bitový, ovšem nejnižších 32 bitů je rezervovaných. Pro aritmetické operace mají význam především bity 32, 33 a 34:
Bit | Příznak | Význam |
---|---|---|
32 | SO | odpovídá OV, ovšem není automaticky nulován další operací, nulování se musí provést explicitně |
33 | OV | příznak přetečení, nastavován při sčítání a odčítání, ne při porovnávání |
34 | CA | příznak přenosu, používán některými aritmetickými operacemi i bitovými posuny |
Příznaky OV a CA zhruba odpovídají příznakům OF a CF na architektuře i386/x86–64.
9. Registr s návratovou adresou ze subrutiny (LR – Link Register)
Na některých RISCových architekturách mikroprocesorů se můžeme setkat s tím, že návratové adresy se při volání podprogramů (subrutin) neukládají na zásobník. Namísto zásobníku se používá speciální registr nazvaný Link Register nebo též zkráceně LR. U některých mikroprocesorů je link register součástí obecně použitelných registrů, ovšem u architektury PowerPC je tomu jinak a LR je oddělen od běžných pracovních registrů GPR0 až GPR31 (nesnižuje tedy jejich počet). Registr LR má šířku 64 bitů, ovšem spodní dva bity jsou ve skutečnosti nulové, neboť každá instrukce má šířku 32 bitů a je v operační paměti zarovnána na celá slova (adresy jsou dělitelné čtyřmi). Pro skok do podprogramu se používají instrukce typu branch and link, pro návrat pak instrukce typu branch to link register.
10. Registr pro implementaci smyček (CTR – Count Register)
Zajímavý je registr nazvaný CTR neboli Count Register. Jak již název napovídá, lze tento 64bitový registr použít pro implementaci počítaných programových smyček, neboť architektura PowerPC obsahuje instrukce podmíněného skoku, které mohou snížit obsah tohoto registru (o jedničku) a následně provést skok, ovšem pouze za podmínky, že hodnota čítače dosáhla nuly či je naopak nenulová. Tuto podmínku je ještě možné doplnit o test nějakého bitu z již popsaného stavového registru CR, takže jediná instrukce podmíněného skoku může ve skutečnosti realizovat relativně složitou podmínku.
11. Instrukční sada a základní formáty instrukcí
I přes označení RISC je ve skutečnosti instrukční sada architektury PowerPC velmi rozsáhlá a obsahuje stovky instrukcí a jejich kombinací. Ovšem všechny instrukce dodržují pravidlo, že mají shodnou šířku 32 bitů a jsou vždy zarovnány na adresu dělitelnou čtyřmi (to mj. znamená, že adresy cílů skoků vždy končí bity 00). Existuje poměrně velké množství formátů instrukcí, například I-format, B-format, SC-format, D-format, DS-format atd. Bity v instrukčním slovu tvoří takzvaná bitová pole, ovšem někdy je bitové pole rozděleno do více částí (aby nebylo dekódování tak jednoduché). Nejnižších pět bitů instrukce tvoří operační kód (OPCD), který je ovšem upřesněn hodnotami bitů z dalších polí.
Obecně lze instrukce rozdělit podle toho, který modul v procesoru je zpracovává:
- Skokové instrukce
- Instrukce celočíselné popř. instrukce s hodnotami s pevnou řádovou čárkou
- Instrukce s hodnotami s plovoucí řádovou čárkou
12. Modul pro řízení běhu programu (Branch Processor)
Modul pro řízení běhu programu (Branch Processor) vykonává především skokové instrukce a taktéž se stará o řízení běhu programu při vzniku výjimky, zachycení výjimky a při volání systémových služeb. Tento modul velmi úzce používá již popsanou trojici stavových registrů – Condition Register CR, Link Register LR a Count Register CTR. Výsledkem práce tohoto modulu je efektivní adresa následující instrukce, což v případě skoku samozřejmě znamená instrukci, která leží na cílové adrese. Efektivní adresu následující instrukce lze vypočítat jednou z těchto variant:
- Absolutní adresa specifikovaná operandem skokové instrukce.
- Relativní adresa (offset), typické u podmíněných skoků.
- Návratová adresa ze subrutiny uložená v link registru (LR)
- Adresa uložená v count registru (CTR, speciální případ použití tohoto registru)
13. Skokové instrukce
U skokových instrukcí se specifikuje jak cíl skoku (viz předchozí kapitolu se čtyřmi možnostmi, jak lze cíl skoku vypočítat), tak i případná podmínka, při jejímž splnění se má skok provést. Otestovat je možné vybraný bit registru CR a provést skok pokud je tento přečtený bit nulový či naopak nenulový. Dále je možné snížit hodnotu čítače CTR a provést skok v případě jeho nulovosti či nenulovosti. Možné jsou ovšem i kombinace – vybraný bit z registru CR je nulový/nenulový a současně hodnota CTR snížená o jedničku dosáhla/nedosáhla nuly. Kombinací tedy existuje velké množství a samozřejmě nesmíme zapomenout na skok provedený vždy – branch always. Podrobnosti si ukážeme příště.
14. Bit obsahující „nápovědu“ pro prediktor skoků
Některé instrukce skoku obsahují dva bity nazývané „at“ (resp. přesněji „a“ a „t“, kde „t“ pravděpodobně značí „(branch) taken“). Tyto bity ovlivňují prediktor skoků a lze je považovat za statickou predikci nastavovanou překladačem či programátorem v assembleru. Význam je jednoduchý – kombinace 11 znamená, že překladač předpokládá, že se skok většinou provede, kombinace 10 znamená, že překladač předpokládá, že se skok naopak neprovede a kombinace 00 značí, že se má procesor spolehnout na svůj dynamický prediktor skoků (což je doporučovaná hodnota, pokud ovšem z kvalitní analýzy kódu neplynou jiné výsledky). Hodnota 01 je prozatím rezervovaná.
15. Odkazy na Internetu
- PowerPC overview (poněkud starší materiály z roku 2006)
http://titancity.com/articles/ppc.html - PowerPC (Wikipedia)
https://en.wikipedia.org/wiki/PowerPC - Status Register
https://en.wikipedia.org/wiki/Status_register - Why Learn Assembly Language?
http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language - Is Assembly still relevant?
http://programmers.stackexchange.com/questions/95836/is-assembly-still-relevant - Why Learning Assembly Language Is Still a Good Idea
http://www.onlamp.com/pub/a/onlamp/2004/05/06/writegreatcode.html - Assembly language today
http://beust.com/weblog/2004/06/23/assembly-language-today/ - RISC-V Draft Sompressed ISA Version 1.9 Released
https://blog.riscv.org/2015/11/risc-v-draft-compressed-isa-version-1–9-released/ - RISC vs. CISC: the Post-RISC Era
http://archive.arstechnica.com/cpu/4q99/risc-cisc/rvc-1.html - Introduction to ARM Thumb
http://www.embedded.com/electronics-blogs/beginner-s-corner/4024632/Introduction-to-ARM-thumb - Code Size – a comprehensive comparison of microMIPS32 and Thumb code size using many Megabytes of customer code
https://community.arm.com/groups/processors/blog/2014/04/28/code-size-a-comprehensive-comparison-of-micromips32-and-thumb-code-size-using-many-megabytes-of-customer-code - MIPS MCUs Outrun ARM
http://www.linleygroup.com/newsletters/newsletter_detail.php?num=5117 - Improving Energy Efficiency and Reducing Code Size with RISC-V Compressed
http://www.eecs.berkeley.edu/~waterman/papers/ms-thesis.pdf - An Introduction to Lock-Free Programming
http://preshing.com/20120612/an-introduction-to-lock-free-programming/ - Sequential consistency
https://en.wikipedia.org/wiki/Sequential_consistency - Understanding Atomic Operations
https://jfdube.wordpress.com/2011/11/30/understanding-atomic-operations/ - Load-link/store-conditional
https://en.wikipedia.org/wiki/Load-link/store-conditional - The RISC-V Compressed Instruction Set Manual (Pozor: verze 1.7)
http://riscv.org/spec/riscv-compressed-spec-v1.7.pdf - Carry bits, The Architect's Trap
http://yarchive.net/comp/carry_bit.html - Microprocessor Design/ALU Flags
https://en.wikibooks.org/wiki/Microprocessor_Design/ALU_Flags - Flags register in an out-of-order processor
http://cs.stackexchange.com/questions/42095/flags-register-in-an-out-of-order-processor - AMD Am29000
https://en.wikipedia.org/wiki/AMD_Am29000 - Status register
https://en.wikipedia.org/wiki/Status_register - AMD Am29000 microprocessor family
http://www.cpu-world.com/CPUs/29000/ - AMD 29k (Streamlined Instruction Processor) ID Guide
http://www.cpushack.com/Am29k.html - AMD Am29000 (Wikipedia)
http://en.wikipedia.org/wiki/AMD_Am29000 - AMD K5 („K5“ / „5k86“)
http://www.pcguide.com/ref/cpu/fam/g5K5-c.html - Comparing four 32-bit soft processor cores
http://www.eetimes.com/author.asp?section_id=14&doc_id=1286116 - RISC-V Instruction Set
http://riscv.org/download.html#spec_compressed_isa - RISC-V Spike (ISA Simulator)
http://riscv.org/download.html#isa-sim - RISC-V (Wikipedia)
https://en.wikipedia.org/wiki/RISC-V - David Patterson (Wikipedia)
https://en.wikipedia.org/wiki/David_Patterson_(computer_scientist) - OpenRISC (oficiální stránky tohoto projektu)
http://openrisc.io/ - OpenRISC architecture
http://openrisc.io/architecture.html - Emulátor OpenRISC CPU v JavaScriptu
http://s-macke.github.io/jor1k/demos/main.html - OpenRISC (Wikipedia)
https://en.wikipedia.org/wiki/OpenRISC - OpenRISC – instrukce
http://sourceware.org/cgen/gen-doc/openrisc-insn.html - OpenRISC – slajdy z přednášky o tomto projektu
https://iis.ee.ethz.ch/~gmichi/asocd/lecturenotes/Lecture6.pdf - Maska mikroprocesoru RISC 1
http://www.cs.berkeley.edu/~pattrsn/Arch/RISC1.jpg - Maska mikroprocesoru RISC 2
http://www.cs.berkeley.edu/~pattrsn/Arch/RISC2.jpg - C.E. Sequin and D.A.Patterson: Design and Implementation of RISC I
http://www.eecs.berkeley.edu/Pubs/TechRpts/1982/CSD-82–106.pdf - Berkeley RISC
http://en.wikipedia.org/wiki/Berkeley_RISC - Great moments in microprocessor history
http://www.ibm.com/developerworks/library/pa-microhist.html - Microprogram-Based Processors
http://research.microsoft.com/en-us/um/people/gbell/Computer_Structures_Principles_and_Examples/csp0167.htm - Great Microprocessors of the Past and Present
http://www.cpushack.com/CPU/cpu1.html - A Brief History of Microprogramming
http://www.cs.clemson.edu/~mark/uprog.html - What is RISC?
http://www-cs-faculty.stanford.edu/~eroberts/courses/soco/projects/2000–01/risc/whatis/ - RISC vs. CISC
http://www-cs-faculty.stanford.edu/~eroberts/courses/soco/projects/2000–01/risc/risccisc/ - RISC and CISC definitions:
http://www.cpushack.com/CPU/cpuAppendA.html - FPGA
https://cs.wikipedia.org/wiki/Programovateln%C3%A9_hradlov%C3%A9_pole - The Evolution of RISC
http://www.ibm.com/developerworks/library/pa-microhist.html#sidebar1 - SPARC Processor Family Photo
http://thenetworkisthecomputer.com/site/?p=243 - SPARC: Decades of Continuous Technical Innovation
http://blogs.oracle.com/ontherecord/entry/sparc_decades_of_continuous_technical - The SPARC processors
http://www.top500.org/2007_overview_recent_supercomputers/sparc_processors - Reduced instruction set computing (Wikipedia)
http://en.wikipedia.org/wiki/Reduced_instruction_set_computer - MIPS architecture (Wikipedia)
http://en.wikipedia.org/wiki/MIPS_architecture - Very long instruction word (Wikipedia)
http://en.wikipedia.org/wiki/Very_long_instruction_word - Classic RISC pipeline (Wikipedia)
http://en.wikipedia.org/wiki/Classic_RISC_pipeline - R2000 Microprocessor (Wikipedia)
http://en.wikipedia.org/wiki/R2000_(microprocessor) - R3000 Microprocessor (Wikipedia)
http://en.wikipedia.org/wiki/R3000 - R4400 Microprocessor (Wikipedia)
http://en.wikipedia.org/wiki/R4400 - R8000 Microprocessor (Wikipedia)
http://en.wikipedia.org/wiki/R8000 - R10000 Microprocessor (Wikipedia)
http://en.wikipedia.org/wiki/R10000 - SPARC (Wikipedia)
http://en.wikipedia.org/wiki/Sparc - CPU design (Wikipedia)
http://en.wikipedia.org/wiki/CPU_design - Control unit (Wikipedia)
http://en.wikipedia.org/wiki/Control_unit