[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

16.5 アセンブラ出力用の C 言語の文

一個の固定テンプレート文字列だけでは、一つの命令パターンで認識される 全てのケースに対して、正確で効率の良いアセンブラコードを生成するのが 難しいということが良くある。 例えば、オペコードはオペランドの種類に依存することがある。 あるいは、オペランドの組合せが悪いと余分の機械命令が必要なこともある。

そういうときは、出力制御文字列を ‘@’ で開始すると、 一行に一個ずつ置いたテンプレートの列とすることが出来る。 (空行や行頭の空白、タブは無視される。) このテンプレート群は、命令パターン中の制約の選択肢に対応する (see section 複数の制約の選択肢)。 例えば、ターゲットの機種が、アドレスを二つ取る加算命令として、 レジスタに加算する命令 ‘addr’ とレジスタの値をメモリ中に加算する命令 ‘addm’ の二つの命令を持っている場合、以下のようにパターンを書くこと ができる。

 
(define_insn "addsi3"
  [(set (match_operand:SI 0 "general_operand" "=r,m")
        (plus:SI (match_operand:SI 1 "general_operand" "0,0")
                 (match_operand:SI 2 "general_operand" "g,r")))]
  ""
  "@
   addr %2,%0
   addm %2,%0")

出力制御文字列が ‘*’ で始まっている場合は、出力テンプレートそのもの ではなくて、テンプレートを生成する C のコード断片であることを示す。 この C コード断片は、return 文を使って、テンプレート文字列を 返す必要がある。このテンプレートは C の文字列リテラルを使う場合が多い。 文字列リテラルの場合は区切り記号として二重引用符が必要である。 テンプレート文字列に二重引用符を含めるには、‘\’ でエスケープする 必要がある。

オペランドは、operands という、rtx [] 型の配列に 収められている。

即値オペランドが、ある一定の範囲内におさまるかどうかによって、 異なるアセンブラコードの生成方法を選択するのは非常に良く 行なわれる。 しかし、その場合には注意が必要である。 とうのは、INTVAL の結果はホストマシンでの整数になるからである。 ホストマシンの int のビット数が、ターゲットマシンの定数で 使われるモードのビット数より大きければ、INTVAL から得られるビットの いくつかは余計なものである。 正しい結果を得るためには、この余分なビットによる値を注意深く 取り除かなければならない。

サブルーチン output_asm_insn を使って、 あるアセンブラ命令を出力し、その後出力を続けたり、さらに計算を行なうことが 可能である。 この関数は引数を二つ取る。テンプレート文字列とオペランドのベクトル である。ベクトルは operands であっても良いし、 あるいは読者がローカルに宣言し、自分で初期化した、別の rtx の 配列でも良い。

ある insn のパターンで、制約に複数の選択肢がある場合は、 アセンブラコードの見かけはどの選択肢にマッチしたかでほとんど決まる ことが多い。その場合、C のコードでは、変数 which_alternative を テストすることができる。この変数は、実際に条件にあった 選択肢の順番を表す数(先頭の選択肢は 0で、二番目は 1、等々)である。

例えば、ゼロを格納する命令には、二つのオペコードがあるとしよう。 レジスタの場合には‘clrreg’、メモリ位置の場合は ‘clrmem’ である。 以下に、あるパターンでどのように which_alternative を 使って、オペコードを選択するかを示す。

 
(define_insn ""
  [(set (match_operand:SI 0 "general_operand" "=r,m")
        (const_int 0))]
  ""
  "*
  return (which_alternative == 0
          ? \"clrreg %0\" : \"clrmem %0\");
  ")

この例は、生成すべきアセンブラコードが選択肢だけで決まるなら、 出力制御文字を ‘@’ で始めるようにすれば、以下のように指定する こともできる。

 
(define_insn ""
  [(set (match_operand:SI 0 "general_operand" "=r,m")
        (const_int 0))]
  ""
  "@
   clrreg %0
   clrmem %0")

This document was generated using texi2html 1.78.