Not only is the Internet dead, it's starting to smell really bad.:2007年12月中旬

2007/12/10(Mon)

[pcc] pcc(1) INCR/DECR issue その1

_Bool type bug( 差分)の話の続きだけど、_Boolだけの問題じゃないのでSubject変更。

pass2は

int x, y, z;
main(void)
{
	/*
	 * | |(B)| |(A+=)| |
	 * |x| = |y| +=  |z|
	 */
	x = y += z;
}
0xbb901294) =, int, 0x0, 0x8081828 … (B)
    0xbb901104) NAME, 0, 0, int, 0x0, 0x8081828
    0xbb901200) +=, int, 0x0, 0x8081828 … (A+=)
        0xbb90122c) NAME, 0, 0, int, 0x0, 0x8081828
        0xbb901080) NAME, 0, 0, int, 0x0, 0x8081828
movl y,%eax
addl z,%eax (A+)
movl %eax,y (A=)
movl %eax,x (B)

とツリーの下の方からアセンブラを生成してくんだけど
現在までのpatchをあてた状態のpccは、INCR/DECRの場合
int x, y, z;
main(void)
{
	/*
	 * | |(C)| |(B+=)| |(A12)|
	 * |x| = |y| +=  |z| ++  |
	 */
        x = y += z++;
}
0xbb9012ec) =, int, 0x0, 0x8081828 … (C)
    0xbb901104) NAME, 0, 0, int, 0x0, 0x8081828
    0xbb9012c0) +=, int, 0x0, 0x8081828 … (B+=)
        0xbb90122c) NAME, 0, 0, int, 0x0, 0x8081828
        0xbb901294) ++, int, 0x0, 0x8081828 … (A12)
            0xbb901080) NAME, 0, 0, int, 0x0, 0x8081828
            0xbb901200) ICON, 1, 0, int, 0x0, 0x8081828
というツリーを吐くので、アセンブラ生成時に
movl y, %eax
movl z, %edx
addl %edx,%eax (B+)
movl %eax,y (B=)
addl $1,%edx (A1)
movl %edx,y (A2)
movl %eax,x (C)
と(B+=)と(A12)の順序を逆にしないとならないんだよな。

INCR/DECRの場合のツリー構造を見直して、逆順が発生しないようにできないもんかね。

Not Allowed NEW in PRE.

週末

体調悪いので修理上がりのカメラで写真撮りにいくのはキャンセルして
おうちでモータウンのCD流しながらベース弾いてた。
Jamerson奏法用にプレベ一本欲しくなってきたぞ。

[OpenBSD] wsconscfg(8)

chvtが無いネタ。
NetBSDやOpenBSDのwscons(4)の場合

$ /usr/sbin/wsconscfg -s 1

とゆーものがありますよ。

と思ったら、OpenBSDのwsconscfg(8)は-sスイッチないのな。

#include <sys/ioctl.h>
#include <fcntl.h>
#include <dev/wscons/wsdisplay_usl_io.h>
int
main(void)
{
    int fd;
    fd = open("/dev/ttyCcfg", O_RDWR, 0);
    ioctl(fd, VT_ACTIVATE, 2);
}

というコードをttyC0から実行すると、ちゃんとttyC1に切り替わるので
wscons(4)自体の機能には不足は無い模様。
NetBSDのwsconscfg.cの最新版をOpenBSDにパチってくればよいかと。

2007/12/11(Tue)

[pcc] pcc(1) INCR/DECR issue その2

昨日の続き。

$ cat >test.c
int x, y, z;
main(void)
{
	x = y += z++;
}
^D

$ cpp test.c | /usr/pkg/libexec/ccom -Zb
...
0xbb9012ec) =, int, REG %eax, SU= 0(@REG,,,,)
    0xbb901104) NAME x, int, REG %eax, SU= 0(@REG,,,,)
    0xbb9012c0) =, int, REG %eax, SU= 0(@REG,,,,)
        0xbb90122c) NAME y, int, REG %eax, SU= 0(@REG,,,,)
        0xbb901344) +, int, REG %eax, SU= 0(@REG,,,,)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 【2】
            0xbb901318) NAME y, int, REG %eax, SU= 0(@REG,,,,)
            0xbb901294) ++, int, REG %eax, SU= 0(@REG,,,,)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 【1】
                0xbb901080) NAME z, int, REG %eax, SU= 0(@REG,,,,)
                0xbb901200) ICON $1, int, REG %eax, SU= 0(@REG,,,,)
...

