The Man Who Fell From The Wrong Side Of The Sky:2007年10月分

2007/10/4(Thu)

[OpenBSD] pcc(1) _Bool bug その3

わざわざpass1でごにょごにょしようとしてる
今のコードは筋が悪い対応で、ちゃんとやるなら
pass2に全部お任せした方がいいよな希ガス吸ってきた。

diff -urBw pcc-0.9.8.orig/cc/ccom/pass1.h pcc-0.9.8/cc/ccom/pass1.h
--- pcc-0.9.8.orig/cc/ccom/pass1.h	2007-09-09 19:01:01.000000000 +0900
+++ pcc-0.9.8/cc/ccom/pass1.h	2007-10-05 02:25:58.000000000 +0900
@@ -385,7 +385,6 @@
  * The following types are only used in pass1.
  */
 #define SIGNED		(MAXTYPES+1)
-#define BOOL		(MAXTYPES+2)
 
 
 #define coptype(o)	(cdope(o)&TYFLG)
diff -urBw pcc-0.9.8.orig/cc/ccom/scan.l pcc-0.9.8/cc/ccom/scan.l
--- pcc-0.9.8.orig/cc/ccom/scan.l	2007-08-20 04:24:51.000000000 +0900
+++ pcc-0.9.8/cc/ccom/scan.l	2007-10-05 02:14:39.000000000 +0900
@@ -88,7 +88,7 @@
 "asm"			{ return(C_ASM); }
 "auto"			{ yylval.intval = AUTO; return(C_CLASS); }
 "_Bool"			{ yylval.nodep = mkty((TWORD)BOOL, 0, MKSUE(BOOL));
-				return(C_TYPE); }
+			  notype=1; return(C_TYPE); }
 "break"			{ return(C_BREAK); }
 "case"			{ return(C_CASE); }
 "char"			{ yylval.nodep = mkty((TWORD)CHAR, 0, MKSUE(CHAR));
diff -urBw pcc-0.9.8.orig/cc/ccom/trees.c pcc-0.9.8/cc/ccom/trees.c
--- pcc-0.9.8.orig/cc/ccom/trees.c	2007-09-10 02:42:33.000000000 +0900
+++ pcc-0.9.8/cc/ccom/trees.c	2007-10-05 02:49:18.000000000 +0900
@@ -2213,27 +2213,6 @@
 	/* Convert "PTR undef" (void *) to "PTR uchar" */
 	if (BTYPE(p->n_type) == VOID)
 		p->n_type = (p->n_type & ~BTMASK) | UCHAR;
-	if (BTYPE(p->n_type) == BOOL) {
-		if (p->n_op == SCONV && p->n_type == BOOL) {
-			/* create a jump and a set */
-			NODE *q, *r, *s;
-			int l, val;
-
-			q = talloc();
-			*q = *p;
-			q->n_type = BOOL_TYPE;
-			r = tempnode(0, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE));
-			val = r->n_lval;
-			s = tempnode(val, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE));
-			*p = *s;
-			q = buildtree(ASSIGN, r, q);
-			cbranch(buildtree(EQ, q, bcon(0)), bcon(l = getlab()));
-			ecode(buildtree(ASSIGN, s, bcon(1)));
-			plabel(l);
-		} else
-			p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE;
-	}
-		
 }
 
 void
diff -urBw pcc-0.9.8.orig/mip/manifest.h pcc-0.9.8/mip/manifest.h
--- pcc-0.9.8.orig/mip/manifest.h	2007-08-20 04:21:14.000000000 +0900
+++ pcc-0.9.8/mip/manifest.h	2007-10-05 02:24:58.000000000 +0900
@@ -78,8 +78,9 @@
 #define	ENUMTY		17
 #define	MOETY		18	/* member of enum */
 #define	VOID		19
+#define	BOOL		20
 
-#define	MAXTYPES	19	/* highest type+1 to be used by lang code */
+#define	MAXTYPES	20	/* highest type+1 to be used by lang code */
 /*
  * Various flags
  */
