m68k-*-gcc 関連

最新の gcc のクロスコンパイラを作ろうかと思ったが、やはり面倒そうなのであきらめた。2点ほどおもしろそうなところがあったので記載する。

GO

google が作ったプログラミング言語。登場時は割と話題に上がったがそれっきりというのが私の認識。

gcc のサポート言語ツリーに go がきっちりいるので、下地はかなりしっかりしているようだ。使ったことがないから perl みたいなスクリプト言語だと勝手に思いこんでいて失礼。

ポインタがないので VRAM とか IO の制御は面倒そうなのと、メモリ管理機能が付いているので OS なしでは利用不可能だと思われる。25年前の CPU に最新言語コンパイラが使える可能性はおもしろい。

m68k でのレジスタの取り回し

d0 が関数の戻り値、 d0,d1,A0,A1 が保護せずに自由に使うレジスタ、 d2-d7,A2-A6 が保護するレジスタというのは経験的にわかっていたのだが、どこに定義されているのかわからなかった。

答えはgcc/m68k/m68k.h に書いてあった。

/* 1 for registers that have pervasive standard uses
   and are not available for the register allocator.
   On the m68k, only the stack pointer is such.
   Our fake arg-pointer is obviously fixed as well.  */
#define FIXED_REGISTERS        \
 {/* Data registers.  */       \
  0, 0, 0, 0, 0, 0, 0, 0,      \
                               \
  /* Address registers.  */    \
  0, 0, 0, 0, 0, 0, 0, 1,      \
                               \
  /* Floating point registers  \
     (if available).  */       \
  0, 0, 0, 0, 0, 0, 0, 0,      \
                               \
  /* Arg pointer.  */          \
  1 }

変数に割り当てられないレジスタの定義。 Arg Pointer がよくわからないが、 A7 はスタックポインタなので使わないように定義されている。

/* 1 for registers not available across function calls.
   These must include the FIXED_REGISTERS and also any
   registers that can be used without being saved.
   The latter must include the registers where values are returned
   and the register where structure-value addresses are passed.
   Aside from that, you can include as many other registers as you like.  */
#define CALL_USED_REGISTERS     \
 {/* Data registers.  */        \
  1, 1, 0, 0, 0, 0, 0, 0,       \
                                \
  /* Address registers.  */     \
  1, 1, 0, 0, 0, 0, 0, 1,       \
                                \
  /* Floating point registers   \
     (if available).  */        \
  1, 1, 0, 0, 0, 0, 0, 0,       \
                                \
  /* Arg pointer.  */           \
  1 }

0 が関数内部で使用する場合に保護するレジスタとなっている。d0,d1,A0,A1 は保護せずに自由に使うレジスタで、A7 はスタックポインタなので使ってはいけない。

#define REG_ALLOC_ORDER		\
{ /* d0/d1/a0/a1 */		\
  0, 1, 8, 9,			\
  /* d2-d7 */			\
  2, 3, 4, 5, 6, 7,		\
  /* a2-a7/arg */		\
  10, 11, 12, 13, 14, 15, 24,	\
  /* fp0-fp7 */			\
  16, 17, 18, 19, 20, 21, 22, 23\
}

あまり重要ではないが、レジスタの割り当ての優先度。

これらの値を変更すればレジスタの割り当てを変更できるようだが、この設定を変えるのと既存のオブジェクトと互換性がなくなるし、パフォーマンスの向上はあまり期待できない気がするのでやらないほうがいいだろう。