Obsah
1. Mikroprocesory a mikrořadiče s jádrem SH-2A a koprocesorem SH2A-FPU
2. Pracovní registry matematického koprocesoru
3. Registr FPUL používaný při přenosu dat
4. Stavový a řídicí registr FPSCR
5. Formáty zpracovávaných hodnot s plovoucí řádovou čárkou
6. Speciální hodnoty a jejich význam
8. Výjimky, které mohou vzniknout při FP operacích
9. Seznam instrukcí matematického koprocesoru
10. Základní aritmetické operace
11. Funkce s jedním vstupním operandem
12. Porovnání operandů s nastavením bitu T
13. Načtení konstanty a konverze
14. Přenos FP hodnot mezi matematickým koprocesorem a pamětí
15. Porovnání možností SH2A-FPU s dalšími RISCovými čipy
1. Mikroprocesory a mikrořadiče s jádrem SH-2A a koprocesorem SH2A-FPU
V předchozích třech částech tohoto seriálu jsme si popsali RISCové procesory s architekturou SH-2 i s její rozšířenou variantou SH-2A. Obě tyto architektury jsou používány doposud a nalezneme je především v čipech vyráběných společností Renesas, která vývoj i výrobu převzala od firmy Hitachi. Vzhledem k tomu, že mnohé moderní čipy musí být připraveny pro zpracování různých typů dat a mnohdy i pro komplikovanější výpočty, nás asi nepřekvapí, že u některých mikroprocesorů a mikrořadičů s architekturou SH-2A nalezneme i matematický koprocesor (realizovaný samozřejmě na stejném čipu). Tento mikroprocesor má vlastní sadu pracovních registrů, stavový a řídicí registr, registr určený pro přenosy dat a pracuje nezávisle na hlavní ALU. Dnes si tento matematický koprocesor popíšeme a navíc si v poslední třetině článku porovnáme jeho možnosti s dalšími RISCovými čipy, což by mohlo být zajímavé, protože jednotlivé RISCové čipy se používaly v mnohdy zcela odlišných oblastech, od mikrořadičů přes grafické pracovní stanice až po superpočítače.
2. Pracovní registry matematického koprocesoru
Matematický koprocesor má vlastní sadu šestnácti 32bitových pracovních registrů pojmenovaných FPR0 až FPR15. Na základě nastaveného režimu je možné tyto registry použít pro uložení hodnot s plovoucí řádovou čárkou s jednoduchou přesností (single) či s dvojitou přesností (double). Při použití jednoduché přesnosti se sada šestnácti pracovních registrů označuje v assembleru jmény FP0 až FP15 (vypadlo písmeno R), zatímco při použití dvojité přesnosti se sada registrů zmenšuje na polovinu: DR0, DR2, DR4 až DR14 (každý z těchto pseudoregistrů má šířku 64 bitů a zabírá dva původní registry FPRn+FPRn+1). Režim výpočtů a režim přenosu dat se ovládá bity PR a SZ v řídicím a stavovém registru FPSCR popsaném v dalších kapitolách.
3. Registr FPUL používaný při přenosu dat
Hodnoty je možné do matematického koprocesoru přenášet dvěma způsoby. Buď je lze přímo načítat z operační paměti s využitím instrukcí FMOV.S a FMOV.D, nebo je možné využít speciální registr FPUL (Floating-Point Communication Register), který tvoří rozhraní mezi hlavním procesorem a matematickým koprocesorem. K dispozici jsou čtyři instrukce určené pro načtení či uložení hodnoty do tohoto registru:
Instrukce | Operandy | Význam |
---|---|---|
LDS | Rm,FPUL | FPUL=Rm |
LDS.L | @Rm+, FPUL | FPUL=(Rm), Rm=Rm+4 |
STS | FPUL,Rn | Rn=FPUL |
STS.L | FPUL,@-Rn | Rn=Rn-4, (Rn)=FPUL |
Jakmile je FP hodnota umístěna v registru FPUL, použijí se na straně matematického koprocesoru instrukce popsané ve třinácté kapitole, které dokážou provádět konverze, prosté uložení hodnoty do zvoleného FP registru apod.
4. Stavový a řídicí registr FPSCR
Kromě sady pracovních registrů a speciálního registru FPUL se při použití matematického koprocesoru využívá stavový a řídicí registr nazvaný FPSCR (podobný registr nalezneme i u mnoha dalších mikroprocesorových architektur). Registr FPSCR je 32bitový, ovšem pouze některé jeho bity jsou skutečně využity. Navíc jsou některé bity určeny pouze pro čtení, protože se nastavují automaticky při provádění některých operací:
Bity | Označení | Přístup | Stručný popis |
---|---|---|---|
0..1 | RM | R/W | volba zaokrouhlovacího režimu |
2..6 | Flag | R/W | bitové pole s „trvalým“ pamatováním příznaků výjimek |
7..11 | Enable | R/W | bitové pole pro povolení jednotlivých typů výjimek |
12..17 | Cause | R/W | bitové pole pro uložení příznaků výjimek |
18 | DN | R | detekce denormalizované hodnoty při provedení operace |
19 | PR | R/W | řízení režimu výpočtů: single/double |
20 | SZ | R/W | řízení režimu přenosu pro instrukce FMOV: single/double |
22 | QIS | R/W | nastavení režimu zpracování hodnot qNaN a nekonečen |
Zajímavý je rozdíl mezi bitovým polem Flag a Cause. Příznaky výjimky v bitovém poli Cause se vždy vynulují před provedením další FP operace, což znamená, že pokud se provede například dělení 0/0 a posléze součet dvou jiných čísel, už se o dělení nulou nedozvíme. Naproti tomu bity v bitovém poli Flag jsou do jedničky nastaveny trvale, přesněji řečeno až do doby, dokud nejsou vynulovány programem (zápisem do registru FPSCR). Díky tomu lze provést delší výpočet a až poté zkontrolovat, zda proběhl správně, a to bez nutnosti implementace relativně složitého mechanismu obsluhy výjimek.
Poznámka: ve skutečnosti je v poli Cause šest bitů, protože zde nalezneme i bit FPU Error (E). Ostatní dvě korespondující bitová pole mají jen pět bitů. FPU Error nemá na SH2-FPU význam a ani ho nelze zakázat.
Pro načtení hodnoty tohoto registru či naopak pro jeho uložení lze použít následující instrukce:
Instrukce | Operandy | Význam |
---|---|---|
LDS | Rm,FPSCR | FPSCR=Rm |
LDS.L | @Rm+, FPSCR | FPSCR=(Rm), Rm=Rm+4 |
STS | FPSCR,Rn | Rn=FPSCR |
STS.L | FPSCR,@-Rn | Rn=Rn-4, (Rn)=FPSCR |
5. Formáty zpracovávaných hodnot s plovoucí řádovou čárkou
V této kapitole si ve stručnosti popíšeme bitové podoby obou formátů numerických hodnot uložených v systému plovoucí řádové čárky, tj. hodnot zpracovávaných v SH2A-FPU. U obou formátů je použita shodná struktura – v jednom bitu je uloženo znaménko čísla, následuje (dvojkový) exponent a ve třetím bitovém poli je uložena mantisa. Formát single odpovídá normě IEEE 754, a to včetně speciálních hodnoty typu nekonečna, denormalizovaných čísel či NaN. 32bitové slovo je rozděleno následovně:
+-+--------+-----------------------+ |s|exponent| mantisa, bity 0..22 | +-+--------+-----------------------+ 31 30 23 22 0
U formátu double, který taktéž odpovídá specifikaci popsané v normě IEEE 754, je rozšířen jak exponent (což zvyšuje rozsah reprezentovatelných hodnot), tak i mantisa (což naopak zvyšuje přesnost uložených hodnot). Číselné hodnoty jsou v operační paměti uloženy ve dvou 32bitových slovech, protože čipy SH-2A k paměti přistupují po 32bitové sběrnici:
+-+-----------+--------------------+ |s| exponent |mantisa, bity 32..51| +-+-----------+--------------------+ 31 30 20 19 0 +----------------------------------+ | mantisa, bity 0..31 | +----------------------------------+ 31 0
Základní vlastnosti obou podporovaných formátů jsou shrnuty v následující tabulce:
Vlastnost | Jednoduchá přesnost | Dvojitá přesnost |
---|---|---|
Znaménko | 1 bit | 1 bit |
Exponent | 8 bitů | 11 bitů |
Mantisa | 23 bitů | 52 bitů |
Celkem | 32 bitů | 64 bitů |
Bias | +127 | +1023 |
6. Speciální hodnoty a jejich význam
Kromě běžných (normalizovaných) hodnot je možné v registrech matematického koprocesoru ukládat i několik speciálních hodnot, které například mohou být výsledkem některých matematických operací. Jedná se především o kladné a záporné nekonečno (výsledek dělení nulou), dále lze rozlišit kladnou a zápornou nulu, takzvaná denormalizovaná čísla (ta mají sníženou přesnost kvůli omezení velikosti exponentu) a taktéž hodnoty NaN (Not a Number), které vzniknou například po operaci 0/0 či ∞+∞. Podívejme se na některé možnosti v případě použití jednoduché přesnosti (32bitových registrů):
Hodnota (hex) | Význam |
---|---|
0×0000 0000 | kladná nula |
0×8000 0000 | záporná nula |
0×7f80 0000 | kladné nekonečno |
0×ff80 0000 | záporné nekonečno |
0×0000 0001 až 0×007f ffff | kladná denormalizovaná čísla |
0×8000 0001 až 0×807f ffff | záporná denormalizovaná čísla |
0×ff8? ???? | NaN |
7. Režimy zaokrouhlování
Na rozdíl od mnoha dalších typů matematických koprocesorů lze u SH2A-FPU zvolit zaokrouhlovací režim pouze ze dvou variant (běžnější jsou čtyři varianty odpovídající normě IEEE 754). Jedná se o zaokrouhlení na nejbližší reprezentovatelné číslo nebo zaokrouhlení směrem k nule (samozřejmě v závislosti na tom, zda se zaokrouhluje kladná či záporná hodnota). Zajímavé je, že v řídicím registru FPSCR jsou pro volbu zaokrouhlovacího režimu rezervovány dva bity, takže zde existuje prostor pro případné další rozšiřování.
8. Výjimky, které mohou vzniknout při FP operacích
Při provádění FP operací může vzniknout několik typů výjimek, jejichž příznaky jsou uloženy do bitových polí Flag a Cause registru FPSCR (viz též čtvrtou kapitolu):
Příznak | Význam |
---|---|
Invalid Operation | vstupem do operace je NaN, či podobný typ chyby |
Division by Zero | dělení nulou, ovšem kromě operace 0/0 |
Overflow | přetečení (výsledek nelze reprezentovat) |
Underflow | podtečení (výsledek je tak blízko nuly, že nelze reprezentovat) |
Inexact | došlo k přetečení, podtečení či nutnosti zaokrouhlení |
Poznámka: termínem zaokrouhlení se zde myslí změna posledního reprezentovatelného bitu mantisy, nikoli zaokrouhlení na celé číslo.
9. Seznam instrukcí matematického koprocesoru
V následujících pěti kapitolách si popíšeme všechny instrukce, které jsou určeny pro ovládání matematického koprocesoru SH2A-FPU. Instrukce můžeme rozdělit jak podle typu operandů (hodnoty s jednoduchou nebo dvojitou přesností), tak i podle funkce či operace, kterou tyto instrukce provádí. V kapitole desáté nalezneme instrukce určené pro provádění základních aritmetických operací se dvěma zdrojovými operandy a jedním operandem cílovým. Podporované unární operace budou popsány v jedenácté kapitole. Důležité jsou samozřejmě i operace určené pro porovnání dvou operandů a nastavení příznakového bitu T; tyto operace jsou popsány v kapitole číslo 12. V navazující kapitole se seznámíme s konverzními funkcemi i instrukcemi určenými pro načtení konstant. A konečně si ve čtrnácté kapitole popíšeme instrukce určené pro přenos hodnot mezi matematickým koprocesorem a operační pamětí.
10. Základní aritmetické operace
Mezi základní aritmetické operace podporované matematickými koprocesory SH2A-FPU patří podle očekávání součet, rozdíl, součin a podíl, k nimž ještě připočtěme operaci typu multiply and accumulate (ta je prováděná jen s typem float/single, což je však pravděpodobně pro většinu aplikací dostačující). Povšimněte si, že součet, rozdíl a součin trvá v případě použití operandů s jednoduchou přesností pouhý jeden takt, zatímco u operandů s dvojitou přesností šest taktů. Operace dělení je mnohem delší – deset popř. celých 23 hodinových cyklů:
Instrukce | Operandy | Prováděná činnost | Počet cyklů |
---|---|---|---|
FADD | FRm, FRn | FRn=FRn+FRm | 1 |
FADD | DRm, DRn | DRn=DRn+DRm | 6 |
FSUB | FRm, FRn | FRn=FRn-FRm | 1 |
FSUB | DRm, DRn | DRn=DRn-DRm | 6 |
FMUL | FRm, FRn | FRn=FRn×FRm | 1 |
FMUL | DRm, DRn | DRn=DRn×DRm | 6 |
FDIV | FRm, FRn | FRn=FRn-FRm | 10 |
FDIV | DRm, DRn | DRn=DRn-DRm | 23 |
FMAC | FR0,FRm,FRn | FRn=FR0×FRm+FRn | 1 |
11. Funkce s jedním vstupním operandem
Následuje trojice operací, které mají pouze jediný vstupní operand. Dvě z těchto instrukcí jsou velmi jednoduché, protože pouze mění nejvyšší (znaménkový) bit mantisy, takže není překvapující, že tyto instrukce jsou dokončeny v jediném taktu. Ovšem třetí instrukce, která počítá druhou odmocninu, je již nepoměrně složitější, čemuž také odpovídá potřebný počet cyklů na dokončení – 9 hodinových cyklů pro jednoduchou přesnost a dokonce celých 22 hodinových cyklů pro přesnost dvojitou:
Instrukce | Operandy | Prováděná činnost | Počet cyklů |
---|---|---|---|
FABS | FRn | FRn=|FRn| | 1 |
FABS | DRn | DRn=|DRn| | 1 |
FNEG | FRn | FRn=-FRn | 1 |
FNEG | DRn | DRn=-DRn | 1 |
FSQRT | FRn | FRn=√FRn | 9 |
FSQRT | DRn | DRn=√DRn | 22 |
12. Porovnání operandů s nastavením bitu T
Další dvě operace se jmenují FCMP/EQ a FCMP/GT. Tyto operace porovnají obsahy dvou pracovních registrů (ať již FR či DR) a na základě splnění či naopak nesplnění podmínky („rovnost“, „větší než“) nastaví příznakový bit T, s jehož významem jsme se seznámili předminule a minule. Povšimněte si, že v případě porovnání registrů obsahujících hodnoty s dvojitou přesností je instrukce dokončena až za dva takty:
Instrukce | Operandy | Prováděná činnost | Počet cyklů |
---|---|---|---|
FCMP/EQ | FRm, FRn | T=(FRn=FRm) | 1 |
FCMP/EQ | DRm, DRn | T=(DRn=DRm) | 2 |
FCMP/GT | FRm, FRn | T=(FRn>FRm) | 1 |
FCMP/GT | DRm, DRn | T=(DRn>DRm) | 2 |
Poznámka: vzhledem k tomu, že existují podmíněné skoky provedené při T==1 či naopak T==0, nebylo nutné implementovat instrukci FCMP/NE či FCMP/LE. Zbylé dvě možnosti FCMP/LT či FCMP/GE (ostře menší, větší nebo rovno) lze realizovat prohozením obou zdrojových operandů.
13. Načtení konstanty a konverze
Instrukce zmíněné v této kapitole je možné rozdělit do dvou podskupin. V první podskupině se nachází jediné dvě instrukce, které dokážou přímo načíst konstantu do zvoleného pracovního registru matematického koprocesoru. První z těchto instrukcí FLDI0 načte hodnotu odpovídající nule, druhá instrukce FLDI1 načte (normalizovanou) jedničku (což je samozřejmě něco jiného než hodnota 0×00000001). Dalších osm instrukcí pak slouží pro přenos dat mezi speciálním registrem FPUL popsaným výše a zvoleným pracovním registrem. Při přenosu dat je možné provést konverzi, což například umožňuje provádět převody mezi celými 32bitovými čísly a hodnotami typu single a double a naopak. Povšimněte si, že všechny tyto instrukce jsou velmi rychlé, což je v kontrastu s jinými typy matematických koprocesorů, v nichž jsou konverze relativně pomalými operacemi:
Instrukce | Operandy | Prováděná činnost | Počet cyklů |
---|---|---|---|
FLDI0 | FRn | FRn=0×00000000 | 1 |
FLDI1 | FRn | FRn=0×3F800000 | 1 |
FLDS | FRm,FPUL | FPUL=FRm | 1 |
FSTS | FPUL,FRn | FPUL=FRn | 1 |
FLOAT | FPUL,FRn | FRn=(float)FPUL | 1 |
FLOAT | FPUL,DRn | DRn=(double)FPUL | 2 |
FCNVDS | DRm,FPUL | FPUL=(float)DRm (konverze) | 2 |
FCNVSD | FPUL,DRn | DRn=(double)FPUL (konverze) | 2 |
FTRC | FRm | FPUL=(long)FRm (konverze) | 1 |
FTRC | DRm | FPUL=(long)DRm (konverze) | 2 |
14. Přenos FP hodnot mezi matematickým koprocesorem a pamětí
Poslední skupinu instrukcí matematického koprocesoru tvoří instrukce, které se používají buď pro přenos hodnot mezi pracovními registry koprocesoru nebo mezi pracovními registry a operační pamětí. Při přístupu do operační paměti je adresa uložena v libovolném celočíselném pracovním registru, ve dvou registrech R0+Rm či je vypočtena na základě součtu dvanáctibitové konstanty a vybraného pracovního registru. Povšimněte si, že je k dispozici i adresní režim s autoinkrementací či autodekrementací adresy, čehož je možné využít například při zpracování polí:
Instrukce | Operandy | Prováděná činnost | Počet cyklů |
---|---|---|---|
FMOV | FRm, FRn | FRn=FRm | 1 |
FMOV | DRm, DRn | DRn=DRm | 2 |
FMOV.S | @Rm, FRn | FRn=(Rm) | 1 |
FMOV.D | @Rm, DRn | DRn=(Rm) | 2 |
FMOV.S | @(R0, Rm), FRn | FRn=(R0+Rm) | 1 |
FMOV.D | @(R0, Rm), DRn | DRn=(R0+Rm) | 2 |
FMOV.S | @Rm+, FRn | FRn=(Rm), Rm+=4 | 1 |
FMOV.D | @Rm+, DRn | DRn=(Rm), Rm+=8 | 2 |
FMOV.S | @(disp12,Rm),FRn | FRn=(disp×4+Rm) | 1 |
FMOV.D | @(disp12,Rm),DRn | DRn=(disp×8+Rm) | 2 |
FMOV.S | FRm, @Rn | (Rn)=FRm | 1 |
FMOV.D | DRm, @Rn | (Rn)=DRm | 2 |
FMOV.S | FRm, @(R0,Rn) | (R0+Rn)=FRm | 1 |
FMOV.D | DRm, @(R0,Rn) | (R0+Rn)=DRm | 2 |
FMOV.S | FRm, @-Rn | Rn-=4, (Rn)=FRm | 1 |
FMOV.D | DRm, @-Rn | Rn-=8, (Rn)=DRm | 2 |
FMOV.S | FRm, @(disp12,Rn) | (disp×4+Rn)=FRm | 1 |
FMOV.D | DRm, @(disp12,Rn) | (disp×8+Rn)=DRm | 2 |
Poznámka: opět platí, že instrukce pracující s 64bitovými hodnotami jsou zpracovány ve dvojnásobném množství taktů, což souvisí s interní stavbou koprocesoru.
15. Porovnání možností SH2A-FPU s dalšími RISCovými čipy
V následujících čtyřech kapitolách bude uvedeno krátké shrnutí vlastností matematických koprocesorů u dalších typů RISCových procesorů. Dále uvedené údaje, s nimiž jsme se již ostatně v tomto seriálu seznámili, nám pomohou si uvědomit, že u některých mikroprocesorových architektur byl matematický koprocesor velmi důležitou součástí čipu (což například souvisí s tím, že některé čipy byly použity ve výkonných a taktéž patřičně drahých grafických pracovních stanicích), zatímco u dalších architektur je patrné, že tento doplněk nebyl až tak důležitý. Taktéž si povšimněte, jaké operace jsou podporovány – v některých případech se jedná o základní aritmetické operace doplněné například o výpočet druhé odmocniny, u dalších koprocesorů pak nalezneme mnohem větší repertoár instrukcí.
16. SPARC
Architektura SPARC-V8 obsahovala FPU, který pracoval nezávisle na hlavním procesoru. FPU používal 32 registrů, z nichž každý měl šířku 32 bitů, podobně jako registry používané centrální procesorovou jednotkou (V8). V 32bitových registrech se uchovávaly hodnoty ve formátu single specifikovaném v IEEE 754. Pokud rozsah a/nebo přesnost formátu single nedostačovala pro řešení dané úlohy, mohly se vždy dva sousední registry spojit a vytvořit tak 64bitový dvouregistr, v němž byly uloženy hodnoty ve formátu double (současně bylo možné využít šestnáct těchto dvouregistrů), opět podle IEEE 754. Dokonce bylo možné spojit čtyři pracovní registry a vytvořit tak 128bitovou hodnotu ve formátu quad (současně se jich mohlo použít osm).
Instrukční sada FPU byla navržena s ohledem na všeprostupující filozofii RISC, tj. obsahuje pouze základní operace s numerickými hodnotami a navíc poněkud komplexnější, ale o to používanější instrukci pro výpočet druhé odmocniny, nikoli například instrukce sloužící pro výpočty goniometrických či logaritmických funkcí (v tom spočívá poměrně zásadní odlišnost od matematických koprocesorů řady 80×87, které navíc původně pracovaly pouze s osmicí registrů tvořících zásobník). Instrukce používají tříadresový kód, protože šířka instrukčního slova je stále 32 bitů.
Seznam podporovaných instrukcí:
# | Instrukce | Význam |
---|---|---|
1 | FsTOd | konverze single na double |
2 | FsTOq | konverze single na quad |
3 | FdTOs | konverze double na single |
4 | FdTOq | konverze double na quad |
5 | FqTOs | konverze quad na single |
6 | FqTOd | konverze quad na double |
7 | FSQRTs | druhá odmocnina (pro typ single) |
8 | FSQRTd | druhá odmocnina (pro typ double) |
9 | FSQRTq | druhá odmocnina (pro typ quad) |
10 | FADDs | součet single |
11 | FADDd | součet double |
12 | FADDq | součet quad |
13 | FSUBs | rozdíl single |
14 | FSUBd | rozdíl double |
15 | FSUBq | rozdíl quad |
16 | FMULs | součin single |
17 | FMULd | součin double |
18 | FMULq | součin quad |
19 | FsMULd | součin single na double |
20 | FdMULq | součin double na quad |
21 | FDIVs | podíl single |
22 | FDIVd | podíl double |
23 | FDIVq | podíl quad |
24 | FCMPs | porovnání single |
25 | FCMPd | porovnání double |
26 | FCMPq | porovnání quad |
27 | FCMPEs | porovnání single (s vyvoláním výjimky při NaN) |
28 | FCMPEd | porovnání double (s vyvoláním výjimky při NaN) |
29 | FCMPEq | porovnání quad (s vyvoláním výjimky při NaN) |
17. PA-RISC
První verze matematických koprocesorů pro mikroprocesory PA-RISC měly poměrně jednoduchou instrukční sadu obsahující instrukce pro provádění základních aritmetických operací s registry FPR0 až FPR15 a později též s registry FPR16 až FPR31 (všechny tyto registry měly šířku 64 bitů, což je v kontrastu s SH2A-FPU). Kromě čtveřice aritmetických operací součtu, rozdílu, součinu a mocniny měli programátoři k dispozici operaci pro výpočet absolutní hodnoty a taktéž instrukci pro výpočet druhé odmocniny. Kromě toho dokázal matematický koprocesor provádět různé konverze, zejména převody mezi numerickými hodnotami uloženými v systému plovoucí řádové čárky (FP – Floating Point) a hodnotami s pevnou řádovou čárkou (FX – Fixed Point). Všechny tyto operace, včetně operace pro zaokrouhlení výsledku či pro porovnání dvou číselných hodnot (k dispozici bylo všech šest testů na relace mezi dvojicí numerických hodnot), jsou vypsány v následující tabulce:
# | Instrukce | Význam |
---|---|---|
1 | COPR | Identifikace koprocesoru |
2 | FCPY | Kopie hodnoty |
3 | FABS | Výpočet absolutní hodnoty |
4 | FSQRT | Výpočet druhé odmocniny |
5 | FRND | Zaokrouhlení na celé číslo |
6 | FCNVFF | Konverze FP na FP |
7 | FCNVXF | Konverze FX na FP |
8 | FCNVFX | Konverze FP na FX |
9 | FCNVFXT | Konverze FP na FX s explicitním zaokrouhlením směrem k nule |
10 | FCMP | Porovnání dvou hodnot |
11 | FTEST | Test příznakových bitů |
12 | FADD | Součet dvou hodnot |
13 | FSUB | Rozdíl dvou hodnot |
14 | FMPY | Součin dvou hodnot |
15 | FDIV | Podíl dvou hodnot |
18. ARM VFP
Na procesorech ARM se můžeme setkat hned s několika různými typy matematických koprocesorů. První technologií je FPA (Floating Point Architecture). Alternativní a dnes dokonce častěji používanou technologií je VFP, což je zkratka odvozená od Vector Floating Point (jedná se o označení, jež je v současnosti možná již poněkud zavádějící). Technologie VFP byla navržena takovým způsobem, aby ji bylo možné použít v mnoha aplikačních oblastech, například v řídicích jednotkách automobilů, pro zpracování obrazu (konvoluční filtry, rychlá Fourierova transformace, rasterizace a další operace prováděné v tiskových procesorech), při zpracování řeči (kodeky) a taktéž pro provádění různých 3D operací (transformace) – právě v těchto oblastech lze totiž využít práci nikoli pouze se skalárními hodnotami, ale taktéž s vektory o dvou až osmi prvcích. Tyto prvky se však zpracovávají postupně, nikoli paralelně.
Matematické koprocesory VFP obecně obsahují šestnáct pracovních registrů, každý o šířce 64 bitů. Tyto registry lze použít buď pro práci s hodnotami s dvojitou přesností (double) – potom se tyto registry v assembleru označují jmény d0 až d15. Ovšem taktéž je možné libovolný registr rozdělit na dva registry o šířce 32 bitů, z nichž každý dokáže pojmout číselnou hodnotu s jednoduchou přesností (single/float). Díky tomuto rozdělení se počet registrů pro formát single zvětšil na dvojnásobek – tyto registry jsou v assembleru pojmenovány s0 až s31. Podle konvence dodržované jak překladači, tak i v programových knihovnách se při volání subrutin používají registry d0 až d7 pro předávání parametrů subrutině, popř. pro získání návratových hodnot ze subrutiny. Samozřejmě se tyto registry taktéž používají při výpočtech v subrutině. Ostatní registry lze taktéž použít, ovšem jejich hodnota by měla být při návratu ze subrutiny obnovena.
V následující tabulce jsou vypsány základní aritmetické operace:
# | Instrukce | Význam | Prováděný výpočet |
---|---|---|---|
1 | VADD Fd, Fn, Fm | součet | Fd := Fn + Fm |
2 | VSUB Fd, Fn, Fm | rozdíl | Fd := Fn – Fm |
3 | VNEG Fd, Fm | změna znaménka | Fd := – Fm |
4 | VABS Fd, Fm | absolutní hodnota | Fd := abs(Fm) |
5 | VSQRT Fd, Fm | druhá odmocnina | Fd := sqrt(Fm) |
6 | VDIV Fd, Fn, Fm | dělení | Fd := Fn / Fm |
7 | VMUL Fd, Fn, Fm | násobení | Fd := Fn * Fm |
8 | VMLA Fd, Fn, Fm | násobení + akumulace | Fd := Fd + (Fn * Fm) |
9 | VMLS Fd, Fn, Fm | odečtení součinu | Fd := Fd – (Fn * Fm) |
10 | VNMUL Fd, Fn, Fm | násobení + změna znaménka | Fn := – (Fn * Fm) |
11 | VNMLA Fd, Fn, Fm | kombinace VNMUL a VMLA | Fd := – Fd – (Fn * Fm) |
12 | VNMLS Fd, Fn, Fm | kombinace VNMUL a VMLS | Fd := – Fd + (Fn * Fm) |
13 | VCMP Fd, Fm | Porovnání obsahu dvou registrů | Fd – Fm |
14 | VCMP Fd, #0.0 | Porovnání jednoho registru s nulou | Fd – 0.0 |
15 | VCVT{C}.F64.F32 Dd, Sm | Konverze single na double | |
16 | VCVT{C}.F32.F64 Sd, Dm | Konverze double na single | |
17 | VCVT{C}.F32/F64.U32 Fd, Sm | Konverze unsigned integer na float | |
18 | VCVT{C}.F32/F64.S32 Fd, Sm | Konverze signed integer na float | |
19 | VCVT{R}{C}.U32.F32/F64 Sd, Fm | Konverze float na unsigned integer | |
20 | VCVT{R}{C}.S32.F32/F64 Sd, Fm | Konverze float na signed integer | |
21 | VCVT.F32/F64.typ Fd, Fd, #bitů | Konverze fixed-point na float (volitelná pozice tečky) | |
22 | VCVT.typ.F32/F64 Fd, Fd, #bitů | Konverze float na fixed-point (volitelná pozice tečky) | |
23 | VCVTT.F16.F32 Sd,Sm | Konverze single na half (do horních 16 bitů registru) | |
24 | VCVTB.F16.F32 Sd,Sm | Konverze single na half (do spodních 16 bitů registru) | |
25 | VCVTT.F32.F16 Sd,Sm | Konverze half na single | |
26 | VCVTB.F32.F16 Sd,Sm | Konverze half na single | |
27 | VMOV.F32/F64 Fd, Fm | Fd := Fm (prostá kopie) | |
28 | VMOV Sn, Rd | Sn := Rd (Rd = registr ARM procesoru) | |
29 | VMOV Rd, Sn | Rd := Sn (Rd = registr ARM procesoru) | |
30 | VMOV Sn, Sm, Rd, Rn | Sn := Rd, Sm := Rn (kopie dvou registrů) | |
31 | VMOV Rd, Rn, Sn, Sm | Rd := Sn, Rn := Sm (kopie dvou registrů) | |
32 | VMOV Dm, Rd, Rn | Dm[31:0] := Rd, Dm[63:32] := Rn (pro double jsou zapotřebí dva ARM registry) | |
33 | VMOV Rd, Rn, Dm | Rd := Dm[31:0], Rn := Dm[63:32] (pro double jsou zapotřebí dva ARM registry) | |
34 | VMOV Dn[0], Rd | Dn[31:0] := Rd (pouze spodní polovina double) | |
35 | VMOV Rd, Dn[0] | Rd := Dn[31:0] (pouze spodní polovina double) | |
36 | VMOV Dn[1], Rd | Dn[63:32] := Rd (pouze horní polovina double) | |
37 | VMOV Rd, Dn[1] | Rd := Dn[63:32] (pouze horní polovina double) | |
38 | VMRS APSR_nzcv, FPSCR | APSR flags := FPSCR flags (přenos příznaků) |
19. RISC-V
Otevřená specifikace mikroprocesorů RISC-V umožňuje rozšiřovat instrukční sadu pomocí standardních rozšíření, z nichž nás dnes bude zajímat především rozšíření „F“, „D“ a „Q“. První rozšíření se jmenuje „F“, protože specifikuje instrukce s hodnotami typu single/float, tj. s čísly s jednoduchou přesností podle normy IEEE 754–2008 (jedná se o zpřesnění původní slavné normy IEEE 754). Druhé rozšíření se podle očekávání jmenuje „D“, protože předepisuje operace s hodnotami typu double, tj. s čísly s přesností dvojitou. Třetí rozšíření nese název „Q“ a je určeno pro instrukce zpracovávající hodnoty se čtyřnásobnou přesností (quad).
Pro rozšíření „F“ se používá nová sada pracovních registrů. Tyto registry jsou pojmenovány f0 až f31 a každý z těchto registrů má šířku 32 bitů. Navíc se u většiny operací používá i stavový a řídicí registr nazvaný fcrs. K dispozici jsou pseudoinstrukce FRCSR a FSCSR sloužící pro přenos obsahu stavového a řídicího registru do libovolného pracovního registru celočíselné části mikroprocesoru (tedy samozřejmě kromě nulového registru).
Podporované instrukce:
# | Instrukce | Význam |
---|---|---|
1 | FLW | načtení FP hodnoty z paměti (adresa rs+offset) |
2 | FSW | uložení FP hodnoty do paměti (adresa rs+offset) |
3 | FADD.S | součet dvou FP hodnot (tříadresový kód) |
4 | FSUB.S | rozdíl dvou FP hodnot |
5 | FMUL.S | součin dvou FP hodnot |
6 | FDIV.S | podíl dvou FP hodnot |
7 | FMIN.S | vrací menší z obou FP hodnot |
8 | FMAX.S | vrací větší z obou FP hodnot |
9 | FSQRT.S | druhá odmocnina (použity jsou jen dva registry) |
10 | FMADD.S | rs1×rs2+rs3 (multiply-add, čtyřadresový kód!) |
11 | FMSUB.S | rs1×rs2-rs3 |
12 | FNMADD.S | -(rs1×rs2+rs3) |
13 | FNMSUB.S | -(rs1×rs2-rs3) |
14 | FCVT.W.S | převod FP na integer |
15 | FCVT.S.W | převod integer na FP |
16 | FCVT.WU.S | převod FP na unsigned integer |
17 | FCVT.S.WU | převod unsigned integer na FP |
18 | FMV.X.S | pouze přesun mezi integer registrem a FP registrem (nikoli konverze) |
19 | FMV.S.X | pouze přesun mezi FP registrem a integer registrem (nikoli konverze) |
20 | FLT.S | porovnání dvou FP hodnot, zápis 0 či 1 do integer registru |
21 | FLE.S | porovnání dvou FP hodnot, zápis 0 či 1 do integer registru |
22 | FEQ.S | porovnání dvou FP hodnot, zápis 0 či 1 do integer registru |
21 | FCLASS | zjistí „třídu“ FP hodnoty a nastaví deset bitů podle následující tabulky |
22 | FSGNJ.S | kopie z registru src1 do dest, ovšem kromě znaménka; to je přečteno ze src2 |
23 | FSGNJN.S | kopie z registru src1 do dest, ovšem kromě znaménka; to je přečteno ze src2 a znegováno |
24 | FSGNJX.S | kopie z registru src1 do dest, ovšem kromě znaménka; to je získáno ze src1 i src2 s využitím operace XOR |
Další rozšíření základní instrukční sady nese označení „D“. Pokud mikroprocesor s architekturou RISC-V podporuje tuto instrukční sadu, budou použity registry pojmenované f0 až f31, což jsou stejně pojmenované registry, jaké již známe z rozšíření „F“. Je zde ovšem jeden podstatný rozdíl – nyní budou mít registry šířku 64 bitů a nikoli pouze 32 bitů. I instrukční sady „F“ a „D“ jsou si v mnoha ohledech podobné, i když zde narazíme na některé pochopitelné rozdíly:
# | Instrukce | Význam |
---|---|---|
1 | FLD | načtení FP hodnoty z paměti (adresa rs+offset) |
2 | FSD | uložení FP hodnoty do paměti (adresa rs+offset) |
3 | FADD.D | součet dvou FP hodnot (tříadresový kód) |
4 | FSUB.D | rozdíl dvou FP hodnot |
5 | FMUL.D | součin dvou FP hodnot |
6 | FDIV.D | podíl dvou FP hodnot |
7 | FMIN.D | vrací menší z obou FP hodnot |
8 | FMAX.D | vrací větší z obou FP hodnot |
9 | FSQRT.D | druhá odmocnina (použity jsou jen dva registry) |
10 | FCVT.S.D | double na single (provádí se zaokrouhlení) |
11 | FCVT.D.S | single na double (hodnota se nezmění) |
12 | FCVT.W.D | double → 32bit signed integer |
13 | FCVT.L.D | double → 64bit signed integer |
14 | FCVT.WU.D | double → 32bit unsigned integer |
15 | FCVT.LU.D | double → 64bit unsigned integer |
16 | FCVT.D.W | 32bit signed integer → double |
17 | FCVT.D.L | 64bit signed integer → double |
18 | FCVT.D.WU | 32bit unsigned integer → double |
19 | FCVT.D.LU | 64bit unsigned integer → double |
20 | FSGNJ.D | kopie z registru src1 do dest, ovšem kromě znaménka; to je přečteno ze src2 |
21 | FSGNJN.D | kopie z registru src1 do dest, ovšem kromě znaménka; to je přečteno ze src2 a znegováno |
22 | FSGNJX.D | kopie z registru src1 do dest, ovšem kromě znaménka; to je získáno ze src1 i src2 s využitím operace XOR |
23 | FMV.X.D | pouze přesun mezi integer registrem a FP registrem (nikoli konverze) |
24 | FMV.D.X | pouze přesun mezi FP registrem a integer registrem (nikoli konverze) |
Dalším rozšířením instrukčních sad je rozšíření označené písmenem „Q“. To přidává možnost práce s numerickými hodnotami s plovoucí řádovou čárkou se čtyřnásobnou přesností. Formát uložení těchto hodnot je specifikován v již několikrát zmíněné normě IEEE 754–2008:
# | Instrukce | Význam |
---|---|---|
1 | FLQ | načtení FP hodnoty z paměti (adresa rs+offset) |
2 | FSQ | uložení FP hodnoty do paměti (adresa rs+offset) |
3 | FADD.Q | součet dvou FP hodnot (tříadresový kód) |
4 | FSUB.Q | rozdíl dvou FP hodnot |
5 | FMUL.Q | součin dvou FP hodnot |
6 | FDIV.Q | podíl dvou FP hodnot |
7 | FMIN.Q | vrací menší z obou FP hodnot |
8 | FMAX.Q | vrací větší z obou FP hodnot |
9 | FSQRT.Q | druhá odmocnina (použity jsou jen dva registry) |
10 | FCVT.S.Q | quadruple → single |
11 | FCVT.Q.S | single → quadruple |
12 | FCVT.D.Q | quadruple → double |
13 | FCVT.Q.D | double → quadruple |
14 | FSGNJ.Q | kopie z registru src1 do dest, ovšem kromě znaménka; to je přečteno ze src2 |
15 | FSGNJN.Q | kopie z registru src1 do dest, ovšem kromě znaménka; to je přečteno ze src2 a znegováno |
16 | FSGNJX.Q | kopie z registru src1 do dest, ovšem kromě znaménka; to je získáno ze src1 i src2 s využitím operace XOR |
20. Odkazy na Internetu
- SH7201 Group User's Manual: Hardware
https://www.renesas.com/en-us/document/hw-manual?hwLayerShowFlg=true&prdLayerId=2038&layerName=SH7201&coronrService=document-prd-search&hwDocUrl=%2Fen-us%2Fdoc%2Fproducts%2Fmpumcu%2Fdoc%2Fsuperh%2Fr01uh0026ej_sh7201_hm.pdf&hashKey=4d1ed116961466babf99bc7cf1d2cdec - SH7203 Group User's Manual: Hardware
https://www.renesas.com/en-us/document/hw-manual?hwLayerShowFlg=true&prdLayerId=2126&layerName=SH7203&coronrService=document-prd-search&hwDocUrl=%2Fen-us%2Fdoc%2Fproducts%2Fmpumcu%2F001%2Fr01uh0458ej0400_sh7203.pdf&hashKey=68baf3ad6c52e9e2616e44024589e8cf - SuperH RISC engine Family Features
https://www.renesas.com/en-us/products/microcontrollers-microprocessors/superh/superh-features.html - Konkurence procesorů s mikroprogramovým řadičem – RISC
http://www.root.cz/clanky/konkurence-procesoru-s-mikroprogramovym-radicem-architektura-risc/ - Mikroprocesory s architekturou RISC I
http://www.root.cz/clanky/mikroprocesory-s-architekturou-risc-i/ - Procesory RISC v pracovních stanicích a serverech
http://www.root.cz/clanky/procesory-s-architekturou-risc-v-pracovnich-stanicich-a-serverech/ - Procesory RISC v pracovních stanicích a serverech – architektura SPARC V8 a
http://www.root.cz/clanky/procesory-risc-v-pracovnich-stanicich-a-serverech-architektura-sparc-v8-a-v9/ - Procesory RISC v pracovních stanicích a serverech – architektura PA-RISC
http://www.root.cz/clanky/procesory-risc-v-pracovnich-stanicich-a-serverech-architektura-pa-risc/ - Rozšíření instrukční sady procesorových jader s otevřenou architekturou RISC-V
http://www.root.cz/clanky/rozsireni-instrukcni-sady-procesorovych-jader-s-otevrenou-architekturou-risc-v/ - Sega documentation
http://koti.kapsi.fi/~antime/sega/docs.html - 1995 Programming on the Sega Saturn
http://cowboyprogramming.com/2010/06/03/1995-programming-on-the-sega-saturn/ - Sega Myths-Saturn was the most difficult console to program for of 5th Gen
http://forums.sega.com/showthread.php?313485-Sega-Myths-Saturn-was-the-most-difficult-console-to-program-for-of-5th-Gen - SuperH RISC engine Family
http://www.renesas.com/products/mpumcu/superh/index.jsp - Sega Saturn
http://en.wikipedia.org/wiki/Sega_saturn - Fourth-Generation Consoles
http://gaming.wikia.com/wiki/Fourth-Generation_Consoles - Fifth-Generation Consoles
http://gaming.wikia.com/wiki/Fifth-Generation_Consoles - History of video game consoles (fifth generation)
http://en.wikipedia.org/wiki/History_of_video_game_consoles_(fifth_generation) - Sega Mega Drive
http://sega.jp/archive/segahard/md/ - Sega Archives
http://sega.jp/archive/segahard/ - Sega Genesis
http://www.dmoz.org/Games/Video_Games/Console_Platforms/Sega/Genesis/ - The Sega Mega Drive/Genesis
http://www.captainwilliams.co.uk/sega/megadrive/megadrive.php - Sega Master System Museum
http://alexkidd.com/ - Jadeite's Sega Master System Museum
http://rp_gamer.tripod.com/SMS/1.html - Sega Master System (Wikipedia)
http://en.wikipedia.org/wiki/Sega_Master_System - Sega Card (Wikipedia)
http://en.wikipedia.org/wiki/Sega_Card - Sega Master System VDP documentation
http://www.smspower.org/uploads/Development/msvdp-20021112.txt?sid=28c370e1fcac51d5774319979bf96f4c - The16bit Era Of Console Video Games
http://tvtropes.org/pmwiki/pmwiki.php/Main/The16bitEraOfConsoleVideoGames - The Console Wars
http://www.cracked.com/funny-2590-the-console-wars/ - Console Wars
http://tvtropes.org/pmwiki/pmwiki.php/Main/ConsoleWars - Era of the „Bit Wars“
http://www.gtplanet.net/forum/threads/era-of-the-bit-wars.119796/ - Rez Wars: How the Bit Wars never really ended
http://www.ign.com/blogs/beastmastertoad/2013/01/31/rez-wars-how-the-bit-wars-never-really-ended - Which system ended the „Bit Wars“?
http://atariage.com/forums/topic/199163-which-system-ended-the-bit-wars/ - Status Register
https://en.wikipedia.org/wiki/Status_register - 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 - 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 - Berkeley RISC
http://en.wikipedia.org/wiki/Berkeley_RISC - Great moments in microprocessor history
http://www.ibm.com/developerworks/library/pa-microhist.html - 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 - The Evolution of RISC
http://www.ibm.com/developerworks/library/pa-microhist.html#sidebar1 - The VFP architecture
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0056d/Bcfibfha.html - NEON
http://www.arm.com/products/processors/technologies/neon.php - ARM Floating Point Accelerator (ARM FPA)
http://vswww.kaist.ac.kr/ver4.0/index.php/research/past-research/arm-fpa.html