diff -urBw pcc-0.9.8.orig/mip/match.c pcc-0.9.8/mip/match.c
--- pcc-0.9.8.orig/mip/match.c	2006-07-30 18:32:15.000000000 +0900
+++ pcc-0.9.8/mip/match.c	2007-10-05 03:49:57.000000000 +0900
@@ -230,6 +230,8 @@
 		return(0);
 
 	switch (t) {
+	case BOOL:
+		return( tword & TBOOL );
 	case CHAR:
 		return( tword & TCHAR );
 	case SHORT:
@@ -384,8 +386,8 @@
 
 static char *tarr[] = {
 	"CHAR", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "POINT", "UCHAR",
-	"USHORT", "UINT", "ULONG", "PTRTO", "ANY", "STRUCT", "LONGLONG",
-	"ULONGLONG",
+	"USHORT", "UNSIGNED", "ULONG", "PTRTO", "ANY", "STRUCT", "LONGLONG",
+	"ULONGLONG", "LDOUBLE", "FTN", "BOOL",
 };
 
 void
@@ -393,7 +395,7 @@
 {
 	int i, gone = 0;
 
-	for (i = 0; i < 16; i++)
+	for (i = 0; i < 19; i++)
 		if ((t >> i) & 1) {
 			if (gone) putchar('|');
 			gone++;
diff -urBw pcc-0.9.8.orig/mip/pass2.h pcc-0.9.8/mip/pass2.h
--- pcc-0.9.8.orig/mip/pass2.h	2006-12-22 15:23:09.000000000 +0900
+++ pcc-0.9.8/mip/pass2.h	2007-10-05 02:45:32.000000000 +0900
@@ -127,6 +127,7 @@
 #define	TULONGLONG	0100000	/* unsigned long long */
 #define	TLDOUBLE	0200000	/* long double; exceeds 16 bit */
 #define	TFTN		0400000	/* function pointer; exceeds 16 bit */
+#define	TBOOL		01000000 /* _Bool */
 
 /* reclamation cookies */
 #define RNULL		0	/* clobber result */

こんな感じにしてpass2にまでBOOLを渡してしまって、
あとはcc/ccom/external.cとarch/x86/table.cを書けばいいんだろな...
ってそれが一番メンドイのだけども。

2007/10/5(Fri)

最近買ったもの

RSS

うーん某RSSリーダーだと記事にちょいと追記とか訂正とかしても反映されないのね。
うちは手抜きなのでpubDateに日記の日付だけしか吐いてないので
記事の新旧をpubDateだけで判断してるRSSリーダーだと
古いキャッシュのままになるってわけか。

2007/10/7(Sun)

[OpenBSD] pcc(1) _Bool bug その4

とりあえず簡単なとこだけtable.cいじってみて挙動の確認。
ひとまず_Boolと整数型との=(ASSIGN)の一部が動くようにしてみた。

diff -urBw pcc-0.9.8.orig/arch/x86/local.c pcc-0.9.8/arch/x86/local.c
--- pcc-0.9.8.orig/arch/x86/local.c	2007-09-09 19:02:59.000000000 +0900
+++ pcc-0.9.8/arch/x86/local.c	2007-10-06 21:37:05.000000000 +0900
@@ -289,8 +289,7 @@
 		p->n_op = ASSIGN;
 		p->n_right = p->n_left;
 		p->n_left = block(REG, NIL, NIL, p->n_type, 0, MKSUE(INT));
-		p->n_left->n_rval = p->n_left->n_type == BOOL ? 
-		    RETREG(CHAR) : RETREG(p->n_type);
+		p->n_left->n_rval = RETREG(p->n_type);
 		break;
 
 	case LS:
diff -urBw pcc-0.9.8.orig/arch/x86/local2.c pcc-0.9.8/arch/x86/local2.c
--- pcc-0.9.8.orig/arch/x86/local2.c	2007-09-09 19:02:59.000000000 +0900
+++ pcc-0.9.8/arch/x86/local2.c	2007-10-06 21:38:23.000000000 +0900
@@ -396,7 +396,7 @@
 {
 	TWORD t = p->n_type;
 
-	if (t < LONGLONG || t == FLOAT || t > BTMASK)
+	if (t < LONGLONG || t == FLOAT || t == BOOL || t > BTMASK)
 		return 4;
 	if (t == LONGLONG || t == ULONGLONG || t == DOUBLE)
 		return 8;
@@ -516,6 +516,7 @@
 		pr = DECRA(p->n_reg, 0);
 		lr = p->n_left->n_rval;
 		switch (p->n_type) {
+		case BOOL:
 		case CHAR:
 		case UCHAR:
 			if (rnames[pr][2] == 'l' && rnames[lr][2] == 'x' &&
diff -urBw pcc-0.9.8.orig/arch/x86/table.c pcc-0.9.8/arch/x86/table.c
--- pcc-0.9.8.orig/arch/x86/table.c	2007-09-09 19:02:59.000000000 +0900
+++ pcc-0.9.8/arch/x86/table.c	2007-10-07 19:09:33.000000000 +0900
@@ -101,6 +101,14 @@
 
 /* char to something */
 
+/* convert (u)char to _Bool. */
+{ SCONV,	INCH,
+	SAREG,	TCHAR|TUCHAR,
+	SANY,	TBOOL,
+		NBREG|NBSL,	RESC1,
+		"	testb AL,AL\n"
+		"	setne A1\n", },
+
 /* convert char to (unsigned) short. */
 { SCONV,	ININT,
 	SBREG|SOREG|SNAME,	TCHAR,
@@ -110,7 +118,7 @@
 
 /* convert unsigned char to (u)short. */
 { SCONV,	ININT,
-	SHCH|SOREG|SNAME,	TUCHAR,
+	SHCH|SOREG|SNAME,	TBOOL|TUCHAR,
 	SAREG,	TSHORT|TUSHORT,
 		NASL|NAREG,	RESC1,
 		"	movzbw AL,A1\n", },
@@ -124,7 +132,7 @@
 
 /* convert unsigned char to (u)int. */
 { SCONV,	ININT,
-	SHCH|SOREG|SNAME,	TUCHAR,
+	SHCH|SOREG|SNAME,	TBOOL|TUCHAR,
 	SAREG,	TWORD,
 		NASL|NAREG,	RESC1,
 		"	movzbl AL,A1\n", },
@@ -138,7 +146,7 @@
 
 /* convert unsigned char to (u)long long */
 { SCONV,	INLL,
-	SHCH|SOREG|SNAME,	TUCHAR,
+	SHCH|SOREG|SNAME,	TBOOL|TUCHAR,
 	SANY,			TLL,
 		NCREG|NCSL,	RESC1,
 		"	movzbl AL,A1\n	xorl U1,U1\n", },
@@ -153,7 +161,7 @@
 
 /* convert (u)char (in register) to double XXX - use NTEMP */
 { SCONV,	INFL,
-	SHCH|SOREG|SNAME,	TUCHAR,
+	SHCH|SOREG|SNAME,	TBOOL|TUCHAR,
 	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
 		NAREG|NASL|NDREG,	RESC2,
 		"	movzbl AL,A1\n	pushl A1\n"
@@ -161,6 +169,14 @@
 
 /* short to something */
 
+/* convert (u)short to _Bool */
+{ SCONV,	INCH,
+	SAREG,	TSHORT|TUSHORT,
+	SANY,	TBOOL,
+		NBREG|NBSL,	RESC1,
+		"	testw AL,AL\n"
+		"	setne A1\n", },
+
 /* convert short (in memory) to char */
 { SCONV,	INCH,
 	SNAME|SOREG,	TSHORT|TUSHORT,
@@ -227,6 +243,14 @@
 
 /* int to something */
 
+/* convert int to _Bool */
+{ SCONV,	INCH,
+	SAREG,	TWORD|TPOINT,
+	SANY,	TBOOL,
+		NBREG|NBSL,	RESC1,
+		"	testl AL,AL\n"
+		"	setne A1\n", },
+
 /* convert int to char. This is done when register is loaded */
 { SCONV,	INCH,
 	SAREG,	TWORD,
@@ -820,13 +844,13 @@
 		"	movw AR,AL\n", },
 
 { ASSIGN,	FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+	SHCH|SNAME|SOREG,	TBOOL|TCHAR|TUCHAR,
 	SCON,		TANY,
 		0,	0,
 		"	movb AR,AL\n", },
 
 { ASSIGN,	FOREFF|INCH,
-	SHCH,		TCHAR|TUCHAR,
+	SHCH,		TBOOL|TCHAR|TUCHAR,
 	SCON,		TANY,
 		0,	RDEST,
 		"	movb AR,AL\n", },
@@ -856,8 +880,8 @@
 		"	movw AR,AL\n", },
 
 { ASSIGN,	FOREFF|INCH,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-	SHCH,		TCHAR|TUCHAR|TWORD,
+	SHCH|SNAME|SOREG,	TBOOL|TCHAR|TUCHAR,
+	SHCH,		TBOOL|TCHAR|TUCHAR/*???|TWORD*/,
 		0,	RDEST,
 		"	movb AR,AL\n", },
 
@@ -1364,8 +1388,8 @@
 		"	pushl AL\n", },
 
 { FUNARG,	FOREFF,
-	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
-	SANY,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+	SCON,	TWORD|TSHORT|TUSHORT|TBOOL|TCHAR|TUCHAR,
+	SANY,	TWORD|TSHORT|TUSHORT|TBOOL|TCHAR|TUCHAR,
 		0,	RNULL,
 		"	pushl AL\n", },
 
@@ -1388,8 +1412,8 @@
 		"	movsbl AL,A1\n	pushl A1\n", },
 
 { FUNARG,	FOREFF,
-	SHCH|SNAME|SOREG,	TUCHAR,
-	SANY,	TUCHAR,
+	SHCH|SNAME|SOREG,	TBOOL|TUCHAR,
+	SANY,	TBOOL|TUCHAR,
 		NAREG,	0,
 		"	movzbl AL,A1\n	pushl A1\n", },
 
diff -urBw pcc-0.9.8.orig/cc/ccom/pass1.h pcc-0.9.8/cc/ccom/pass1.h
--- pcc-0.9.8.orig/cc/ccom/pass1.h	2007-09-09 19:01:01.000000000 +0900
+++ pcc-0.9.8/cc/ccom/pass1.h	2007-10-06 21:39:04.000000000 +0900
@@ -385,7 +385,6 @@
  * The following types are only used in pass1.
  */
 #define SIGNED		(MAXTYPES+1)
-#define BOOL		(MAXTYPES+2)
 
 
 #define coptype(o)	(cdope(o)&TYFLG)
diff -urBw pcc-0.9.8.orig/cc/ccom/scan.l pcc-0.9.8/cc/ccom/scan.l
--- pcc-0.9.8.orig/cc/ccom/scan.l	2007-08-20 04:24:51.000000000 +0900
+++ pcc-0.9.8/cc/ccom/scan.l	2007-10-06 21:39:31.000000000 +0900
@@ -88,7 +88,7 @@
 "asm"			{ return(C_ASM); }
 "auto"			{ yylval.intval = AUTO; return(C_CLASS); }
 "_Bool"			{ yylval.nodep = mkty((TWORD)BOOL, 0, MKSUE(BOOL));
-				return(C_TYPE); }
+			  notype=1; return(C_TYPE); }
 "break"			{ return(C_BREAK); }
 "case"			{ return(C_CASE); }
 "char"			{ yylval.nodep = mkty((TWORD)CHAR, 0, MKSUE(CHAR));
diff -urBw pcc-0.9.8.orig/cc/ccom/trees.c pcc-0.9.8/cc/ccom/trees.c
--- pcc-0.9.8.orig/cc/ccom/trees.c	2007-09-10 02:42:33.000000000 +0900
+++ pcc-0.9.8/cc/ccom/trees.c	2007-10-06 21:39:53.000000000 +0900
@@ -2213,27 +2213,6 @@
 	/* Convert "PTR undef" (void *) to "PTR uchar" */
 	if (BTYPE(p->n_type) == VOID)
 		p->n_type = (p->n_type & ~BTMASK) | UCHAR;
-	if (BTYPE(p->n_type) == BOOL) {
-		if (p->n_op == SCONV && p->n_type == BOOL) {
-			/* create a jump and a set */
-			NODE *q, *r, *s;
-			int l, val;
-
-			q = talloc();
-			*q = *p;
-			q->n_type = BOOL_TYPE;
-			r = tempnode(0, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE));
-			val = r->n_lval;
-			s = tempnode(val, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE));
-			*p = *s;
-			q = buildtree(ASSIGN, r, q);
-			cbranch(buildtree(EQ, q, bcon(0)), bcon(l = getlab()));
-			ecode(buildtree(ASSIGN, s, bcon(1)));
-			plabel(l);
-		} else
-			p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE;
-	}
-		
 }
 
 void
diff -urBw pcc-0.9.8.orig/mip/common.c pcc-0.9.8/mip/common.c
--- pcc-0.9.8.orig/mip/common.c	2007-09-10 02:42:33.000000000 +0900
+++ pcc-0.9.8/mip/common.c	2007-10-06 21:40:38.000000000 +0900
@@ -408,8 +408,8 @@
 		"enumty",
 		"moety",
 		"void",
+		"bool",
 		"signed", /* pass1 */
-		"bool", /* pass1 */
 		"?", "?"
 		};
 
diff -urBw pcc-0.9.8.orig/mip/manifest.h pcc-0.9.8/mip/manifest.h
--- pcc-0.9.8.orig/mip/manifest.h	2007-08-20 04:21:14.000000000 +0900
+++ pcc-0.9.8/mip/manifest.h	2007-10-06 21:41:24.000000000 +0900
@@ -78,8 +78,9 @@
 #define	ENUMTY		17
 #define	MOETY		18	/* member of enum */
 #define	VOID		19
+#define BOOL		20
 
-#define	MAXTYPES	19	/* highest type+1 to be used by lang code */
+#define	MAXTYPES	20	/* highest type+1 to be used by lang code */
 /*
  * Various flags
  */
diff -urBw pcc-0.9.8.orig/mip/match.c pcc-0.9.8/mip/match.c
--- pcc-0.9.8.orig/mip/match.c	2006-07-30 18:32:15.000000000 +0900
+++ pcc-0.9.8/mip/match.c	2007-10-06 21:42:50.000000000 +0900
@@ -230,6 +230,8 @@
 		return(0);
 
 	switch (t) {
+	case BOOL:
+		return( tword & TBOOL );
 	case CHAR:
 		return( tword & TCHAR );
 	case SHORT:
@@ -384,8 +386,8 @@
 
 static char *tarr[] = {
 	"CHAR", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "POINT", "UCHAR",
-	"USHORT", "UINT", "ULONG", "PTRTO", "ANY", "STRUCT", "LONGLONG",
-	"ULONGLONG",
+	"USHORT", "UNSIGNED", "ULONG", "PTRTO", "ANY", "STRUCT", "LONGLONG",
+	"ULONGLONG", "LDOUBLE", "FTN", "BOOL",
 };
 
 void
@@ -393,7 +395,7 @@
 {
 	int i, gone = 0;
 
-	for (i = 0; i < 16; i++)
+	for (i = 0; i < 19; i++)
 		if ((t >> i) & 1) {
 			if (gone) putchar('|');
 			gone++;
diff -urBw pcc-0.9.8.orig/mip/pass2.h pcc-0.9.8/mip/pass2.h
--- pcc-0.9.8.orig/mip/pass2.h	2006-12-22 15:23:09.000000000 +0900
+++ pcc-0.9.8/mip/pass2.h	2007-10-06 21:43:33.000000000 +0900
@@ -127,6 +127,7 @@
 #define	TULONGLONG	0100000	/* unsigned long long */
 #define	TLDOUBLE	0200000	/* long double; exceeds 16 bit */
 #define	TFTN		0400000	/* function pointer; exceeds 16 bit */
+#define TBOOL		01000000 /* C99: _Bool */
 
 /* reclamation cookies */
 #define RNULL		0	/* clobber result */


これで正しいかどーかは正直謎。

そもそもlong longの実装もちと間違ってる希ガス。

long long x;
char y;
y = x;

のような場合、OPLTYPEが呼ばれて型変換するんだがlong longだけ呼ばれない。
このフックがないとlong long -> _Boolでも非常に困る。
なんつーかいろいろと怪し杉。

連休

天気が微妙でこないだ買った50mm/F1.4も不発でござい。
今年は紅葉遅いみたいだし、しばらく生頃しか。

2007/10/9(Tue)

[OpenBSD] pcc(1) _Bool type bug その5

table.cいじり遅々として進まん。
現状で判ってることをぼちぼちメモ残しておこう。

char x;
long long int y;
x = (char)y;

上記のCコードをassemblerにすると

movl y,%eax
movl y+4,%edx
movb %al,x

となる。pcc(1)は上記のassemblerを吐くのに

OPLTYPE
	movl UL,U1
	movl AL,A1
SCONV
	/* nothing to do */
ASSIGN
	movb %AR,AL

以上3つのopcodeが使われる。
しかーし実際のところ最適化してしまえば

movb y,%al
movb %al,x

でおkなので、pcc(3)はさっさとOPLTYPEを削除?して

SCONV
	movb AL,A1
ASSIGN
	movb %AR,AL

の2つのみを使う。

てなわけで同じ型同士でのASSIGNの場合以外はOPLTYPEは呼ばれないっぽ。

int x, y;
x = y
OPLTYPE
	movl AL,A1
ASSIGN
	movl AR,AL

ところが_Boolの実装をする場合には

_Bool x;
long long int y;
x = (_Bool)y;

のCコードは

movl y,%edx
movl y+4,%eax
orl %edx,%eax
testl %eax,%eax
setne %al
movb %al,x

というassemblerに展開されるので

OPLTYPE
	movl AL,A1
	movl UL,U1
SCONV
	orl UR,AR
	testl AR,AR
	setne A1
ASSIGN
	movb AR,AL

と、OPLTYPEが最適化されて消えてしまうとちと困るのね。
無理矢理SCONVで処理しようとするとレジスタ名称が正しく取得できなさげ。

つーわけで週末までの宿題。

2007/10/10(Wed)

[OpenBSD] pcc(1) _Bool type bug その6

そもそもpass1の時点で何かおかすい。

cat >test.c
#include <stdbool.h>
_Bool x;
char y;
main() {
	x = y;
}
^D
$ cpp test.c | /usr/pkg/libexec/ccom -Xe -Ze | less
        .data
        .text
0x8076068) =, bool, 0x0, 0x80747f0
    0x8076104) NAME, 0, 134701360, bool, 0x0, 0x80747f0
    0x80761b8) NAME, 0, 134701432, bool, 0x0, 0x8074718
Entering pass2
PROLOG (0x808600c): main (local) regs ffffffff autos -1 mintemp 100 minlbl 13
DEFLAB (0x8086050): .L13
NODE (0x8086064):
0x8076068) =, bool, REG %eax, SU= 0(@REG,,,,)
    0x8076104) NAME x, bool, REG %eax, SU= 0(@REG,,,,)
    0x80761b8) NAME y, bool, REG %eax, SU= 0(@REG,,,,)
