diff -urBw pcc.orig/arch/i386/local.c pcc/arch/i386/local.c --- pcc.orig/arch/i386/local.c 2008-02-19 18:03:03.000000000 +0900 +++ pcc/arch/i386/local.c 2008-02-19 23:30:05.000000000 +0900 @@ -392,7 +392,8 @@ 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 || @@ -477,7 +478,8 @@ nfree(p); p = l; } - if ((p->n_type == CHAR || p->n_type == UCHAR || + if ((p->n_type == BOOL || + p->n_type == CHAR || p->n_type == UCHAR || p->n_type == SHORT || p->n_type == USHORT) && (l->n_type == FLOAT || l->n_type == DOUBLE || l->n_type == LDOUBLE)) { @@ -512,8 +514,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.orig/arch/i386/local2.c pcc/arch/i386/local2.c --- pcc.orig/arch/i386/local2.c 2008-02-19 18:03:03.000000000 +0900 +++ pcc/arch/i386/local2.c 2008-02-19 23:30:06.000000000 +0900 @@ -200,6 +200,7 @@ tlen(p) NODE *p; { switch(p->n_type) { + case BOOL: case CHAR: case UCHAR: return(1); @@ -426,7 +427,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; @@ -546,6 +547,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' && @@ -731,7 +733,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) { @@ -982,6 +984,7 @@ rnames[d][3],rnames[d][4],rnames[d][5]); #endif break; + case BOOL: case CHAR: case UCHAR: printf(" movb %s,%s\n", rnames[s], rnames[d]); @@ -1045,7 +1048,7 @@ int gclass(TWORD t) { - if (t == CHAR || t == UCHAR) + if (t == BOOL || t == CHAR || t == UCHAR) return CLASSB; if (t == LONGLONG || t == ULONGLONG) return CLASSC; diff -urBw pcc.orig/arch/i386/macdefs.h pcc/arch/i386/macdefs.h --- pcc.orig/arch/i386/macdefs.h 2008-02-19 18:03:03.000000000 +0900 +++ pcc/arch/i386/macdefs.h 2008-02-19 23:30:06.000000000 +0900 @@ -284,7 +284,7 @@ #define ENCRA2(x) ((x) << 12) /* A2 */ #define ENCRA(x,y) ((x) << (6+y*6)) /* encode regs in int */ /* XXX - return char in al? */ -#define RETREG(x) (x == CHAR || x == UCHAR ? AL : \ +#define RETREG(x) (x == BOOL || x == CHAR || x == UCHAR ? AL : \ x == LONGLONG || x == ULONGLONG ? EAXEDX : \ x == FLOAT || x == DOUBLE || x == LDOUBLE ? 31 : EAX) diff -urBw pcc.orig/arch/i386/table.c pcc/arch/i386/table.c --- pcc.orig/arch/i386/table.c 2008-02-19 18:03:03.000000000 +0900 +++ pcc/arch/i386/table.c 2008-02-19 23:33:39.000000000 +0900 @@ -64,6 +64,13 @@ /* itself to itself, including pointers */ +/* convert _Bool to _Bool. */ +{ SCONV, INCH, + SHCH, TBOOL, + SHCH, TBOOL, + 0, RLEFT, + "", }, + /* convert (u)char to (u)char. */ { SCONV, INCH, SHCH, TCHAR|TUCHAR, @@ -99,8 +106,25 @@ 0, RLEFT, "", }, +/* _Bool to something */ + +/* convert _Bool to (u)char. */ +{ SCONV, INCH, + SHCH|SOREG|SNAME, TBOOL, + SHCH, TBOOL|TCHAR|TUCHAR, + NBSL|NBREG, RESC1, + " movb AL,A1\n", }, + /* char to something */ +/* convert char to _Bool. */ +{ SCONV, INCH, + SHCH, TCHAR|TUCHAR, + SHCH, TBOOL, + NBSL|NBREG, RESC1, + " cmpb $0,AL\n" + " setne A1\n", }, + /* convert char to (unsigned) short. */ { SCONV, ININT, SBREG|SOREG|SNAME, TCHAR, @@ -110,7 +134,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 +148,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 +162,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 +177,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 +185,14 @@ /* short to something */ +/* convert short too _Bool. */ +{ SCONV, INCH, + SHINT, TSHORT|TUSHORT, + SHCH, TBOOL, + NBSL|NBREG, RESC1, + " cmpw $0,AL\n" + " setne A1\n", }, + /* convert short (in memory) to char */ { SCONV, INCH, SNAME|SOREG, TSHORT|TUSHORT, @@ -227,6 +259,14 @@ /* int to something */ +/* convert int to _Bool. */ +{ SCONV, INCH, + SHINT, TWORD, + SHCH, TBOOL, + NBSL|NBREG, RESC1, + " cmpl $0,AL\n" + " setne A1\n", }, + /* convert int to char. This is done when register is loaded */ { SCONV, INCH, SAREG, TWORD, @@ -271,6 +311,14 @@ /* long long to something */ +/* convert (u)long long to _Bool. */ +{ SCONV, INCH, + SHLL, TLL, + SHCH, TBOOL, + NBSL|NBREG, RESC1, + " orl UL,AL\n" + " setne A1\n", }, + /* convert (u)long long to (u)char (mem->reg) */ { SCONV, INCH, SOREG|SNAME, TLL, @@ -338,6 +386,13 @@ /* float to something */ #if 0 /* go via int by adding an extra sconv in clocal() */ +/* convert float/double to _Bool */ +{ SCONV, INCH, + SHFL, TLDOUBLE|TDOUBLE|TFLOAT, + SHCH, TBOOL, + NBREG, RESC1, + "XXX: FIXME\n", }, + /* convert float/double to (u) char. XXX should use NTEMP here */ { SCONV, INCH, SHFL, TLDOUBLE|TDOUBLE|TFLOAT, @@ -690,7 +745,17 @@ 0, RLEFT, " Ol AR,AL\n Ol UR,UL\n", }, +{ OPSIMP, INCH|FOREFF, + SHCH, TBOOL, + SHCH|SNAME|SOREG, TBOOL, + 0, RLEFT, + " Ob AR,AL\n", }, +{ OPSIMP, INCH|FOREFF, + SHCH|SNAME|SOREG, TBOOL, + SCON, TANY, + 0, RLEFT, + " Ob AR,AL\n", }, /* * The next rules handle all shift operators. */ @@ -886,13 +951,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", }, @@ -922,14 +987,14 @@ " 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", }, { ASSIGN, FOREFF|INBREG, - SFLD, TCHAR|TUCHAR, - SBREG|SCON, TCHAR|TUCHAR, + SFLD, TBOOL|TCHAR|TUCHAR, + SBREG|SCON, TBOOL|TCHAR|TUCHAR, NAREG|NBREG, RDEST, " movb AR,A2\n" " movzbl A2,A1\n" @@ -1231,7 +1296,7 @@ " cmpw AR,AL\n", }, { OPLOG, FORCC, - SBREG|SOREG|SNAME, TCHAR|TUCHAR, + SBREG|SOREG|SNAME, TBOOL|TCHAR|TUCHAR, SCON|SBREG, TANY, 0, RESCC, " cmpb AR,AL\n", }, @@ -1295,8 +1360,8 @@ " andw AR,AL\n", }, { AND, INBREG|FOREFF, - SBREG|SOREG|SNAME, TCHAR|TUCHAR, - SCON|SBREG, TCHAR|TUCHAR, + SBREG|SOREG|SNAME, TBOOL|TCHAR|TUCHAR, + SCON|SBREG, TBOOL|TCHAR|TUCHAR, 0, RLEFT, " andb AR,AL\n", }, @@ -1365,7 +1430,7 @@ { OPLTYPE, INBREG, SANY, TANY, - SBREG|SOREG|SNAME|SCON, TCHAR|TUCHAR, + SBREG|SOREG|SNAME|SCON, TBOOL|TCHAR|TUCHAR, NBREG, RESC1, " movb AL,A1\n", }, @@ -1440,6 +1505,12 @@ 0, RLEFT, " fchs\n", }, +{ UMINUS, INBREG|FOREFF, + SBREG, TBOOL, + SBREG, TBOOL, + 0, RLEFT, + "", }, + { COMPL, INCREG, SCREG, TLL, SANY, TANY, @@ -1480,8 +1551,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", }, @@ -1504,8 +1575,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.orig/cc/ccom/pass1.h pcc/cc/ccom/pass1.h --- pcc.orig/cc/ccom/pass1.h 2008-02-19 18:03:04.000000000 +0900 +++ pcc/cc/ccom/pass1.h 2008-02-19 23:30:06.000000000 +0900 @@ -381,13 +381,10 @@ #define UNASG (-(PLUSEQ-PLUS))+ -#define INCR (MAXOP+26) -#define DECR (MAXOP+27) /* * 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.orig/cc/ccom/scan.l pcc/cc/ccom/scan.l --- pcc.orig/cc/ccom/scan.l 2008-02-19 18:03:04.000000000 +0900 +++ pcc/cc/ccom/scan.l 2008-02-19 23:30:06.000000000 +0900 @@ -90,7 +90,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.orig/cc/ccom/trees.c pcc/cc/ccom/trees.c --- pcc.orig/cc/ccom/trees.c 2008-02-19 18:03:04.000000000 +0900 +++ pcc/cc/ccom/trees.c 2008-02-19 23:30:06.000000000 +0900 @@ -234,6 +234,16 @@ return(l); } } + if (l != NULL && l->n_type == BOOL && + o >= PLUSEQ && o <= RSEQ) { + NODE *lx, *rx; + + lx = talloc(); + *lx = *l; + rx = buildtree(UNASG o, l, r); + return buildtree(ASSIGN, lx, rx); + } + runtime: /* its real; we must make a new node */ @@ -419,7 +429,8 @@ case RS: /* must make type size at least int... */ if (p->n_type == CHAR || p->n_type == SHORT) { p->n_left = makety(l, INT, 0, 0, MKSUE(INT)); - } else if (p->n_type == UCHAR || p->n_type == USHORT) { + } else if (p->n_type == BOOL || + p->n_type == UCHAR || p->n_type == USHORT) { p->n_left = makety(l, UNSIGNED, 0, 0, MKSUE(UNSIGNED)); } @@ -1929,18 +1940,7 @@ NODE *q, *r; int tval; - if (p->n_op == INCR || p->n_op == DECR) { - /* - * Rewrite x++ to (x += 1) -1; and deal with it further down. - * Pass2 will remove -1 if unneccessary. - */ - q = ccopy(p); - tfree(p->n_left); - q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ; - p->n_op = (p->n_op==INCR)?MINUS:PLUS; - p->n_left = delasgop(q); - - } else if ((cdope(p->n_op)&ASGOPFLG) && + if ((cdope(p->n_op)&ASGOPFLG) && p->n_op != RETURN && p->n_op != CAST) { NODE *l = p->n_left; NODE *ll = l->n_left; @@ -2154,27 +2154,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 = regno(r); - 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 @@ -2295,8 +2274,6 @@ SNAM(EREQ,^=) SNAM(LSEQ,<<=) SNAM(RSEQ,>>=) - SNAM(INCR,++) - SNAM(DECR,--) default: cerror("bad copst %d", op); } @@ -2345,9 +2322,6 @@ case LSEQ: case RSEQ: return BITYPE|SHFFLG|ASGFLG|ASGOPFLG; - case INCR: - case DECR: - return BITYPE|ASGFLG; } return 0; /* XXX gcc */ } diff -urBw pcc.orig/mip/common.c pcc/mip/common.c --- pcc.orig/mip/common.c 2008-02-19 18:03:04.000000000 +0900 +++ pcc/mip/common.c 2008-02-19 23:30:06.000000000 +0900 @@ -371,6 +371,8 @@ { STCALL, "STCALL", BITYPE|CALLFLG, }, { USTCALL, "USTCALL", UTYPE|CALLFLG, }, { ADDROF, "U&", UTYPE, }, + { INCR, "++", BITYPE|ASGFLG, }, + { DECR, "--", BITYPE|ASGFLG, }, { -1, "", 0 }, }; @@ -413,8 +415,8 @@ "enumty", "moety", "void", + "bool", "signed", /* pass1 */ - "bool", /* pass1 */ "?", "?" }; diff -urBw pcc.orig/mip/manifest.h pcc/mip/manifest.h --- pcc.orig/mip/manifest.h 2008-02-19 18:03:04.000000000 +0900 +++ pcc/mip/manifest.h 2008-02-19 23:30:07.000000000 +0900 @@ -80,8 +80,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.orig/mip/match.c pcc/mip/match.c --- pcc.orig/mip/match.c 2008-01-22 04:46:19.000000000 +0900 +++ pcc/mip/match.c 2008-02-19 23:30:07.000000000 +0900 @@ -215,6 +215,8 @@ return(0); switch (t) { + case BOOL: + return( tword & TBOOL ); case CHAR: return( tword & TCHAR ); case SHORT: @@ -387,8 +389,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 @@ -396,7 +398,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.orig/mip/node.h pcc/mip/node.h --- pcc.orig/mip/node.h 2008-02-19 18:03:04.000000000 +0900 +++ pcc/mip/node.h 2008-02-19 23:30:07.000000000 +0900 @@ -191,4 +191,7 @@ #define FUNARG 57 #define ADDROF 58 -#define MAXOP 58 +#define INCR 59 +#define DECR 60 + +#define MAXOP 60 diff -urBw pcc.orig/mip/pass2.h pcc/mip/pass2.h --- pcc.orig/mip/pass2.h 2008-02-19 18:03:04.000000000 +0900 +++ pcc/mip/pass2.h 2008-02-19 23:30:07.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 */ diff -urBw pcc.orig/mip/reader.c pcc/mip/reader.c --- pcc.orig/mip/reader.c 2008-02-19 18:03:04.000000000 +0900 +++ pcc/mip/reader.c 2008-02-19 23:30:07.000000000 +0900 @@ -144,6 +144,8 @@ case USTCALL: case STASG: case STARG: + case INCR: + case DECR: return 0; default: return 1; @@ -471,6 +473,10 @@ p->n_su = 0; break; + case INCR: + case DECR: + break; + case FORCE: /* XXX needed? */ geninsn(p->n_left, INREGS); p->n_su = 0; /* su calculations traverse left */