AVRはハードウェア的に言えば修正ハーバードアーキテクチャを利用した8bit RISCである。特徴的なのは全命令が1cycleで処理できるように工夫されている事と、これに絡んで32個もの汎用レジスタ(8bit)が用意されている事だ。ちなみにアドレスは16bitで、この場合は汎用レジスタを2組使って16bitとしている(これが可能なレジスタが3組ある)。面白いのは、このAVRの設計方針がアセンブラだけでなくC言語でも高速に実行できるように工夫されている点だ。実際のところAtmelはμRISCをそのまま採用した訳ではなく、μRISCをベースにあらためてAVRを開発した形だが、その際にはC言語のコンパイラチームも参加したそうだ。例えば
void routine(void)
{
long n1, n2;
int n3;
...
if (n1 != n2) n3 +=5;
...
}
というCのコード(ここでn1とn2は32bit、n3は16bit幅である)をAVR向けにコンパイラした際のアセンブリコードは
... CP R0,R4 ; n1-n2 (byte 0) CPC R1,R5 ; n1-n2-C (byte 1) CPC R2,R6 ; n1-n2-C (byte 2) CPC R3,R7 ; n1-n2-C (byte 3) BREQ EQUAL ; Branch if equal SUBI R16,LOW(0xfffb) ;n3+5 low byte SBCI R17,HIGH(0xfffb);n3+C high byte EQUAL: ...
となる。n1がR0〜R3、n2がR4〜R7に割り当てられているので、まずは8bit毎に引き算を行い、結果が0(つまり全て一致する)ならEQUALにジャンプする。そうでなければ、n3に5を加算するというのがSUBI/SBCIというわけで、なんというか非常にシンプルであるのがお分かりいただけるかと思う。ここでのポイントは、AVRにはCPC(キャリー付きの比較)、それとゼロフラグ伝搬の機能が付いている事だ。ゼロフラフ伝搬はキャリー伝搬と同じ動作をするので、R0,R4の比較でキャリーが立った場合、それは次のR1,R5の比較に反映されるし、以下R2,R6やR3,R7も同じことである。通常のCISCにはこうした機能が無いので、比較を行ったあとでキャリーフラグをTestする必要があり、ここで余分な命令が必要になる。
最後のSUBI/SBCIもAVRらしい命令である。SUBIは即値減算、SBCIはキャリー付きの即値減算である。ここではn3に5を足す代わりに、n3から5の補数を減算するという形で処理を行っているが、ここでもキャリーの伝搬が行われるので、あとでキャリーの心配をする必要がない。ちなみに同様の加算命令(ADDI/ADCI)は存在しない。というのは補数を使えばSUBI/SBCIで代用できるので、無駄に命令数を増やさないために省かれている。
別の例として
A = ((A.and.84h)+(B.xor.C)).or.80h
を実行する場合のコードをAVRとCISC(恐らく8051)と比較したのがこちらで
AVR code CISC code EOR B,C MOV ACC,C ANDI A,#84h EOR ACC,B ADD A,B MOV TMP,ACC ORI B,#80h MOV ACC,A AND ACC,#84h ADD ACC,TMP OR ACC,#80h MOV A,ACC 8 bytes 12-16 bytes 4 clocks 48-96 clocks
となる。ここでAVR codeの方のA/B/Cというのは適当な汎用レジスタである。要するに汎用レジスタの数がたっぷりあるから、CISCのようにレジスタをいちいち入れ替えしたりする必要が無いし、その分命令数が削減でき、実行速度も上がるというわけだ。加えて1命令が1cycleで処理できるから、絶対性能で言えばCISC比で12倍くらいの性能が発揮できる、という仕組みである。
面白いところではSRAM Direct with Displacement(図3)という機能がある。これはC言語のポインタを簡単に扱えるようにするための仕組みだ。ポインタを使って構造体とかTableとかの参照を行うのに、ポインタ(Y or Z Register)に対するオフセット(0〜63Byte)を1命令の中に収められるというものである。これがCISCだと、オフセットを別のレジスタにセットして、ポインタの値に加算するとかいう手間が掛かる訳だが、そうした手間がいらない訳だ。他にもDirect addressingとかZero flag propagation、Non-destructive comparisonなど、あまり従来の8bit CPUには無い特徴を多く搭載するが、この辺はもともとのμRISCには無かったものであり、それもあってかAVRのアーキテクチャが完成したタイミングで、AtmelはこのAVRのアーキテクチャに関して特許(US5809327A)を取得している。
AVR CPUを搭載する最初の製品である「AT90S8515」(図4)は40pin DIPパッケージで1997年から提供を開始したが、これは8051の40pinと「ほぼ」ピン互換の形になっていた。唯一RESET信号の扱いだけが異なる(8051はActive High Reset、AVRはActive Low Reset)が、それ以外は全く同じなので、8051からの移行も容易だった。このAT90S8515は最大8MHzで動作し、8MIPSの性能を実現した。これは8051で言えば96MHz駆動とかに相当する性能である。
Copyright © ITmedia, Inc. All Rights Reserved.