(以下略)

すでにpass1の最後でyの型がcharからboolに化けてるげ。

  1. arch/x86/local.c
    177                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
    178                     btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
    179                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
    180                             l->n_type != FLOAT && l->n_type != DOUBLE &&
    181                             l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
    182                                 if (l->n_op == NAME || l->n_op == UMUL ||
    183                                     l->n_op == TEMP) {
    184                                         l->n_type = p->n_type;
    185                                         nfree(p);
    186                                         return l;
    
  2. cc/ccom/main.c
    257         btdims[BOOL].suesize = SZBOOL;
    258         btdims[CHAR].suesize = SZCHAR;
    
  3. arch/x86/machdef.h
    44 #define SZCHAR          8
    45 #define SZBOOL          8
    

1.のとこでbit sizeが一緒の場合、最適化が行われSCONVは消されるってことだ。
2.と3.を見て判る通り、boolとcharのサイズが一緒なので(以下省略)なのね。
とりあえずこれでいいかは判らんけどclocal()に暫定patch適用。

--- pcc-0.9.8.orig/arch/x86/local.c     2007-09-09 19:02:59.000000000 +0900
+++ pcc-0.9.8/arch/x86/local.c  2007-10-09 21:29:24.000000000 +0900
@@ -176,7 +176,7 @@

                if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
                    btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
-                       if (p->n_type != FLOAT && p->n_type != DOUBLE &&
+                       if (p->n_type != BOOL && p->n_type != FLOAT && p->n_type != DOUBLE &&
                            l->n_type != FLOAT && l->n_type != DOUBLE &&
                            l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
                                if (l->n_op == NAME || l->n_op == UMUL ||

でもこれ型変換のルールで

unsigned char x;
char y;
x = y;

の場合はclocal()呼ばれるけど

unsigned char x;
char y;
y = x;

ではそもそも呼ばれないので、もっと別の場所で対処する必要があるげ。
例えばarch/x86/tree.cのtymatch()あたりとかmoditype()が返す値とかが怪しげなキモス。

2007/10/11(Thu)

[OpenBSD] pcc(1) _Bool type bug その7

とりあえずASSIGNのlong long問題はおいといてPLUSに進んでみる。

前置++の場合

char x, y;
x = ++y;

とは

OPLTYPE
	movb y,%al
PLUS
	incb %al
ASSIGN-1
	movb %al,y
ASSIGN-2
	movb %al,x

となるので、_Boolの実装には

{ PLUS,		INCH,
	SHCH|SNAME|SOREG,	TBOOL,
	SONE,	TANY,
		0,	RLEFT,
		"	movb $1,AL\n", },
{ ASSIGN,	FOREFF|INCH,
	SHCH|SOREG|SNAME,	TBOOL,
	SHCH,	TBOOL,
		0,	RDEST,
		"	movb AR,AL\n", },

をtable.cに追加すればよい、これは特に問題ない。

それでは後置++の場合。

char x, y;
x = y++;

としたとき、今の実装は

OPLTYPE
	movb y,%al
PLUS
	incl %al
ASSIGN-1
	movb %al,y
OPSIMP
	subb $1,%al
ASSIGN-2
	movb %al,x

という動作をしてくれやがる、つまり

char x, y;
++y;
x = y - 1;

と等価なわけ。

なんでこんなアセンブラ吐くのかってーと

int y;
y++;

となった場合、yの元の値を保存する必要は無いので

int y;
++y;

と等価であるので

OPLTYPE
	movb y,%al
PLUS
	incl %al
ASSIGN
	movb %al,y

とOPSIMP->ASSIGN-2を消すだけで最適化になるからだろうと予想。

OPLTYPE-1
	movb y,%al
OPLTYPE-2
	movb y,%ah
PLUS
	incl %al
ASSIGN-1
	movb %al,y
ASSIGN-2
	movb %ah,x

として最適化時にはOPLTYPE-2とASSIGN-2を消す方がいいと思うんだけど
そんなん無理らめぇな実装なのかもしれず。

_Boolの場合、上記の挙動だと

OPLTYPE
	movb y,%al
PLUS
	movb $1,%al
ASSIGN-1
	movb %al,y
OPSIMP
	subb $1,%al
ASSIGN-2
	movb %al,x

となるので、xは常に0になってしまいダメぽな予感。
ここはやはり

OPLTYPE-1
	movb y,%al
OPLTYPE-2
	movb y,%ah
PLUS
	movb $1,%al
ASSIGN-1
	movb %al,y
ASSIGN-2
	movb %ah,x

として元の値をレジスタに保存しといてくれんと困るんだがなぁ。

実際にはどういう動きをするか、空のOPSIMPをtable.cに追加してみる。

{ OPSIMP,       INCH|FOREFF,
	SHCH,	TBOOL,
	SHCH|SNAME|SOREG,	TBOOL,
		"/**/", },

んで出力結果。

OPLTYPE-1
	movb $1,%ah
OPLTYPE-2
	movb y,%al
PLUS
	movb $1,%al
ASSIGN-1
        movb %al,y
OPSIMP
	/**/
ASSIGN-1
        movb %al,x

おー予想外の動き、何故OPLTYPE-1が出力されんのかさっぱり判らん。
この定数$1ってどっから拾ってきたん?でも

OPLTYPE-1
	movb y,%ah
	^^^^^^^^^^
OPLTYPE-2
	movb y,%al
PLUS
	movb $1,%al
ASSIGN-1
	movb %al,y
OPSIMP
	movb %ah,%al
	^^^^^^^^^^^^
ASSIGN-1
	movb %al,x

という風に変えられればなんとか実装できそうな気ガス吸ってきた。

2007/10/12(Fri)

[OpenBSD] pcc(1) _Bool type bug その8

mip/reader.cのgencode()を監視しようとccomに-ZcオプションつけたらSIGSEGV喰らった。
Nodeのn_left/n_rightが共用体だから(以下略)、本題はそこじゃないので
mip/reader.cのgencode()に簡単なデバグプリント入れて実験。

$ cat > test.c
#include <stdbool.h>
_Bool x, y;
main()
{
	x = y++;
}
^D
$ cpp test.c | /usr/pkg/libexec/ccom
	.data
	.text
	.globl main
	.align 4
main:
	pushl %ebp
	movl %esp,%ebp
[gencode] type:6, op: 49
^^^^^^^^^^^^^^^^^^^^^^^^
[gencode] type:6, op: 6
^^^^^^^^^^^^^^^^^^^^^^^^
[gencode] type:6, op: 6
^^^^^^^^^^^^^^^^^^^^^^^^
	movl %ebx,%edx
^^^^^^^^^^^^^^^^^^^^^^^^
.L13:
[gencode] type:20, op: 49
^^^^^^^^^^^^^^^^^^^^^^^^^
[gencode] type:20, op: 11
^^^^^^^^^^^^^^^^^^^^^^^^^
[gencode] type:20, op: 4
^^^^^^^^^^^^^^^^^^^^^^^^^
        movb $1,%ah
^^^^^^^^^^^^^^^^^^^^^^^^^
[gencode] type:20, op: 49
[gencode] type:20, op: 10
[gencode] type:20, op: 2
	movb y,%al
[gencode] type:20, op: 4
	movb $1,%al
[gencode] type:20, op: 2
	movb %al,y
	/**/
[gencode] type:20, op: 2
	movb %al,x
.L14:
[gencode] type:6, op: 49
^^^^^^^^^^^^^^^^^^^^^^^^
[gencode] type:6, op: 6
^^^^^^^^^^^^^^^^^^^^^^^^
[gencode] type:6, op: 6
^^^^^^^^^^^^^^^^^^^^^^^^
	movl %edx,%ebx
^^^^^^^^^^^^^^^^^^^^^^^^
	leave
	ret
	.comm x,01
	.comm y,01

うーん、pass1の最後とpass2の最初では正しいNode treeできてんのに
gencode()が呼ばれる時になるとゴミがまぎれこんでるザマス、あばばばば(クマAA略)。
ということは昨日の予想外コードはこいつが原因くさいので
やっぱり後置++/--の実装は見直しが必要だね、しくしく。

[NetBSD] isspace(3)その後

PR/36560
あとで見る

[NetBSD] PR/36560

各国語版sysinst(multibyte言語圏含む)の為にCitrus全部crunch binaryに
突っ込むのは容量的に現実的ではないよな、dlopen(3)問題もあるし。
UTF-8オンリーのちっちゃいlocale subsystemを書くとかかな。

購入物

2007/10/16(Tue)

[OpenBSD] pcc(1)

_Boolネタはちょっとお休みしてそのうち仕切り直す。

http://www.thejemreport.com/mambo/content/view/369/
コンパイラよりも先にown libstdc++は欲しいとは思う。

週末

50mm/F1.4の試し切りに城ヶ島まで。天気悪くてフィルム1本ほどで撤収。
その後風邪ひいて寝込んだ。

某祭り3次元には興味がないんでってリサ・ランドール「異次元は存在する」読んでたんじゃね?

デモ聴いてみたけど最近のソフトシンセはすごいね。
大昔KORG WAVESTATION A/DでVocoderごっことか
Roland S-550使って自声でケチャ(kecak)ごっこやってた頃からすると
こんだけのものがたった1万5千円ってなんてこったい\(^o^)/と思う。

そういえば、イモ(YMO)に固執するカレー系のDTM回帰組が
ニコ動に増えているという事実も、多少気になるところだが
Taisoはまだですか?

2007/10/17(Wed)

[OpenBSD] pcc(1) sign extend issue with +=

tamoさんとこより。

また別の話みたいですね、こっちは

movl -12(%ebp),%eax
cltd
addl -8(%ebp),%eax
adcl -4(%ebp),%edx
movl %eax,-8(%ebp)
movl %edx,-4(%ebp)
cltd

で%eaxを%edx:%eaxに変換してるからですね、gccは

movl $0,%edx

としてるんですが。

cltd使っちゃうとlong longに変換した時に

0x00000000ffffffffULL

でなく

0xffffffffffffffffULL

に化けちゃうのでこういう結果になるわけです。

pcc(1) sign extend issue with += その2

たぶんこんなかんじです

--- pcc-0.9.8.orig/arch/x86/table.c	2007-09-09 19:02:59.000000000 +0900
+++ pcc-0.9.8/arch/x86/table.c	2007-10-16 19:36:40.000000000 +0900
@@ -241,19 +241,19 @@
 		0,	RLEFT,
 		"", },
 
-/* convert int to long long */
+/* convert signed int to (u)long long */
 { SCONV,	INLL,
-	SAREG,	TWORD|TPOINT,
-	SCREG,	TLONGLONG,
-		NSPECIAL|NCREG|NCSL,	RESC1,
+	SHINT,	TSWORD,
+	SHLL,	TLL,
+		NCREG|NCSL,	RESC1,
 		"	cltd\n", },
 
-/* convert int to unsigned long long */
+/* convert unsigned int to (u)long long */
 { SCONV,	INLL,
-	SAREG|SOREG|SNAME,	TWORD|TPOINT,
-	SHLL,	TULONGLONG,
-		NCSL|NCREG,	RESC1,
-		"	movl AL,A1\n	xorl U1,U1\n", },
+	SHINT|SOREG|SNAME,	TUWORD|TPOINT,
+	SHLL,	TLL,
+		NCREG|NCSL,	RESC1,
+		"	movl AL,A1\n	movl $0,U1\n", },
 
 /* convert int (in memory) to double */
 { SCONV,	INFL,

このへんの話はinteger conversion rankとかusual arithmetic conversion
あたりの仕様を理解しておく必要がありますな。

[OpenBSD] pcc(1) _Bool type bug その9

いちおASSIGNのめどはたった。
OPLEFTが呼ばれない問題は解決ってことで。
そこで現在作業中断ちう、来週あたりからPLUSのゴミ問題かたずける予定。

現在の差分

2007/10/18(Thu)

[pcc] pcc-list

昨日の(u)int -> (u)long longの型変換ネタのパッチは
いちおotto氏とpcc-listメールに投げたんだけど
まだ流れんねぇ、gmailから投げたからフィルタ引っかかったかな?

まあragge氏は今確実にpcc-list読んでるどころでない状態
(Conguratuation!)だと思われるのでとりあえず放置しとこう。

[pcc] xor[bwl] %reg,%reg vs mov[bwl] $0,%reg

フィルタに引っかかってたのは自分の方でしたと orz
http://marc.info/?l=pcc-list&m=119186547515490&w=2
全く読んでなかったぜwwww
昨日のpatchはmovl $0,%edxにわざわざ書き換えてたけど
xor %edx,%edxを使いましょうってことで。

2007/10/19(Fri)

[pcc] pcc(1) _Bool type bug その10

PLUSのゴミ問題は来週からやろと思ったんだけど
実はtable.cの定義が漏れてたのが原因なことが判明、ちゃっちゃと 直した
もっとTとんでもないB馬鹿げたS処理漏れを予想してたんだがね。

というわけで後置++/--の処理をどうするかを来週から。
うーmip/regs.c読みたくねぇ。

通常の+/-はinc/subをor/xorに置き換えるように
mip/match.cのexpand()を書き換えて誤魔化した、多分駄目かも。

週末

またまた奥多摩へ、雨降んなきゃいいけど。

2007/10/22(Mon)

[pcc] integer promotion issue with +=

今の実装では(どうやら)TBOOL vs TANYにはならないのです。
事前にSCONVが呼ばれ0/1に変換(つまりTBOOL vs TBOOL)された上で
OPSIMPされるのでs/add/or/;s/sub/xor/してしまえばおkなはず。

...なのですが、これじゃぁC99の仕様的に駄目なんですよね。
JIS X0310:2003から引用。

6.3.1 算術オペランド
6.3.1.1 論理型, 文字型及び整数型
すべての整数型は, 次のとおり定義される整数変換の順位(integer conversion rank)をもつ。
(中略)
 - _Bool型は, その他すべての標準整数型より低い順位をもたなければならない。
(中略)
 - 整数変換の順位がint型及びunsigned int型より低い整数型をもつオブジェクト又は式
 - _Bool型, int型, signed int型,またはunsigned int型のビットフィールド
これらのものの元の型のすべての値をint型で表現可能な場合, その値をint型に変換する。
そうでない場合, unsigned int型に変換する。これらの処理を, 整数拡張(integer promotion)と呼ぶ。
(以下略)

この整数拡張が行われなければならないので
SCONVでTANYが先にTBOOLに変換してしまうと正しい結果が出ないのです。
これが前回の「多分駄目かも」の理由。

整数拡張は_Boolだけではなく、charやshortなどでも必要です。

char x;
int y;

x += y;

というCソースでは、charはintに拡張されますので

movsbl	x,%eax
movl	y,%edx
addl	%edx,%eax
movb	%al,x

というアセンブラになるはずです *1

しかしこのアセンブラは最適化 *2してしまえば

movl	y,%eax
addb	%al,x

と同じです *3
pccもpass1の時点で

0xbb901068) +=, char, 0x0, 0x8075818
    0xbb901154) NAME, 0, -1148186320, char, 0x0, 0x8075818
    0xbb901180) SCONV, char, 0x0, 0x8075818
        0xbb901104) NAME, 0, -1148186124, int, 0x0, 0x8075848