以前のパッチで

a += b

という式は

a = a + b

のように書き換えられる事に注意。

まずはmip/reader.cのgeninsn()での処理。
INCR/DECRが見つかった場合、すなわち【1】の"++"nodeを処理する個所では

@@ -470,6 +472,8 @@
 		p->n_su = 0;
 		break;
 
+	case INCR:
+	case DECR:
 	case FORCE: /* XXX needed? */
 		geninsn(p->n_left, INREGS);
 		p->n_su = 0; /* su calculations traverse left */

として左node(=z)をレジスタ(=%eax)に割当ててしまえばOK(zの値を1増分するのは後回し)。

そうすると次はツリーの上位、つまり【2】の"+"nodeの処理に移るわけだけど
このPLUSの右ノードには、これまでNAME(変数)やICON(定数)、REG/OREG(レジスタ)のみが
許可されていたので、ここにいきなりINCR(op=59)が飛び込んでくると

test.c, line 4: compiler error: illegal address, op 59, node 0xbb901294

というエラーが出て落ちてしまう。

このエラーの回避は簡単で、arch/i386/local2.cのadrput()で

@@ -723,7 +724,7 @@
 	int r;
 	/* output an address, with offsets, from p */

-	if (p->n_op == FLD)
+	if (p->n_op == FLD || p->n_op == INCR || p->n_op == DECR)
 		p = p->n_left;

 	switch (p->n_op) {

として、PLUSの右ノードがINCR/DECRだった場合には、INCR/DECRの
左ノード(=z)が割当てられてるレジスタ(=%eax)を使うように修正するだけ。

ここまでの修正を取り込んでアセンブラ吐かせてみると

movl z,%eax
movl y,%edx
leal (%edx,%eax),%eax
movl %eax,y
movl %eax,x

うん、あとは【1】でペンディングにしていたzを1増分する処理を
【2】が終わった後に挿入してやればいいだけっぽいですな。

というわけでツリー構成を変更するまでもない気がしてきたぞ。

movl y,%eax
movl z,%edx

とならないとダメだ、ということはgeninsn()でのINCR/DECRの処理は見直しだな。

2007/12/12(Wed)

[pcc] pcc(1) INCR/DECR issue その3

うーむ昨日の修正はあれでOKな気がしてきた。
各ノードに割当てられてるレジスタが今のままじゃダメなんだろう。

0xbb9012ec) =, int, REG %eax, SU= 0(@REG,,,,)
    0xbb901104) NAME x, int, REG %eax, SU= 0(@REG,,,,)
    0xbb9012c0) =, int, REG %eax, SU= 0(@REG,,,,)
        0xbb90122c) NAME y, int, REG %eax, SU= 0(@REG,,,,)
        0xbb901344) +, int, REG %eax, SU= 0(@REG,,,,)
            0xbb901318) NAME y, int, REG %eax, SU= 0(@REG,,,,)
            0xbb901294) ++, int, REG %eax, SU= 0(@REG,,,,)
                0xbb901080) NAME z, int, REG %eax, SU= 0(@REG,,,,)
                0xbb901200) ICON $1, int, REG %eax, SU= 0(@REG,,,,)

↓とでもなればいいのかな。

0xbb9012ec) =, int, REG %edx, SU= 0(@REG,,,,)
    0xbb901104) NAME x, int, REG %edx, SU= 0(@REG,,,,)
    0xbb9012c0) =, int, REG %edx, SU= 0(@REG,,,,)
        0xbb90122c) NAME y, int, REG %edx, SU= 0(@REG,,,,)
        0xbb901344) +, int, REG %edx, SU= 0(@REG,,,,)
            0xbb901318) NAME y, int, REG %edx, SU= 0(@REG,,,,)
            0xbb901294) ++, int, REG %eax, SU= 0(@REG,,,,)
                0xbb901080) NAME z, int, REG %eax, SU= 0(@REG,,,,)
                0xbb901200) ICON $1, int, REG %eax, SU= 0(@REG,,,,)

うへーregs.c読みたくないなぁ。

しかしこの問題まだまだ解決まで時間かかりそうなので

の2つに分割して、前者だけ先にpcc-listに投げちまった方がいいかもな。

2007/12/13(Thu)

localedef

Darwinのlocaledef(adv_cmdsにある)ってperl scriptなのなw
昔FreeBSDのC99 Projectがらみでasmodai氏?がCで書きかけの
localedefをどっかで見た記憶があるんだが、あれどうなったんだろ *1

*1:オマエモナー