Not only is the Internet dead, it's starting to smell really bad.:2010年08月26日分

2010/08/26(Thu)

[pcc] _Bool + INCR/DECR(後置インクリメント/デクリメント命令) 問題

@そもそも

なぜ pcc は INCR/DECR を pass1 で扱っているのかよーわかりませ。
これはUNIX V7のソースに含まれる pcc の過去の歴史がすっぽすっぽ抜け落ちてるので
もうコード読んで恐山気分でイマジンノーヘブンするしかないのですよね…

ありそうな理由としては、pass2 は言語非依存なんで、インクリメント演算のない言語(f77とか)を考慮して
pass1 に移しから(なんというパラノイア)とか、そもそも pass2 で扱うのがめんどくさいので pass1 で消しこんでるとか。
# なんとなく後者の気がするなぁ…

そもそも最適化を考えた場合、x += 1 なんかは i386 なら addl $1,x を incl x にした方が効率いいのですよな。
なんで

  • INCR/DECR は pass2 で処理する為、pass1で何もしない
  • pass2ではインクリメント/デクリメント命令のない cpu は INCR/DECR を PLUSEQ/MINUSEQ に書換する
  • 〃 ある cpu は pass2 の最適化で PLUSEQ/MINUSEQ が 1 の場合、INCR/DECR に書換する

というのがいいような気がする。

ところが現状だと

  • pass1 は INCR/DECR は PLUSEQ/MINUSEQ に書換する
  • 更に PLUSEQ/MINUSEQ は PLUS/MINUS つまり x = x + 1 / x = x - 1 に書換する
  • pass2 での最適化のため PLUS/MINUS が1の場合、SONE ちう bit を立てておく
  • pass2 ではインクリメント/デクリメント命令のない cpu は SONE を無視する
  • 〃 ある cpu は SONE が立ってたらインクリメント/デクリメント命令で最適化を行う

という感じ、関連するtable.cのエントリは↓とか。

[ arch/i386/table.c ]
647 { PLUS,         INAREG|FOREFF,
648         SAREG|SNAME|SOREG,      TWORD|TPOINT,
649         SONE,   TANY,
650                 0,      RLEFT,
651                 "       incl AL\n", },

まぁpass1でやるかpass2でやるかの問題ですが。
これはソース相当読み込まないと答えだせなさそうだなー。

明日くらいに和訳続きと、別途に俺オリジナルでソース解説やりますね。