というNode treeを作成し、整数拡張を見事に無視してくれやがります。

ところが_Boolの場合この最適化をやられてしまうと困るのです。

#include <stdbool.h>

_Bool x = true;
int y = 100;
main(void)
{
	x -= y;
	printf("%d\n", x);
}

というコードを考えた場合、今の実装では

となりますが、実際には

とならなければなりません *4、あばばばばばばばばばば。

*1:gcc4は最適化なしだとこれに近いアセンブラを出力します。
*2:6.3.1.3 符号付き整数型及び符号無し整数型 も参照。
*3:gcc3は最適化の有無に関わらず、gcc4だと-01以上でこれに近いアセンブラを出力します。
*4:gccはちゃんと後者で出力されますな。

土曜日

PearlTAMAの檜原村へ。

今回は人数と荷物の関係でレンタカー借りたんだけど
ツーリングワゴンでなくミニバンにしとけばよかった、ちと狭い。
最近の車はよー判らん。

日曜は風邪寒鰤返して寝てた、ゲホゲホ。

2007/10/23(Tue)

[pcc] integer promotion issue with += その2

さーてpass1の修正をどうするかね…PLUSEQ/MINUSEQについては

$ cat >test.c
#include <stdbool.h>
_Bool x;
int y;
main(void)
{
	x += y;
}
^D
$ cpp test.c | /usr/pkg/libexec/ccom -Xb
0xbb901068) +=, bool, 0x0, 0x80758d0
    0xbb901104) NAME, 0, -1148186320, bool, 0x0, 0x80758d0
    0xbb9011b8) SCONV, bool, 0x0, 0x80758d0
        0xbb9011e4) NAME, 0, -1148186248, int, 0x0, 0x8075828

$ cat >test.c
#include <stdbool.h>
_Bool x;
int y;
main(void)
{
	x = x + y;
}
^D
$ cpp test.c | /usr/pkg/libexec/ccom -Xb
0xbb901278) =, bool, 0x0, 0x80758d0
    0xbb901104) NAME, 0, -1148186320, bool, 0x0, 0x80758d0
    0xbb9012a4) SCONV, bool, 0x0, 0x80758d0
        0xbb9011b8) +, int, 0x0, 0x8075828
            0xbb90124c) SCONV, int, 0x0, 0x8075828
                0xbb9011e4) NAME, 0, -1148186320, bool, 0x0, 0x80758d0
            0xbb901068) NAME, 0, -1148186248, int, 0x0, 0x8075828

のようにいったんx = x + y に展開しとかないとダメだよな。
+= のまま扱おうとすると

SCONV, bool # ここにSCONVを置くのは変
	+=, int
	SCONV, int
		NAME, bool
	NAME, int

のようにツリー構造が破綻してpass1の以降の処理もpass2も動かなくなりそう。

[FreeBSD] isspace((int)0xA0) + UTF-8 locale problem

あっちでもcommitされた模様、えんがちょ。

2007/10/24(Wed)

[pcc] integer promotion issue with += その3

こんなんでいいのかな。
あんまり叩いてないけど、とりあえずこれでPLUS/MINUSはおkのよな希ガス。

あとはINCR/DECRとtable.cの不足分(LSとかRS)の追加かぁ。

鍵盤

YAMAHA NP-30、76鍵で5.4kgはいいねぇ。
乾電池駆動可というのもKORG POLY-800っぽくてイイ。
ホイールないけどどーせ使わんので全然おk。
Roland JV-90は処分してこれ買うかちょっと考え中。

もしくは M-AUDIO Keystation 88esかね。
でも88鍵まではさすがに不要だし重さ10kgってなぁ。

2007/10/25(Thu)

[C言語] C1X

VAIO C1X[E-G]の話ではないぞよ。

ちょっと古い話だけど JTC1/SC22/WG14C1X宣言きてるねぇ、後日読もうかね。

めも、 ISO の制定順序

ところで char16_t/char32_t は C++0X の方が先に入りそうなんだが
こーゆーの順序的に前後していいのだろか。

[pcc] pcc(1) _Bool type bug その11

INCR/DECRの場合、buildtree()内で

x = y++;
 ↓
x = y;
y = y + 1;

へ書き換えるのはちと難しげ。
delvoid()でやるのもあんまり夜露死苦なさげ。
cgram.yでなんとかできるかな?

[pcc] _Bool vs atomicity

_Boolの実装しててatomicityまわりに不安があったんだけど
C99読んでもよーわからん、C++の方では こんな感じなので安心かな?

2007/10/27(Sat)

最近買ったもの

2007/10/29(Mon)

週末

現像したまま放置してたポジをひたすらスキャンしてた。

Photoshop Elements 5.0の写真整理モード遅すぐる。
1枚130MB程度のtiffが大量にあるとまるで使いものにならん。
Lightroomだとどうなんだろ、体験版でも入れてみるか。

今年の夏はFUJIFILMの FortiaSPを多用してたら、その毒々しい色に慣れてしまい
Velviaですら地味に感じてヤバい、ちょ化学調味料シンドロームwwwww

α-8700iシャッター壊れた(´・ω・`)フィルム入れる前だったのは不幸中の幸い。

のでサブ機として重宝してたんだが、合掌。
これで同機種は残り1台、もう何台か捕獲するかどしよか...相場は3〜5kぐらいだし。
ただ最近は状態のいい中古が少ないんだよなぁ。

2007/10/30(Tue)

[pcc] pcc(1) _Bool type bug (intermission)

サボり中。

INCR/DECRをpass1レベルでPLUS/MINUSにRewriteするのは
いろいろ破綻してるげなんで、さっさとpass2に処理任せる方針で。

友達の友達は(以下略

新宿アルタ前への法相派遣法案なら今国会でも成立しそうだな。

今日

某商用チャート生成ツール、グラフの軸の注釈を改行したい場合
メーカーのFAQにはHTMLタグが使えるのでPタグなりBRタグなり好きなの使え
と書いてあるんだが、内部的にはこれ

とゆー実装になってるようで、両者混在させると字の大きさがびみょーに合わず地味に困る。
あとswingだと字が汚くなるのよね(Java5以降はいいとして)。